mntly/extension not found (#6425)

Co-authored-by: Mislav Marohnić <mislav@github.com>
This commit is contained in:
Ariel Deitcher 2022-10-14 16:27:15 +03:00 committed by GitHub
parent c89d0402bb
commit abb8c86ee8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 92 additions and 15 deletions

View file

@ -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
}

View file

@ -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"},

View file

@ -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

View file

@ -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
}

View file

@ -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: &reg}, 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()