chore(go): inject stdin and pass rc force explicitly
This commit is contained in:
@@ -8,10 +8,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
exitCode := run(os.Args[1:], os.Stdout, os.Stderr)
|
_ = os.Setenv("GIT_TERMINAL_PROMPT", "0")
|
||||||
|
exitCode := run(os.Args[1:], os.Stdin, os.Stdout, os.Stderr)
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(args []string, stdout io.Writer, stderr io.Writer) int {
|
func run(args []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) int {
|
||||||
return cli.Run(args, stdout, stderr)
|
return cli.Run(args, stdin, stdout, stderr)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ func TestRunVersionCommand(t *testing.T) {
|
|||||||
stdout := &bytes.Buffer{}
|
stdout := &bytes.Buffer{}
|
||||||
stderr := &bytes.Buffer{}
|
stderr := &bytes.Buffer{}
|
||||||
|
|
||||||
exitCode := run([]string{"version"}, stdout, stderr)
|
exitCode := run([]string{"version"}, bytes.NewBuffer(nil), stdout, stderr)
|
||||||
if exitCode != 0 {
|
if exitCode != 0 {
|
||||||
t.Fatalf("run(version) exit code = %d, want 0", exitCode)
|
t.Fatalf("run(version) exit code = %d, want 0", exitCode)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import (
|
|||||||
"github.com/alecthomas/kong"
|
"github.com/alecthomas/kong"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Run(args []string, stdout io.Writer, stderr io.Writer) int {
|
func Run(args []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) int {
|
||||||
model := &cliModel{}
|
model := &cliModel{}
|
||||||
|
|
||||||
app, err := core.New(stdout, stderr)
|
app, err := core.NewApp(stdin, stdout, stderr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_, _ = fmt.Fprintf(stderr, "error: %v\n", err)
|
_, _ = fmt.Fprintf(stderr, "error: %v\n", err)
|
||||||
return 1
|
return 1
|
||||||
@@ -227,11 +227,7 @@ func (c *openCmd) Run(app *core.App) error { return app.Open(defaultCastle(c.
|
|||||||
func (c *execCmd) Run(app *core.App) error { return app.Exec(c.Castle, c.Command) }
|
func (c *execCmd) Run(app *core.App) error { return app.Exec(c.Castle, c.Command) }
|
||||||
func (c *execAllCmd) Run(app *core.App) error { return app.ExecAll(c.Command) }
|
func (c *execAllCmd) Run(app *core.App) error { return app.ExecAll(c.Command) }
|
||||||
func (c *rcCmd) Run(app *core.App) error {
|
func (c *rcCmd) Run(app *core.App) error {
|
||||||
originalForce := app.Force
|
return app.Rc(defaultCastle(c.Castle), c.Force)
|
||||||
app.Force = c.Force
|
|
||||||
err := app.Rc(defaultCastle(c.Castle))
|
|
||||||
app.Force = originalForce
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
func (c *generateCmd) Run(app *core.App) error { return app.Generate(c.Path) }
|
func (c *generateCmd) Run(app *core.App) error { return app.Generate(c.Path) }
|
||||||
|
|
||||||
@@ -329,11 +325,3 @@ type cliExitError struct {
|
|||||||
func (e *cliExitError) Error() string {
|
func (e *cliExitError) Error() string {
|
||||||
return e.err.Error()
|
return e.err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func notImplemented(command string) error {
|
|
||||||
return &cliExitError{code: 2, err: fmt.Errorf("%s is not implemented in Go yet", command)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
_ = os.Setenv("GIT_TERMINAL_PROMPT", "0")
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ func (s *CLISuite) TestRun_VersionAliases() {
|
|||||||
s.stdout.Reset()
|
s.stdout.Reset()
|
||||||
s.stderr.Reset()
|
s.stderr.Reset()
|
||||||
|
|
||||||
exitCode := cli.Run(args, s.stdout, s.stderr)
|
exitCode := cli.Run(args, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Equal(s.T(), version.String+"\n", s.stdout.String())
|
require.Equal(s.T(), version.String+"\n", s.stdout.String())
|
||||||
require.Empty(s.T(), s.stderr.String())
|
require.Empty(s.T(), s.stderr.String())
|
||||||
@@ -75,7 +75,7 @@ func (s *CLISuite) TestRun_VersionAliases() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestRun_ShowPath_DefaultCastle() {
|
func (s *CLISuite) TestRun_ShowPath_DefaultCastle() {
|
||||||
exitCode := cli.Run([]string{"show_path"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"show_path"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Equal(s.T(), filepath.Join(s.homeDir, ".homesick", "repos", "dotfiles")+"\n", s.stdout.String())
|
require.Equal(s.T(), filepath.Join(s.homeDir, ".homesick", "repos", "dotfiles")+"\n", s.stdout.String())
|
||||||
@@ -83,7 +83,7 @@ func (s *CLISuite) TestRun_ShowPath_DefaultCastle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestRun_Cd_DefaultCastle() {
|
func (s *CLISuite) TestRun_Cd_DefaultCastle() {
|
||||||
exitCode := cli.Run([]string{"cd"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"cd"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Equal(s.T(), filepath.Join(s.homeDir, ".homesick", "repos", "dotfiles")+"\n", s.stdout.String())
|
require.Equal(s.T(), filepath.Join(s.homeDir, ".homesick", "repos", "dotfiles")+"\n", s.stdout.String())
|
||||||
@@ -91,7 +91,7 @@ func (s *CLISuite) TestRun_Cd_DefaultCastle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestRun_Cd_ExplicitCastle() {
|
func (s *CLISuite) TestRun_Cd_ExplicitCastle() {
|
||||||
exitCode := cli.Run([]string{"cd", "work"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"cd", "work"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Equal(s.T(), filepath.Join(s.homeDir, ".homesick", "repos", "work")+"\n", s.stdout.String())
|
require.Equal(s.T(), filepath.Join(s.homeDir, ".homesick", "repos", "work")+"\n", s.stdout.String())
|
||||||
@@ -102,7 +102,7 @@ func (s *CLISuite) TestRun_Exec_RunsCommandInCastleRoot() {
|
|||||||
castleRoot := filepath.Join(s.homeDir, ".homesick", "repos", "dotfiles")
|
castleRoot := filepath.Join(s.homeDir, ".homesick", "repos", "dotfiles")
|
||||||
require.NoError(s.T(), os.MkdirAll(castleRoot, 0o755))
|
require.NoError(s.T(), os.MkdirAll(castleRoot, 0o755))
|
||||||
|
|
||||||
exitCode := cli.Run([]string{"exec", "dotfiles", "pwd"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"exec", "dotfiles", "pwd"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Contains(s.T(), s.stdout.String(), castleRoot)
|
require.Contains(s.T(), s.stdout.String(), castleRoot)
|
||||||
@@ -114,7 +114,7 @@ func (s *CLISuite) TestRun_Exec_WithPretend_DoesNotExecute() {
|
|||||||
require.NoError(s.T(), os.MkdirAll(castleRoot, 0o755))
|
require.NoError(s.T(), os.MkdirAll(castleRoot, 0o755))
|
||||||
target := filepath.Join(castleRoot, "should-not-exist")
|
target := filepath.Join(castleRoot, "should-not-exist")
|
||||||
|
|
||||||
exitCode := cli.Run([]string{"--pretend", "exec", "dotfiles", "touch should-not-exist"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"--pretend", "exec", "dotfiles", "touch should-not-exist"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.NoFileExists(s.T(), target)
|
require.NoFileExists(s.T(), target)
|
||||||
@@ -127,7 +127,7 @@ func (s *CLISuite) TestRun_Exec_WithDryRunAlias_DoesNotExecute() {
|
|||||||
require.NoError(s.T(), os.MkdirAll(castleRoot, 0o755))
|
require.NoError(s.T(), os.MkdirAll(castleRoot, 0o755))
|
||||||
target := filepath.Join(castleRoot, "should-not-exist")
|
target := filepath.Join(castleRoot, "should-not-exist")
|
||||||
|
|
||||||
exitCode := cli.Run([]string{"--dry-run", "exec", "dotfiles", "touch should-not-exist"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"--dry-run", "exec", "dotfiles", "touch should-not-exist"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.NoFileExists(s.T(), target)
|
require.NoFileExists(s.T(), target)
|
||||||
@@ -139,7 +139,7 @@ func (s *CLISuite) TestRun_Exec_WithQuiet_SuppressesStatusOutput() {
|
|||||||
castleRoot := filepath.Join(s.homeDir, ".homesick", "repos", "dotfiles")
|
castleRoot := filepath.Join(s.homeDir, ".homesick", "repos", "dotfiles")
|
||||||
require.NoError(s.T(), os.MkdirAll(castleRoot, 0o755))
|
require.NoError(s.T(), os.MkdirAll(castleRoot, 0o755))
|
||||||
|
|
||||||
exitCode := cli.Run([]string{"--quiet", "exec", "dotfiles", "true"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"--quiet", "exec", "dotfiles", "true"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Empty(s.T(), s.stdout.String())
|
require.Empty(s.T(), s.stdout.String())
|
||||||
@@ -147,7 +147,7 @@ func (s *CLISuite) TestRun_Exec_WithQuiet_SuppressesStatusOutput() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestRun_PullAll_NoCastlesIsNoop() {
|
func (s *CLISuite) TestRun_PullAll_NoCastlesIsNoop() {
|
||||||
exitCode := cli.Run([]string{"pull", "--all"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"pull", "--all"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Empty(s.T(), s.stderr.String())
|
require.Empty(s.T(), s.stderr.String())
|
||||||
@@ -158,7 +158,7 @@ func (s *CLISuite) TestRun_Rc_HomesickrcRequiresForce() {
|
|||||||
require.NoError(s.T(), os.MkdirAll(castleRoot, 0o755))
|
require.NoError(s.T(), os.MkdirAll(castleRoot, 0o755))
|
||||||
require.NoError(s.T(), os.WriteFile(filepath.Join(castleRoot, ".homesickrc"), []byte("# ruby\n"), 0o644))
|
require.NoError(s.T(), os.WriteFile(filepath.Join(castleRoot, ".homesickrc"), []byte("# ruby\n"), 0o644))
|
||||||
|
|
||||||
exitCode := cli.Run([]string{"rc", "dotfiles"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"rc", "dotfiles"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.NotEqual(s.T(), 0, exitCode)
|
require.NotEqual(s.T(), 0, exitCode)
|
||||||
require.Contains(s.T(), s.stderr.String(), "--force")
|
require.Contains(s.T(), s.stderr.String(), "--force")
|
||||||
@@ -169,14 +169,14 @@ func (s *CLISuite) TestRun_Rc_WithForceRuns() {
|
|||||||
require.NoError(s.T(), os.MkdirAll(castleRoot, 0o755))
|
require.NoError(s.T(), os.MkdirAll(castleRoot, 0o755))
|
||||||
require.NoError(s.T(), os.WriteFile(filepath.Join(castleRoot, ".homesickrc"), []byte("# ruby\n"), 0o644))
|
require.NoError(s.T(), os.WriteFile(filepath.Join(castleRoot, ".homesickrc"), []byte("# ruby\n"), 0o644))
|
||||||
|
|
||||||
exitCode := cli.Run([]string{"rc", "--force", "dotfiles"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"rc", "--force", "dotfiles"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Empty(s.T(), s.stderr.String())
|
require.Empty(s.T(), s.stderr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestRun_CloneSubcommandHelp() {
|
func (s *CLISuite) TestRun_CloneSubcommandHelp() {
|
||||||
exitCode := cli.Run([]string{"clone", "--help"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"clone", "--help"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Contains(s.T(), s.stdout.String(), "clone")
|
require.Contains(s.T(), s.stdout.String(), "clone")
|
||||||
@@ -189,7 +189,7 @@ func (s *CLISuite) TestRun_Help_UsesProgramNameAndDescription() {
|
|||||||
s.T().Cleanup(func() { os.Args = originalArgs })
|
s.T().Cleanup(func() { os.Args = originalArgs })
|
||||||
os.Args = []string{"gosick"}
|
os.Args = []string{"gosick"}
|
||||||
|
|
||||||
exitCode := cli.Run([]string{"--help"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"--help"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Contains(s.T(), s.stdout.String(), "Usage: gosick")
|
require.Contains(s.T(), s.stdout.String(), "Usage: gosick")
|
||||||
@@ -204,7 +204,7 @@ func (s *CLISuite) TestRun_SymlinkAlias_MatchesLinkCommand() {
|
|||||||
require.NoError(s.T(), os.MkdirAll(castleHome, 0o755))
|
require.NoError(s.T(), os.MkdirAll(castleHome, 0o755))
|
||||||
require.NoError(s.T(), os.WriteFile(filepath.Join(castleHome, ".vimrc"), []byte("set number\n"), 0o644))
|
require.NoError(s.T(), os.WriteFile(filepath.Join(castleHome, ".vimrc"), []byte("set number\n"), 0o644))
|
||||||
|
|
||||||
exitCode := cli.Run([]string{"symlink", "dotfiles"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"symlink", "dotfiles"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
target := filepath.Join(s.homeDir, ".vimrc")
|
target := filepath.Join(s.homeDir, ".vimrc")
|
||||||
@@ -215,7 +215,7 @@ func (s *CLISuite) TestRun_SymlinkAlias_MatchesLinkCommand() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestRun_Commit_PositionalMessageCompatibility() {
|
func (s *CLISuite) TestRun_Commit_PositionalMessageCompatibility() {
|
||||||
exitCode := cli.Run([]string{"--pretend", "commit", "dotfiles", "behavior-suite-commit"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"--pretend", "commit", "dotfiles", "behavior-suite-commit"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Contains(s.T(), s.stdout.String(), "git commit -m behavior-suite-commit")
|
require.Contains(s.T(), s.stdout.String(), "git commit -m behavior-suite-commit")
|
||||||
@@ -225,7 +225,7 @@ func (s *CLISuite) TestRun_Commit_PositionalMessageCompatibility() {
|
|||||||
func (s *CLISuite) TestRun_List_NoArguments() {
|
func (s *CLISuite) TestRun_List_NoArguments() {
|
||||||
s.createCastleRepo("dotfiles")
|
s.createCastleRepo("dotfiles")
|
||||||
|
|
||||||
exitCode := cli.Run([]string{"list"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"list"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Contains(s.T(), s.stdout.String(), "dotfiles")
|
require.Contains(s.T(), s.stdout.String(), "dotfiles")
|
||||||
@@ -235,7 +235,7 @@ func (s *CLISuite) TestRun_List_NoArguments() {
|
|||||||
func (s *CLISuite) TestRun_Generate_CreatesNewCastle() {
|
func (s *CLISuite) TestRun_Generate_CreatesNewCastle() {
|
||||||
castlePath := filepath.Join(s.T().TempDir(), "my-castle")
|
castlePath := filepath.Join(s.T().TempDir(), "my-castle")
|
||||||
|
|
||||||
exitCode := cli.Run([]string{"generate", castlePath}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"generate", castlePath}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.DirExists(s.T(), filepath.Join(castlePath, ".git"))
|
require.DirExists(s.T(), filepath.Join(castlePath, ".git"))
|
||||||
@@ -243,7 +243,7 @@ func (s *CLISuite) TestRun_Generate_CreatesNewCastle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestRun_Clone_WithoutArgs() {
|
func (s *CLISuite) TestRun_Clone_WithoutArgs() {
|
||||||
exitCode := cli.Run([]string{"clone"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"clone"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
// Clone requires arguments, should fail
|
// Clone requires arguments, should fail
|
||||||
require.NotEqual(s.T(), 0, exitCode)
|
require.NotEqual(s.T(), 0, exitCode)
|
||||||
@@ -253,7 +253,7 @@ func (s *CLISuite) TestRun_Status_DefaultCastle() {
|
|||||||
castleRoot := s.createCastleRepo("dotfiles")
|
castleRoot := s.createCastleRepo("dotfiles")
|
||||||
require.NoError(s.T(), os.WriteFile(filepath.Join(castleRoot, "home", ".vimrc"), []byte("changed\n"), 0o644))
|
require.NoError(s.T(), os.WriteFile(filepath.Join(castleRoot, "home", ".vimrc"), []byte("changed\n"), 0o644))
|
||||||
|
|
||||||
exitCode := cli.Run([]string{"status"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"status"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Contains(s.T(), s.stdout.String(), "modified:")
|
require.Contains(s.T(), s.stdout.String(), "modified:")
|
||||||
@@ -264,7 +264,7 @@ func (s *CLISuite) TestRun_Diff_DefaultCastle() {
|
|||||||
castleRoot := s.createCastleRepo("dotfiles")
|
castleRoot := s.createCastleRepo("dotfiles")
|
||||||
require.NoError(s.T(), os.WriteFile(filepath.Join(castleRoot, "home", ".vimrc"), []byte("changed\n"), 0o644))
|
require.NoError(s.T(), os.WriteFile(filepath.Join(castleRoot, "home", ".vimrc"), []byte("changed\n"), 0o644))
|
||||||
|
|
||||||
exitCode := cli.Run([]string{"diff"}, s.stdout, s.stderr)
|
exitCode := cli.Run([]string{"diff"}, bytes.NewBuffer(nil), s.stdout, s.stderr)
|
||||||
|
|
||||||
require.Equal(s.T(), 0, exitCode)
|
require.Equal(s.T(), 0, exitCode)
|
||||||
require.Contains(s.T(), s.stdout.String(), "diff --git")
|
require.Contains(s.T(), s.stdout.String(), "diff --git")
|
||||||
|
|||||||
@@ -21,13 +21,15 @@ type App struct {
|
|||||||
Stdin io.Reader
|
Stdin io.Reader
|
||||||
Stdout io.Writer
|
Stdout io.Writer
|
||||||
Stderr io.Writer
|
Stderr io.Writer
|
||||||
Verbose bool
|
|
||||||
Force bool
|
Force bool
|
||||||
Quiet bool
|
Quiet bool
|
||||||
Pretend bool
|
Pretend bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(stdout io.Writer, stderr io.Writer) (*App, error) {
|
func NewApp(stdin io.Reader, stdout io.Writer, stderr io.Writer) (*App, error) {
|
||||||
|
if stdin == nil {
|
||||||
|
return nil, errors.New("stdin reader cannot be nil")
|
||||||
|
}
|
||||||
if stdout == nil {
|
if stdout == nil {
|
||||||
return nil, errors.New("stdout writer cannot be nil")
|
return nil, errors.New("stdout writer cannot be nil")
|
||||||
}
|
}
|
||||||
@@ -43,7 +45,7 @@ func New(stdout io.Writer, stderr io.Writer) (*App, error) {
|
|||||||
return &App{
|
return &App{
|
||||||
HomeDir: home,
|
HomeDir: home,
|
||||||
ReposDir: filepath.Join(home, ".homesick", "repos"),
|
ReposDir: filepath.Join(home, ".homesick", "repos"),
|
||||||
Stdin: os.Stdin,
|
Stdin: stdin,
|
||||||
Stdout: stdout,
|
Stdout: stdout,
|
||||||
Stderr: stderr,
|
Stderr: stderr,
|
||||||
}, nil
|
}, nil
|
||||||
@@ -845,7 +847,7 @@ func gitOutput(dir string, args ...string) (string, error) {
|
|||||||
// If a .homesickrc file exists in the castle root and no parity.rb wrapper
|
// If a .homesickrc file exists in the castle root and no parity.rb wrapper
|
||||||
// already exists in .homesick.d, a Ruby wrapper script named parity.rb is
|
// already exists in .homesick.d, a Ruby wrapper script named parity.rb is
|
||||||
// written there before execution so that it sorts first.
|
// written there before execution so that it sorts first.
|
||||||
func (a *App) Rc(castle string) error {
|
func (a *App) Rc(castle string, force bool) error {
|
||||||
castleRoot := filepath.Join(a.ReposDir, castle)
|
castleRoot := filepath.Join(a.ReposDir, castle)
|
||||||
if _, err := os.Stat(castleRoot); err != nil {
|
if _, err := os.Stat(castleRoot); err != nil {
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
@@ -857,7 +859,7 @@ func (a *App) Rc(castle string) error {
|
|||||||
homesickD := filepath.Join(castleRoot, ".homesick.d")
|
homesickD := filepath.Join(castleRoot, ".homesick.d")
|
||||||
homesickRc := filepath.Join(castleRoot, ".homesickrc")
|
homesickRc := filepath.Join(castleRoot, ".homesickrc")
|
||||||
|
|
||||||
if _, err := os.Stat(homesickRc); err == nil && !a.Force {
|
if _, err := os.Stat(homesickRc); err == nil && !force {
|
||||||
return errors.New("refusing to run legacy .homesickrc without --force")
|
return errors.New("refusing to run legacy .homesickrc without --force")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,19 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewRejectsNilWriters(t *testing.T) {
|
func TestNewAppRejectsNilReaders(t *testing.T) {
|
||||||
|
t.Run("nil stdin", func(t *testing.T) {
|
||||||
|
app, err := NewApp(nil, &bytes.Buffer{}, &bytes.Buffer{})
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected error for nil stdin")
|
||||||
|
}
|
||||||
|
if app != nil {
|
||||||
|
t.Fatal("expected nil app for nil stdin")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("nil stdout", func(t *testing.T) {
|
t.Run("nil stdout", func(t *testing.T) {
|
||||||
app, err := New(nil, &bytes.Buffer{})
|
app, err := NewApp(new(bytes.Buffer), nil, &bytes.Buffer{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error for nil stdout")
|
t.Fatal("expected error for nil stdout")
|
||||||
}
|
}
|
||||||
@@ -18,7 +28,7 @@ func TestNewRejectsNilWriters(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("nil stderr", func(t *testing.T) {
|
t.Run("nil stderr", func(t *testing.T) {
|
||||||
app, err := New(&bytes.Buffer{}, nil)
|
app, err := NewApp(new(bytes.Buffer), &bytes.Buffer{}, nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error for nil stderr")
|
t.Fatal("expected error for nil stderr")
|
||||||
}
|
}
|
||||||
@@ -49,11 +59,12 @@ func TestDeriveDestination(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewInitializesApp(t *testing.T) {
|
func TestNewAppInitializesApp(t *testing.T) {
|
||||||
|
stdin := new(bytes.Buffer)
|
||||||
stdout := &bytes.Buffer{}
|
stdout := &bytes.Buffer{}
|
||||||
stderr := &bytes.Buffer{}
|
stderr := &bytes.Buffer{}
|
||||||
|
|
||||||
app, err := New(stdout, stderr)
|
app, err := NewApp(stdin, stdout, stderr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -61,6 +72,9 @@ func TestNewInitializesApp(t *testing.T) {
|
|||||||
t.Fatal("expected app instance")
|
t.Fatal("expected app instance")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if app.Stdin != stdin {
|
||||||
|
t.Fatal("expected stdin reader to be assigned")
|
||||||
|
}
|
||||||
if app.Stdout != stdout {
|
if app.Stdout != stdout {
|
||||||
t.Fatal("expected stdout writer to be assigned")
|
t.Fatal("expected stdout writer to be assigned")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ var _ io.Writer
|
|||||||
// TestRc_UnknownCastleReturnsError ensures Rc returns an error when the
|
// TestRc_UnknownCastleReturnsError ensures Rc returns an error when the
|
||||||
// castle directory does not exist.
|
// castle directory does not exist.
|
||||||
func (s *RcSuite) TestRc_UnknownCastleReturnsError() {
|
func (s *RcSuite) TestRc_UnknownCastleReturnsError() {
|
||||||
err := s.app.Rc("nonexistent")
|
err := s.app.Rc("nonexistent", false)
|
||||||
require.Error(s.T(), err)
|
require.Error(s.T(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ func (s *RcSuite) TestRc_UnknownCastleReturnsError() {
|
|||||||
// .homesickrc are present.
|
// .homesickrc are present.
|
||||||
func (s *RcSuite) TestRc_NoScriptsAndNoHomesickrcIsNoop() {
|
func (s *RcSuite) TestRc_NoScriptsAndNoHomesickrcIsNoop() {
|
||||||
s.createCastle("dotfiles")
|
s.createCastle("dotfiles")
|
||||||
require.NoError(s.T(), s.app.Rc("dotfiles"))
|
require.NoError(s.T(), s.app.Rc("dotfiles", false))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestRc_HomesickrcRequiresForce ensures legacy .homesickrc does not run
|
// TestRc_HomesickrcRequiresForce ensures legacy .homesickrc does not run
|
||||||
@@ -71,7 +71,7 @@ func (s *RcSuite) TestRc_HomesickrcRequiresForce() {
|
|||||||
homesickRc := filepath.Join(castleRoot, ".homesickrc")
|
homesickRc := filepath.Join(castleRoot, ".homesickrc")
|
||||||
require.NoError(s.T(), os.WriteFile(homesickRc, []byte("# ruby setup code\n"), 0o644))
|
require.NoError(s.T(), os.WriteFile(homesickRc, []byte("# ruby setup code\n"), 0o644))
|
||||||
|
|
||||||
err := s.app.Rc("dotfiles")
|
err := s.app.Rc("dotfiles", false)
|
||||||
require.Error(s.T(), err)
|
require.Error(s.T(), err)
|
||||||
require.Contains(s.T(), err.Error(), "--force")
|
require.Contains(s.T(), err.Error(), "--force")
|
||||||
require.NoFileExists(s.T(), filepath.Join(castleRoot, ".homesick.d", "parity.rb"))
|
require.NoFileExists(s.T(), filepath.Join(castleRoot, ".homesick.d", "parity.rb"))
|
||||||
@@ -84,8 +84,7 @@ func (s *RcSuite) TestRc_HomesickrcRunsWithForce() {
|
|||||||
homesickRc := filepath.Join(castleRoot, ".homesickrc")
|
homesickRc := filepath.Join(castleRoot, ".homesickrc")
|
||||||
require.NoError(s.T(), os.WriteFile(homesickRc, []byte("# ruby setup code\n"), 0o644))
|
require.NoError(s.T(), os.WriteFile(homesickRc, []byte("# ruby setup code\n"), 0o644))
|
||||||
|
|
||||||
s.app.Force = true
|
require.NoError(s.T(), s.app.Rc("dotfiles", true))
|
||||||
require.NoError(s.T(), s.app.Rc("dotfiles"))
|
|
||||||
require.FileExists(s.T(), filepath.Join(castleRoot, ".homesick.d", "parity.rb"))
|
require.FileExists(s.T(), filepath.Join(castleRoot, ".homesick.d", "parity.rb"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +102,7 @@ func (s *RcSuite) TestRc_ExecutesScriptsInSortedOrder() {
|
|||||||
require.NoError(s.T(), os.WriteFile(scriptA, []byte("#!/bin/sh\necho a >> "+orderFile+"\n"), 0o755))
|
require.NoError(s.T(), os.WriteFile(scriptA, []byte("#!/bin/sh\necho a >> "+orderFile+"\n"), 0o755))
|
||||||
require.NoError(s.T(), os.WriteFile(scriptB, []byte("#!/bin/sh\necho b >> "+orderFile+"\n"), 0o755))
|
require.NoError(s.T(), os.WriteFile(scriptB, []byte("#!/bin/sh\necho b >> "+orderFile+"\n"), 0o755))
|
||||||
|
|
||||||
require.NoError(s.T(), s.app.Rc("dotfiles"))
|
require.NoError(s.T(), s.app.Rc("dotfiles", false))
|
||||||
|
|
||||||
content, err := os.ReadFile(orderFile)
|
content, err := os.ReadFile(orderFile)
|
||||||
require.NoError(s.T(), err)
|
require.NoError(s.T(), err)
|
||||||
@@ -121,7 +120,7 @@ func (s *RcSuite) TestRc_SkipsNonExecutableFiles() {
|
|||||||
// Write a script that would exit 1 if actually run — verify it is skipped.
|
// Write a script that would exit 1 if actually run — verify it is skipped.
|
||||||
require.NoError(s.T(), os.WriteFile(notExec, []byte("#!/bin/sh\nexit 1\n"), 0o644))
|
require.NoError(s.T(), os.WriteFile(notExec, []byte("#!/bin/sh\nexit 1\n"), 0o644))
|
||||||
|
|
||||||
require.NoError(s.T(), s.app.Rc("dotfiles"))
|
require.NoError(s.T(), s.app.Rc("dotfiles", false))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestRc_HomesickrcCreatesRubyWrapper verifies that a .homesickrc file causes
|
// TestRc_HomesickrcCreatesRubyWrapper verifies that a .homesickrc file causes
|
||||||
@@ -130,9 +129,7 @@ func (s *RcSuite) TestRc_HomesickrcCreatesRubyWrapper() {
|
|||||||
castleRoot := s.createCastle("dotfiles")
|
castleRoot := s.createCastle("dotfiles")
|
||||||
homesickRc := filepath.Join(castleRoot, ".homesickrc")
|
homesickRc := filepath.Join(castleRoot, ".homesickrc")
|
||||||
require.NoError(s.T(), os.WriteFile(homesickRc, []byte("# ruby setup code\n"), 0o644))
|
require.NoError(s.T(), os.WriteFile(homesickRc, []byte("# ruby setup code\n"), 0o644))
|
||||||
s.app.Force = true
|
require.NoError(s.T(), s.app.Rc("dotfiles", true))
|
||||||
|
|
||||||
require.NoError(s.T(), s.app.Rc("dotfiles"))
|
|
||||||
|
|
||||||
wrapperPath := filepath.Join(castleRoot, ".homesick.d", "parity.rb")
|
wrapperPath := filepath.Join(castleRoot, ".homesick.d", "parity.rb")
|
||||||
require.FileExists(s.T(), wrapperPath)
|
require.FileExists(s.T(), wrapperPath)
|
||||||
@@ -152,7 +149,6 @@ func (s *RcSuite) TestRc_HomesickrcWrapperNotOverwrittenIfExists() {
|
|||||||
castleRoot := s.createCastle("dotfiles")
|
castleRoot := s.createCastle("dotfiles")
|
||||||
homesickRc := filepath.Join(castleRoot, ".homesickrc")
|
homesickRc := filepath.Join(castleRoot, ".homesickrc")
|
||||||
require.NoError(s.T(), os.WriteFile(homesickRc, []byte("# ruby setup code\n"), 0o644))
|
require.NoError(s.T(), os.WriteFile(homesickRc, []byte("# ruby setup code\n"), 0o644))
|
||||||
s.app.Force = true
|
|
||||||
|
|
||||||
homesickD := filepath.Join(castleRoot, ".homesick.d")
|
homesickD := filepath.Join(castleRoot, ".homesick.d")
|
||||||
require.NoError(s.T(), os.MkdirAll(homesickD, 0o755))
|
require.NoError(s.T(), os.MkdirAll(homesickD, 0o755))
|
||||||
@@ -160,7 +156,7 @@ func (s *RcSuite) TestRc_HomesickrcWrapperNotOverwrittenIfExists() {
|
|||||||
originalContent := []byte("#!/bin/sh\n# pre-existing wrapper\n")
|
originalContent := []byte("#!/bin/sh\n# pre-existing wrapper\n")
|
||||||
require.NoError(s.T(), os.WriteFile(wrapperPath, originalContent, 0o755))
|
require.NoError(s.T(), os.WriteFile(wrapperPath, originalContent, 0o755))
|
||||||
|
|
||||||
require.NoError(s.T(), s.app.Rc("dotfiles"))
|
require.NoError(s.T(), s.app.Rc("dotfiles", true))
|
||||||
|
|
||||||
content, err := os.ReadFile(wrapperPath)
|
content, err := os.ReadFile(wrapperPath)
|
||||||
require.NoError(s.T(), err)
|
require.NoError(s.T(), err)
|
||||||
@@ -173,7 +169,6 @@ func (s *RcSuite) TestRc_HomesickrcWrapperCreatedBeforeExecution() {
|
|||||||
castleRoot := s.createCastle("dotfiles")
|
castleRoot := s.createCastle("dotfiles")
|
||||||
homesickRc := filepath.Join(castleRoot, ".homesickrc")
|
homesickRc := filepath.Join(castleRoot, ".homesickrc")
|
||||||
require.NoError(s.T(), os.WriteFile(homesickRc, []byte("# ruby setup code\n"), 0o644))
|
require.NoError(s.T(), os.WriteFile(homesickRc, []byte("# ruby setup code\n"), 0o644))
|
||||||
s.app.Force = true
|
|
||||||
|
|
||||||
homesickD := filepath.Join(castleRoot, ".homesick.d")
|
homesickD := filepath.Join(castleRoot, ".homesick.d")
|
||||||
require.NoError(s.T(), os.MkdirAll(homesickD, 0o755))
|
require.NoError(s.T(), os.MkdirAll(homesickD, 0o755))
|
||||||
@@ -186,7 +181,7 @@ func (s *RcSuite) TestRc_HomesickrcWrapperCreatedBeforeExecution() {
|
|||||||
"#!/bin/sh\n[ -f "+wrapperPath+" ] && echo present >> "+orderFile+"\n",
|
"#!/bin/sh\n[ -f "+wrapperPath+" ] && echo present >> "+orderFile+"\n",
|
||||||
), 0o755))
|
), 0o755))
|
||||||
|
|
||||||
require.NoError(s.T(), s.app.Rc("dotfiles"))
|
require.NoError(s.T(), s.app.Rc("dotfiles", true))
|
||||||
|
|
||||||
content, err := os.ReadFile(orderFile)
|
content, err := os.ReadFile(orderFile)
|
||||||
require.NoError(s.T(), err)
|
require.NoError(s.T(), err)
|
||||||
@@ -203,7 +198,7 @@ func (s *RcSuite) TestRc_FailingScriptReturnsError() {
|
|||||||
failing := filepath.Join(homesickD, "10_fail.sh")
|
failing := filepath.Join(homesickD, "10_fail.sh")
|
||||||
require.NoError(s.T(), os.WriteFile(failing, []byte("#!/bin/sh\nexit 42\n"), 0o755))
|
require.NoError(s.T(), os.WriteFile(failing, []byte("#!/bin/sh\nexit 42\n"), 0o755))
|
||||||
|
|
||||||
err := s.app.Rc("dotfiles")
|
err := s.app.Rc("dotfiles", false)
|
||||||
require.Error(s.T(), err)
|
require.Error(s.T(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +212,7 @@ func (s *RcSuite) TestRc_ScriptOutputForwarded() {
|
|||||||
script := filepath.Join(homesickD, "10_output.sh")
|
script := filepath.Join(homesickD, "10_output.sh")
|
||||||
require.NoError(s.T(), os.WriteFile(script, []byte("#!/bin/sh\necho hello\necho world >&2\n"), 0o755))
|
require.NoError(s.T(), os.WriteFile(script, []byte("#!/bin/sh\necho hello\necho world >&2\n"), 0o755))
|
||||||
|
|
||||||
require.NoError(s.T(), s.app.Rc("dotfiles"))
|
require.NoError(s.T(), s.app.Rc("dotfiles", false))
|
||||||
require.Contains(s.T(), s.stdout.String(), "hello")
|
require.Contains(s.T(), s.stdout.String(), "hello")
|
||||||
require.Contains(s.T(), s.stderr.String(), "world")
|
require.Contains(s.T(), s.stderr.String(), "world")
|
||||||
}
|
}
|
||||||
@@ -232,6 +227,6 @@ func (s *RcSuite) TestRc_ScriptsRunWithCwdSetToCastleRoot() {
|
|||||||
script := filepath.Join(homesickD, "10_pwd.sh")
|
script := filepath.Join(homesickD, "10_pwd.sh")
|
||||||
require.NoError(s.T(), os.WriteFile(script, []byte("#!/bin/sh\npwd\n"), 0o755))
|
require.NoError(s.T(), os.WriteFile(script, []byte("#!/bin/sh\npwd\n"), 0o755))
|
||||||
|
|
||||||
require.NoError(s.T(), s.app.Rc("dotfiles"))
|
require.NoError(s.T(), s.app.Rc("dotfiles", false))
|
||||||
require.Contains(s.T(), s.stdout.String(), castleRoot)
|
require.Contains(s.T(), s.stdout.String(), castleRoot)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user