mntly/extension not found (#6425)
Co-authored-by: Mislav Marohnić <mislav@github.com>
This commit is contained in:
parent
c89d0402bb
commit
abb8c86ee8
5 changed files with 92 additions and 15 deletions
|
|
@ -124,6 +124,9 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
|
|||
} else if errors.Is(err, commitNotFoundErr) {
|
||||
return fmt.Errorf("%s %s does not exist in %s",
|
||||
cs.FailureIcon(), cs.Cyan(pinFlag), args[0])
|
||||
} else if errors.Is(err, repositoryNotFoundErr) {
|
||||
return fmt.Errorf("%s Could not find extension '%s' on host %s",
|
||||
cs.FailureIcon(), args[0], repo.RepoHost())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,25 @@ func TestNewCmdExtension(t *testing.T) {
|
|||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error extension not found",
|
||||
args: []string{"install", "owner/gh-some-ext"},
|
||||
managerStubs: func(em *extensions.ExtensionManagerMock) func(*testing.T) {
|
||||
em.ListFunc = func() []extensions.Extension {
|
||||
return []extensions.Extension{}
|
||||
}
|
||||
em.InstallFunc = func(_ ghrepo.Interface, _ string) error {
|
||||
return repositoryNotFoundErr
|
||||
}
|
||||
return func(t *testing.T) {
|
||||
installCalls := em.InstallCalls()
|
||||
assert.Equal(t, 1, len(installCalls))
|
||||
assert.Equal(t, "gh-some-ext", installCalls[0].InterfaceMoqParam.RepoName())
|
||||
}
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: "X Could not find extension 'owner/gh-some-ext' on host github.com",
|
||||
},
|
||||
{
|
||||
name: "install local extension with pin",
|
||||
args: []string{"install", ".", "--pin", "v1.0.0"},
|
||||
|
|
|
|||
|
|
@ -13,32 +13,54 @@ import (
|
|||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
)
|
||||
|
||||
func hasScript(httpClient *http.Client, repo ghrepo.Interface) (hs bool, err error) {
|
||||
func repoExists(httpClient *http.Client, repo ghrepo.Interface) (bool, error) {
|
||||
url := fmt.Sprintf("%srepos/%s/%s", ghinstance.RESTPrefix(repo.RepoHost()), repo.RepoOwner(), repo.RepoName())
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
return true, nil
|
||||
case 404:
|
||||
return false, nil
|
||||
default:
|
||||
return false, api.HandleHTTPError(resp)
|
||||
}
|
||||
}
|
||||
|
||||
func hasScript(httpClient *http.Client, repo ghrepo.Interface) (bool, error) {
|
||||
path := fmt.Sprintf("repos/%s/%s/contents/%s",
|
||||
repo.RepoOwner(), repo.RepoName(), repo.RepoName())
|
||||
url := ghinstance.RESTPrefix(repo.RepoHost()) + path
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return
|
||||
return false, err
|
||||
}
|
||||
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return
|
||||
return false, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == 404 {
|
||||
return
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if resp.StatusCode > 299 {
|
||||
err = api.HandleHTTPError(resp)
|
||||
return
|
||||
return false, err
|
||||
}
|
||||
|
||||
hs = true
|
||||
return
|
||||
return true, nil
|
||||
}
|
||||
|
||||
type releaseAsset struct {
|
||||
|
|
@ -80,8 +102,9 @@ func downloadAsset(httpClient *http.Client, asset releaseAsset, destPath string)
|
|||
return err
|
||||
}
|
||||
|
||||
var releaseNotFoundErr = errors.New("release not found")
|
||||
var commitNotFoundErr = errors.New("commit not found")
|
||||
var releaseNotFoundErr = errors.New("release not found")
|
||||
var repositoryNotFoundErr = errors.New("repository not found")
|
||||
|
||||
// fetchLatestRelease finds the latest published release for a repository.
|
||||
func fetchLatestRelease(httpClient *http.Client, baseRepo ghrepo.Interface) (*release, error) {
|
||||
|
|
@ -98,6 +121,9 @@ func fetchLatestRelease(httpClient *http.Client, baseRepo ghrepo.Interface) (*re
|
|||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == 404 {
|
||||
return nil, releaseNotFoundErr
|
||||
}
|
||||
if resp.StatusCode > 299 {
|
||||
return nil, api.HandleHTTPError(resp)
|
||||
}
|
||||
|
|
@ -162,7 +188,7 @@ func fetchCommitSHA(httpClient *http.Client, baseRepo ghrepo.Interface, targetRe
|
|||
return "", err
|
||||
}
|
||||
|
||||
req.Header.Set("Accept", "application/vnd.github.VERSION.sha")
|
||||
req.Header.Set("Accept", "application/vnd.github.v3.sha")
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -339,7 +339,15 @@ type binManifest struct {
|
|||
func (m *Manager) Install(repo ghrepo.Interface, target string) error {
|
||||
isBin, err := isBinExtension(m.client, repo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not check for binary extension: %w", err)
|
||||
if errors.Is(err, releaseNotFoundErr) {
|
||||
if ok, err := repoExists(m.client, repo); err != nil {
|
||||
return err
|
||||
} else if !ok {
|
||||
return repositoryNotFoundErr
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("could not check for binary extension: %w", err)
|
||||
}
|
||||
}
|
||||
if isBin {
|
||||
return m.installBin(repo, target)
|
||||
|
|
@ -760,11 +768,6 @@ func isBinExtension(client *http.Client, repo ghrepo.Interface) (isBin bool, err
|
|||
var r *release
|
||||
r, err = fetchLatestRelease(client, repo)
|
||||
if err != nil {
|
||||
httpErr, ok := err.(api.HTTPError)
|
||||
if ok && httpErr.StatusCode == 404 {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -844,6 +844,32 @@ func TestManager_Install_binary(t *testing.T) {
|
|||
assert.Equal(t, "", stderr.String())
|
||||
}
|
||||
|
||||
func TestManager_repo_not_found(t *testing.T) {
|
||||
repo := ghrepo.NewWithHost("owner", "gh-bin-ext", "example.com")
|
||||
|
||||
reg := httpmock.Registry{}
|
||||
defer reg.Verify(t)
|
||||
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "api/v3/repos/owner/gh-bin-ext/releases/latest"),
|
||||
httpmock.StatusStringResponse(404, `{}`))
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "api/v3/repos/owner/gh-bin-ext"),
|
||||
httpmock.StatusStringResponse(404, `{}`))
|
||||
|
||||
ios, _, stdout, stderr := iostreams.Test()
|
||||
tempDir := t.TempDir()
|
||||
|
||||
m := newTestManager(tempDir, &http.Client{Transport: ®}, ios)
|
||||
|
||||
if err := m.Install(repo, ""); err != repositoryNotFoundErr {
|
||||
t.Errorf("expected repositoryNotFoundErr, got: %v", err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "", stdout.String())
|
||||
assert.Equal(t, "", stderr.String())
|
||||
}
|
||||
|
||||
func TestManager_Create(t *testing.T) {
|
||||
chdirTemp(t)
|
||||
ios, _, stdout, stderr := iostreams.Test()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue