Refactor extension executable error handling

This commit is contained in:
Kynan Ware 2024-12-08 15:55:09 -07:00
parent b5f3463b75
commit b2ab7b84f8
4 changed files with 36 additions and 14 deletions

View file

@ -340,9 +340,11 @@ func NewCmdExtension(f *cmdutil.Factory) *cobra.Command {
}
err = m.InstallLocal(wd)
if errors.Is(err, ErrExtensionExecutableNotFound) {
var ErrExtensionExecutableNotFound *ErrExtensionExecutableNotFound
if errors.As(err, &ErrExtensionExecutableNotFound) {
cs := io.ColorScheme()
if io.IsStdoutTTY() {
fmt.Fprintln(io.ErrOut, err.Error())
fmt.Fprintf(io.ErrOut, "%s %s", cs.WarningIcon(), ErrExtensionExecutableNotFound.Error())
}
return nil
}

View file

@ -287,27 +287,38 @@ func TestNewCmdExtension(t *testing.T) {
},
},
{
name: "install local extension without executable TTY",
name: "installing local extension without executable with TTY shows warning",
args: []string{"install", "."},
managerStubs: func(em *extensions.ExtensionManagerMock) func(*testing.T) {
em.InstallLocalFunc = func(dir string) error {
return ErrExtensionExecutableNotFound
return &ErrExtensionExecutableNotFound{
Dir: tempDir,
Name: "gh-test",
}
}
em.ListFunc = func() []extensions.Extension {
return []extensions.Extension{}
}
return nil
},
wantStderr: fmt.Sprintln(ErrExtensionExecutableNotFound.Error()),
wantErr: false,
isTTY: true,
wantStderr: fmt.Sprintf(
"! %s",
(&ErrExtensionExecutableNotFound{
Dir: tempDir,
Name: "gh-test",
}).Error()),
wantErr: false,
isTTY: true,
},
{
name: "install local extension without executable no TTY",
name: "install local extension without executable with no TTY shows no warning",
args: []string{"install", "."},
managerStubs: func(em *extensions.ExtensionManagerMock) func(*testing.T) {
em.InstallLocalFunc = func(dir string) error {
return ErrExtensionExecutableNotFound
return &ErrExtensionExecutableNotFound{
Dir: tempDir,
Name: "gh-test",
}
}
em.ListFunc = func() []extensions.Extension {
return []extensions.Extension{}

View file

@ -28,7 +28,15 @@ import (
// ErrInitialCommitFailed indicates the initial commit when making a new extension failed.
var ErrInitialCommitFailed = errors.New("initial commit failed")
var ErrExtensionExecutableNotFound = errors.New("an extension has been installed but there is no executable")
type ErrExtensionExecutableNotFound struct {
Dir string
Name string
}
func (e *ErrExtensionExecutableNotFound) Error() string {
return fmt.Sprintf("an extension has been installed but there is no executable: executable file named \"%s\" in %s is required to run the extension after install. Perhaps you need to build it?\n", e.Name, e.Dir)
}
const darwinAmd64 = "darwin-amd64"
@ -195,7 +203,6 @@ func (m *Manager) populateLatestVersions(exts []*Extension) {
func (m *Manager) InstallLocal(dir string) error {
name := filepath.Base(dir)
targetLink := filepath.Join(m.installDir(), name)
cs := m.io.ColorScheme()
if err := os.MkdirAll(filepath.Dir(targetLink), 0755); err != nil {
return err
@ -209,8 +216,10 @@ func (m *Manager) InstallLocal(dir string) error {
// it does indicate that the user will not be able to run the extension until
// the executable file is built or created manually somehow.
if _, err := os.Stat(filepath.Join(dir, name)); os.IsNotExist(err) {
errMsg := fmt.Errorf("%v %w: executable file named \"%s\" in %s is required to run the extension after install. Perhaps you need to build it?", cs.WarningIcon(), ErrExtensionExecutableNotFound, name, dir)
return errMsg
return &ErrExtensionExecutableNotFound{
Dir: dir,
Name: name,
}
}
return nil
}

View file

@ -771,7 +771,7 @@ func TestManager_Install_local_no_executable_found(t *testing.T) {
// to simulate an attempt to install a local extension without an executable
err := m.InstallLocal(localDir)
require.ErrorIs(t, err, ErrExtensionExecutableNotFound)
require.ErrorAs(t, err, new(*ErrExtensionExecutableNotFound))
assert.Equal(t, "", stdout.String())
assert.Equal(t, "", stderr.String())
}