From 1759ddf2470389d8de7ccedad24caf66c3cdb7d5 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 29 Sep 2020 19:10:57 +1000 Subject: [PATCH] move OS commands into their own package --- pkg/app/app.go | 5 +- pkg/commands/commit_list_builder.go | 7 +- pkg/commands/commit_list_builder_test.go | 5 +- pkg/commands/dummies.go | 51 ++---------- pkg/commands/git.go | 21 ++--- pkg/commands/git_test.go | 5 +- pkg/commands/os_default_platform.go | 20 ----- pkg/commands/oscommands/dummies.go | 11 +++ .../{ => oscommands}/exec_live_default.go | 2 +- .../{ => oscommands}/exec_live_win.go | 2 +- pkg/commands/{ => oscommands}/os.go | 82 +++++++++---------- .../oscommands/os_default_platform.go | 20 +++++ pkg/commands/{ => oscommands}/os_test.go | 20 ++--- pkg/commands/{ => oscommands}/os_windows.go | 4 +- pkg/commands/pull_request_test.go | 1 + pkg/config/dummies.go | 26 ++++++ pkg/gui/gui.go | 5 +- pkg/gui/reset_menu_panel.go | 6 +- pkg/gui/undoing.go | 4 +- pkg/tasks/tasks.go | 4 +- pkg/test/test.go | 3 +- pkg/updates/updates.go | 6 +- pkg/utils/dummies.go | 14 ++++ pkg/{commands => utils}/errors.go | 2 +- 24 files changed, 175 insertions(+), 151 deletions(-) delete mode 100644 pkg/commands/os_default_platform.go create mode 100644 pkg/commands/oscommands/dummies.go rename pkg/commands/{ => oscommands}/exec_live_default.go (99%) rename pkg/commands/{ => oscommands}/exec_live_win.go (95%) rename pkg/commands/{ => oscommands}/os.go (88%) create mode 100644 pkg/commands/oscommands/os_default_platform.go rename pkg/commands/{ => oscommands}/os_test.go (93%) rename pkg/commands/{ => oscommands}/os_windows.go (81%) create mode 100644 pkg/config/dummies.go create mode 100644 pkg/utils/dummies.go rename pkg/{commands => utils}/errors.go (95%) diff --git a/pkg/app/app.go b/pkg/app/app.go index d200e3f15..d41f208d7 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -16,6 +16,7 @@ import ( "github.com/aybabtme/humanlog" "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/env" "github.com/jesseduffield/lazygit/pkg/gui" @@ -30,7 +31,7 @@ type App struct { Config config.AppConfigurer Log *logrus.Entry - OSCommand *commands.OSCommand + OSCommand *oscommands.OSCommand GitCommand *commands.GitCommand Gui *gui.Gui Tr *i18n.Localizer @@ -106,7 +107,7 @@ func NewApp(config config.AppConfigurer, filterPath string) (*App, error) { return app, nil } - app.OSCommand = commands.NewOSCommand(app.Log, config) + app.OSCommand = oscommands.NewOSCommand(app.Log, config) app.Updater, err = updates.NewUpdater(app.Log, config, app.OSCommand, app.Tr) if err != nil { diff --git a/pkg/commands/commit_list_builder.go b/pkg/commands/commit_list_builder.go index 32b3de0d8..d29e03a28 100644 --- a/pkg/commands/commit_list_builder.go +++ b/pkg/commands/commit_list_builder.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/fatih/color" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/i18n" "github.com/jesseduffield/lazygit/pkg/models" "github.com/sirupsen/logrus" @@ -31,12 +32,12 @@ const SEPARATION_CHAR = "|" type CommitListBuilder struct { Log *logrus.Entry GitCommand *GitCommand - OSCommand *OSCommand + OSCommand *oscommands.OSCommand Tr *i18n.Localizer } // NewCommitListBuilder builds a new commit list builder -func NewCommitListBuilder(log *logrus.Entry, gitCommand *GitCommand, osCommand *OSCommand, tr *i18n.Localizer) *CommitListBuilder { +func NewCommitListBuilder(log *logrus.Entry, gitCommand *GitCommand, osCommand *oscommands.OSCommand, tr *i18n.Localizer) *CommitListBuilder { return &CommitListBuilder{ Log: log, GitCommand: gitCommand, @@ -151,7 +152,7 @@ func (c *CommitListBuilder) GetCommits(opts GetCommitsOptions) ([]*models.Commit cmd := c.getLogCmd(opts) - err = RunLineOutputCmd(cmd, func(line string) (bool, error) { + err = oscommands.RunLineOutputCmd(cmd, func(line string) (bool, error) { if strings.Split(line, " ")[0] != "gpg:" { commit := c.extractCommitFromLine(line) if commit.Sha == firstPushedCommit { diff --git a/pkg/commands/commit_list_builder_test.go b/pkg/commands/commit_list_builder_test.go index cb57b28df..1c35f6c63 100644 --- a/pkg/commands/commit_list_builder_test.go +++ b/pkg/commands/commit_list_builder_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/jesseduffield/lazygit/pkg/i18n" + "github.com/jesseduffield/lazygit/pkg/utils" "github.com/stretchr/testify/assert" ) @@ -13,10 +14,10 @@ func NewDummyCommitListBuilder() *CommitListBuilder { osCommand := NewDummyOSCommand() return &CommitListBuilder{ - Log: NewDummyLog(), + Log: utils.NewDummyLog(), GitCommand: NewDummyGitCommandWithOSCommand(osCommand), OSCommand: osCommand, - Tr: i18n.NewLocalizer(NewDummyLog()), + Tr: i18n.NewLocalizer(utils.NewDummyLog()), } } diff --git a/pkg/commands/dummies.go b/pkg/commands/dummies.go index 57bf1bed9..da03d2f08 100644 --- a/pkg/commands/dummies.go +++ b/pkg/commands/dummies.go @@ -1,61 +1,24 @@ package commands import ( - "io/ioutil" - + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/i18n" - "github.com/sirupsen/logrus" - "github.com/spf13/viper" - yaml "gopkg.in/yaml.v2" + "github.com/jesseduffield/lazygit/pkg/utils" ) -// This file exports dummy constructors for use by tests in other packages - -// NewDummyOSCommand creates a new dummy OSCommand for testing -func NewDummyOSCommand() *OSCommand { - return NewOSCommand(NewDummyLog(), NewDummyAppConfig()) -} - -// NewDummyAppConfig creates a new dummy AppConfig for testing -func NewDummyAppConfig() *config.AppConfig { - userConfig := viper.New() - userConfig.SetConfigType("yaml") - if err := config.LoadDefaults(userConfig, config.GetDefaultConfig()); err != nil { - panic(err) - } - appConfig := &config.AppConfig{ - Name: "lazygit", - Version: "unversioned", - Commit: "", - BuildDate: "", - Debug: false, - BuildSource: "", - UserConfig: userConfig, - } - _ = yaml.Unmarshal([]byte{}, appConfig.AppState) - return appConfig -} - -// NewDummyLog creates a new dummy Log for testing -func NewDummyLog() *logrus.Entry { - log := logrus.New() - log.Out = ioutil.Discard - return log.WithField("test", "test") -} - // NewDummyGitCommand creates a new dummy GitCommand for testing func NewDummyGitCommand() *GitCommand { - return NewDummyGitCommandWithOSCommand(NewDummyOSCommand()) + return NewDummyGitCommandWithOSCommand(oscommands.NewDummyOSCommand()) } // NewDummyGitCommandWithOSCommand creates a new dummy GitCommand for testing -func NewDummyGitCommandWithOSCommand(osCommand *OSCommand) *GitCommand { +func NewDummyGitCommandWithOSCommand(osCommand *oscommands.OSCommand) *GitCommand { return &GitCommand{ - Log: NewDummyLog(), + Log: utils.NewDummyLog(), OSCommand: osCommand, - Tr: i18n.NewLocalizer(NewDummyLog()), - Config: NewDummyAppConfig(), + Tr: i18n.NewLocalizer(utils.NewDummyLog()), + Config: config.NewDummyAppConfig(), getGlobalGitConfig: func(string) (string, error) { return "", nil }, getLocalGitConfig: func(string) (string, error) { return "", nil }, removeFile: func(string) error { return nil }, diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 5c3e423db..970aaa35c 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -16,6 +16,7 @@ import ( "github.com/go-errors/errors" gogit "github.com/go-git/go-git/v5" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/commands/patch" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/env" @@ -42,7 +43,7 @@ func navigateToRepoRootDirectory(stat func(string) (os.FileInfo, error), chdir f // we've been given the git directory explicitly so no need to navigate to it _, err := stat(gitDir) if err != nil { - return WrapError(err) + return utils.WrapError(err) } return nil @@ -58,11 +59,11 @@ func navigateToRepoRootDirectory(stat func(string) (os.FileInfo, error), chdir f } if !os.IsNotExist(err) { - return WrapError(err) + return utils.WrapError(err) } if err = chdir(".."); err != nil { - return WrapError(err) + return utils.WrapError(err) } } } @@ -112,7 +113,7 @@ func setupRepository(openGitRepository func(string) (*gogit.Repository, error), // GitCommand is our main git interface type GitCommand struct { Log *logrus.Entry - OSCommand *OSCommand + OSCommand *oscommands.OSCommand Repo *gogit.Repository Tr *i18n.Localizer Config config.AppConfigurer @@ -128,7 +129,7 @@ type GitCommand struct { } // NewGitCommand it runs git commands -func NewGitCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Localizer, config config.AppConfigurer) (*GitCommand, error) { +func NewGitCommand(log *logrus.Entry, osCommand *oscommands.OSCommand, tr *i18n.Localizer, config config.AppConfigurer) (*GitCommand, error) { var repo *gogit.Repository // see what our default push behaviour is @@ -464,7 +465,7 @@ func (c *GitCommand) Fetch(opts FetchOptions) error { } // ResetToCommit reset to commit -func (c *GitCommand) ResetToCommit(sha string, strength string, options RunCommandOptions) error { +func (c *GitCommand) ResetToCommit(sha string, strength string, options oscommands.RunCommandOptions) error { return c.OSCommand.RunCommandWithOptions(fmt.Sprintf("git reset --%s %s", strength, sha), options) } @@ -604,7 +605,7 @@ func (c *GitCommand) Push(branchName string, force bool, upstream string, args s // CatFile obtains the content of a file func (c *GitCommand) CatFile(fileName string) (string, error) { - return c.OSCommand.RunCommandWithOutput("%s %s", c.OSCommand.Platform.catCmd, c.OSCommand.Quote(fileName)) + return c.OSCommand.RunCommandWithOutput("%s %s", c.OSCommand.Platform.CatCmd, c.OSCommand.Quote(fileName)) } // StageFile stages a file @@ -765,7 +766,7 @@ func (c *GitCommand) Checkout(branch string, options CheckoutOptions) error { if options.Force { forceArg = "--force " } - return c.OSCommand.RunCommandWithOptions(fmt.Sprintf("git checkout %s %s", forceArg, branch), RunCommandOptions{EnvVars: options.EnvVars}) + return c.OSCommand.RunCommandWithOptions(fmt.Sprintf("git checkout %s %s", forceArg, branch), oscommands.RunCommandOptions{EnvVars: options.EnvVars}) } // PrepareCommitAmendSubProcess prepares a subprocess for `git commit --amend --allow-empty` @@ -972,7 +973,7 @@ func (c *GitCommand) PrepareInteractiveRebaseCommand(baseSha string, todo string c.Log.WithField("command", cmdStr).Info("RunCommand") splitCmd := str.ToArgv(cmdStr) - cmd := c.OSCommand.command(splitCmd[0], splitCmd[1:]...) + cmd := c.OSCommand.Command(splitCmd[0], splitCmd[1:]...) gitSequenceEditor := ex if todo == "" { @@ -1391,7 +1392,7 @@ func (c *GitCommand) GetReflogCommits(lastReflogCommit *models.Commit, filterPat cmd := c.OSCommand.ExecutableFromString(fmt.Sprintf("git reflog --abbrev=20 --date=unix %s", filterPathArg)) onlyObtainedNewReflogCommits := false - err := RunLineOutputCmd(cmd, func(line string) (bool, error) { + err := oscommands.RunLineOutputCmd(cmd, func(line string) (bool, error) { match := re.FindStringSubmatch(line) if len(match) <= 1 { return false, nil diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go index 17f31e9cd..812f24cc3 100644 --- a/pkg/commands/git_test.go +++ b/pkg/commands/git_test.go @@ -12,9 +12,12 @@ import ( "github.com/go-errors/errors" gogit "github.com/go-git/go-git/v5" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" + "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/i18n" "github.com/jesseduffield/lazygit/pkg/models" "github.com/jesseduffield/lazygit/pkg/test" + "github.com/jesseduffield/lazygit/pkg/utils" "github.com/stretchr/testify/assert" ) @@ -251,7 +254,7 @@ func TestNewGitCommand(t *testing.T) { for _, s := range scenarios { t.Run(s.testName, func(t *testing.T) { s.setup() - s.test(NewGitCommand(NewDummyLog(), NewDummyOSCommand(), i18n.NewLocalizer(NewDummyLog()), NewDummyAppConfig())) + s.test(NewGitCommand(utils.NewDummyLog(), oscommands.NewDummyOSCommand(), i18n.NewLocalizer(utils.NewDummyLog()), config.NewDummyAppConfig())) }) } } diff --git a/pkg/commands/os_default_platform.go b/pkg/commands/os_default_platform.go deleted file mode 100644 index 864b1f3c8..000000000 --- a/pkg/commands/os_default_platform.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build !windows - -package commands - -import ( - "runtime" -) - -func getPlatform() *Platform { - return &Platform{ - os: runtime.GOOS, - catCmd: "cat", - shell: "bash", - shellArg: "-c", - escapedQuote: "'", - openCommand: "open {{filename}}", - openLinkCommand: "open {{link}}", - fallbackEscapedQuote: "\"", - } -} diff --git a/pkg/commands/oscommands/dummies.go b/pkg/commands/oscommands/dummies.go new file mode 100644 index 000000000..bb6f741f1 --- /dev/null +++ b/pkg/commands/oscommands/dummies.go @@ -0,0 +1,11 @@ +package oscommands + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + "github.com/jesseduffield/lazygit/pkg/utils" +) + +// NewDummyOSCommand creates a new dummy OSCommand for testing +func NewDummyOSCommand() *OSCommand { + return NewOSCommand(utils.NewDummyLog(), config.NewDummyAppConfig()) +} diff --git a/pkg/commands/exec_live_default.go b/pkg/commands/oscommands/exec_live_default.go similarity index 99% rename from pkg/commands/exec_live_default.go rename to pkg/commands/oscommands/exec_live_default.go index bb3ffcdc1..2e09e38dd 100644 --- a/pkg/commands/exec_live_default.go +++ b/pkg/commands/oscommands/exec_live_default.go @@ -1,6 +1,6 @@ // +build !windows -package commands +package oscommands import ( "bufio" diff --git a/pkg/commands/exec_live_win.go b/pkg/commands/oscommands/exec_live_win.go similarity index 95% rename from pkg/commands/exec_live_win.go rename to pkg/commands/oscommands/exec_live_win.go index d06cb920b..1f5a4df52 100644 --- a/pkg/commands/exec_live_win.go +++ b/pkg/commands/oscommands/exec_live_win.go @@ -1,6 +1,6 @@ // +build windows -package commands +package oscommands // RunCommandWithOutputLiveWrapper runs a command live but because of windows compatibility this command can't be ran there // TODO: Remove this hack and replace it with a proper way to run commands live on windows diff --git a/pkg/commands/os.go b/pkg/commands/oscommands/os.go similarity index 88% rename from pkg/commands/os.go rename to pkg/commands/oscommands/os.go index 74bcd1a78..45effa94d 100644 --- a/pkg/commands/os.go +++ b/pkg/commands/oscommands/os.go @@ -1,4 +1,4 @@ -package commands +package oscommands import ( "bufio" @@ -24,14 +24,14 @@ import ( // Platform stores the os state type Platform struct { - os string - catCmd string - shell string - shellArg string - escapedQuote string - openCommand string - openLinkCommand string - fallbackEscapedQuote string + OS string + CatCmd string + Shell string + ShellArg string + EscapedQuote string + OpenCommand string + OpenLinkCommand string + FallbackEscapedQuote string } // OSCommand holds all the os commands @@ -39,10 +39,10 @@ type OSCommand struct { Log *logrus.Entry Platform *Platform Config config.AppConfigurer - command func(string, ...string) *exec.Cmd - beforeExecuteCmd func(*exec.Cmd) - getGlobalGitConfig func(string) (string, error) - getenv func(string) string + Command func(string, ...string) *exec.Cmd + BeforeExecuteCmd func(*exec.Cmd) + GetGlobalGitConfig func(string) (string, error) + Getenv func(string) string } // NewOSCommand os command runner @@ -51,21 +51,21 @@ func NewOSCommand(log *logrus.Entry, config config.AppConfigurer) *OSCommand { Log: log, Platform: getPlatform(), Config: config, - command: exec.Command, - beforeExecuteCmd: func(*exec.Cmd) {}, - getGlobalGitConfig: gitconfig.Global, - getenv: os.Getenv, + Command: exec.Command, + BeforeExecuteCmd: func(*exec.Cmd) {}, + GetGlobalGitConfig: gitconfig.Global, + Getenv: os.Getenv, } } // SetCommand sets the command function used by the struct. // To be used for testing only func (c *OSCommand) SetCommand(cmd func(string, ...string) *exec.Cmd) { - c.command = cmd + c.Command = cmd } func (c *OSCommand) SetBeforeExecuteCmd(cmd func(*exec.Cmd)) { - c.beforeExecuteCmd = cmd + c.BeforeExecuteCmd = cmd } type RunCommandOptions struct { @@ -102,7 +102,7 @@ func (c *OSCommand) RunCommandWithOutput(formatString string, formatArgs ...inte // RunExecutableWithOutput runs an executable file and returns its output func (c *OSCommand) RunExecutableWithOutput(cmd *exec.Cmd) (string, error) { - c.beforeExecuteCmd(cmd) + c.BeforeExecuteCmd(cmd) return sanitisedCommandOutput(cmd.CombinedOutput()) } @@ -115,7 +115,7 @@ func (c *OSCommand) RunExecutable(cmd *exec.Cmd) error { // ExecutableFromString takes a string like `git status` and returns an executable command for it func (c *OSCommand) ExecutableFromString(commandStr string) *exec.Cmd { splitCmd := str.ToArgv(commandStr) - cmd := c.command(splitCmd[0], splitCmd[1:]...) + cmd := c.Command(splitCmd[0], splitCmd[1:]...) cmd.Env = append(os.Environ(), "GIT_OPTIONAL_LOCKS=0") return cmd } @@ -124,13 +124,13 @@ func (c *OSCommand) ExecutableFromString(commandStr string) *exec.Cmd { func (c *OSCommand) ShellCommandFromString(commandStr string) *exec.Cmd { quotedCommand := "" // Windows does not seem to like quotes around the command - if c.Platform.os == "windows" { + if c.Platform.OS == "windows" { quotedCommand = commandStr } else { quotedCommand = strconv.Quote(commandStr) } - shellCommand := fmt.Sprintf("%s %s %s", c.Platform.shell, c.Platform.shellArg, quotedCommand) + shellCommand := fmt.Sprintf("%s %s %s", c.Platform.Shell, c.Platform.ShellArg, quotedCommand) return c.ExecutableFromString(shellCommand) } @@ -188,7 +188,7 @@ func (c *OSCommand) RunDirectCommand(command string) (string, error) { c.Log.WithField("command", command).Info("RunDirectCommand") return sanitisedCommandOutput( - c.command(c.Platform.shell, c.Platform.shellArg, command). + c.Command(c.Platform.Shell, c.Platform.ShellArg, command). CombinedOutput(), ) } @@ -199,7 +199,7 @@ func sanitisedCommandOutput(output []byte, err error) (string, error) { // errors like 'exit status 1' are not very useful so we'll create an error // from the combined output if outputString == "" { - return "", WrapError(err) + return "", utils.WrapError(err) } return outputString, errors.New(outputString) } @@ -233,13 +233,13 @@ func (c *OSCommand) OpenLink(link string) error { // EditFile opens a file in a subprocess using whatever editor is available, // falling back to core.editor, VISUAL, EDITOR, then vi func (c *OSCommand) EditFile(filename string) (*exec.Cmd, error) { - editor, _ := c.getGlobalGitConfig("core.editor") + editor, _ := c.GetGlobalGitConfig("core.editor") if editor == "" { - editor = c.getenv("VISUAL") + editor = c.Getenv("VISUAL") } if editor == "" { - editor = c.getenv("EDITOR") + editor = c.Getenv("EDITOR") } if editor == "" { if err := c.RunCommand("which vi"); err == nil { @@ -258,7 +258,7 @@ func (c *OSCommand) EditFile(filename string) (*exec.Cmd, error) { // PrepareSubProcess iniPrepareSubProcessrocess then tells the Gui to switch to it // TODO: see if this needs to exist, given that ExecutableFromString does the same things func (c *OSCommand) PrepareSubProcess(cmdName string, commandArgs ...string) *exec.Cmd { - cmd := c.command(cmdName, commandArgs...) + cmd := c.Command(cmdName, commandArgs...) if cmd != nil { cmd.Env = append(os.Environ(), "GIT_OPTIONAL_LOCKS=0") } @@ -268,9 +268,9 @@ func (c *OSCommand) PrepareSubProcess(cmdName string, commandArgs ...string) *ex // Quote wraps a message in platform-specific quotation marks func (c *OSCommand) Quote(message string) string { message = strings.Replace(message, "`", "\\`", -1) - escapedQuote := c.Platform.escapedQuote - if strings.Contains(message, c.Platform.escapedQuote) { - escapedQuote = c.Platform.fallbackEscapedQuote + escapedQuote := c.Platform.EscapedQuote + if strings.Contains(message, c.Platform.EscapedQuote) { + escapedQuote = c.Platform.FallbackEscapedQuote } return escapedQuote + message + escapedQuote } @@ -285,13 +285,13 @@ func (c *OSCommand) Unquote(message string) string { func (c *OSCommand) AppendLineToFile(filename, line string) error { f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) if err != nil { - return WrapError(err) + return utils.WrapError(err) } defer f.Close() _, err = f.WriteString("\n" + line) if err != nil { - return WrapError(err) + return utils.WrapError(err) } return nil } @@ -301,16 +301,16 @@ func (c *OSCommand) CreateTempFile(filename, content string) (string, error) { tmpfile, err := ioutil.TempFile("", filename) if err != nil { c.Log.Error(err) - return "", WrapError(err) + return "", utils.WrapError(err) } if _, err := tmpfile.WriteString(content); err != nil { c.Log.Error(err) - return "", WrapError(err) + return "", utils.WrapError(err) } if err := tmpfile.Close(); err != nil { c.Log.Error(err) - return "", WrapError(err) + return "", utils.WrapError(err) } return tmpfile.Name(), nil @@ -325,7 +325,7 @@ func (c *OSCommand) CreateFileWithContent(path string, content string) error { if err := ioutil.WriteFile(path, []byte(content), 0644); err != nil { c.Log.Error(err) - return WrapError(err) + return utils.WrapError(err) } return nil @@ -334,7 +334,7 @@ func (c *OSCommand) CreateFileWithContent(path string, content string) error { // Remove removes a file or directory at the specified path func (c *OSCommand) Remove(filename string) error { err := os.RemoveAll(filename) - return WrapError(err) + return utils.WrapError(err) } // FileExists checks whether a file exists at the specified path @@ -352,7 +352,7 @@ func (c *OSCommand) FileExists(path string) (bool, error) { // this is useful if you need to give your command some environment variables // before running it func (c *OSCommand) RunPreparedCommand(cmd *exec.Cmd) error { - c.beforeExecuteCmd(cmd) + c.BeforeExecuteCmd(cmd) out, err := cmd.CombinedOutput() outString := string(out) c.Log.Info(outString) @@ -376,7 +376,7 @@ func (c *OSCommand) GetLazygitPath() string { // RunCustomCommand returns the pointer to a custom command func (c *OSCommand) RunCustomCommand(command string) *exec.Cmd { - return c.PrepareSubProcess(c.Platform.shell, c.Platform.shellArg, command) + return c.PrepareSubProcess(c.Platform.Shell, c.Platform.ShellArg, command) } // PipeCommands runs a heap of commands and pipes their inputs/outputs together like A | B | C diff --git a/pkg/commands/oscommands/os_default_platform.go b/pkg/commands/oscommands/os_default_platform.go new file mode 100644 index 000000000..7ba166428 --- /dev/null +++ b/pkg/commands/oscommands/os_default_platform.go @@ -0,0 +1,20 @@ +// +build !windows + +package oscommands + +import ( + "runtime" +) + +func getPlatform() *Platform { + return &Platform{ + OS: runtime.GOOS, + CatCmd: "cat", + Shell: "bash", + ShellArg: "-c", + EscapedQuote: "'", + OpenCommand: "open {{filename}}", + OpenLinkCommand: "open {{link}}", + FallbackEscapedQuote: "\"", + } +} diff --git a/pkg/commands/os_test.go b/pkg/commands/oscommands/os_test.go similarity index 93% rename from pkg/commands/os_test.go rename to pkg/commands/oscommands/os_test.go index 2141b0e1e..3383db215 100644 --- a/pkg/commands/os_test.go +++ b/pkg/commands/oscommands/os_test.go @@ -1,4 +1,4 @@ -package commands +package oscommands import ( "io/ioutil" @@ -102,7 +102,7 @@ func TestOSCommandOpenFile(t *testing.T) { for _, s := range scenarios { OSCmd := NewDummyOSCommand() - OSCmd.command = s.command + OSCmd.Command = s.command OSCmd.Config.GetUserConfig().Set("os.openCommand", "open {{filename}}") s.test(OSCmd.OpenFile(s.filename)) @@ -231,9 +231,9 @@ func TestOSCommandEditFile(t *testing.T) { for _, s := range scenarios { OSCmd := NewDummyOSCommand() - OSCmd.command = s.command - OSCmd.getGlobalGitConfig = s.getGlobalGitConfig - OSCmd.getenv = s.getenv + OSCmd.Command = s.command + OSCmd.GetGlobalGitConfig = s.getGlobalGitConfig + OSCmd.Getenv = s.getenv s.test(OSCmd.EditFile(s.filename)) } @@ -245,7 +245,7 @@ func TestOSCommandQuote(t *testing.T) { actual := osCommand.Quote("hello `test`") - expected := osCommand.Platform.escapedQuote + "hello \\`test\\`" + osCommand.Platform.escapedQuote + expected := osCommand.Platform.EscapedQuote + "hello \\`test\\`" + osCommand.Platform.EscapedQuote assert.EqualValues(t, expected, actual) } @@ -254,11 +254,11 @@ func TestOSCommandQuote(t *testing.T) { func TestOSCommandQuoteSingleQuote(t *testing.T) { osCommand := NewDummyOSCommand() - osCommand.Platform.os = "linux" + osCommand.Platform.OS = "linux" actual := osCommand.Quote("hello 'test'") - expected := osCommand.Platform.fallbackEscapedQuote + "hello 'test'" + osCommand.Platform.fallbackEscapedQuote + expected := osCommand.Platform.FallbackEscapedQuote + "hello 'test'" + osCommand.Platform.FallbackEscapedQuote assert.EqualValues(t, expected, actual) } @@ -267,11 +267,11 @@ func TestOSCommandQuoteSingleQuote(t *testing.T) { func TestOSCommandQuoteDoubleQuote(t *testing.T) { osCommand := NewDummyOSCommand() - osCommand.Platform.os = "linux" + osCommand.Platform.OS = "linux" actual := osCommand.Quote(`hello "test"`) - expected := osCommand.Platform.escapedQuote + "hello \"test\"" + osCommand.Platform.escapedQuote + expected := osCommand.Platform.EscapedQuote + "hello \"test\"" + osCommand.Platform.EscapedQuote assert.EqualValues(t, expected, actual) } diff --git a/pkg/commands/os_windows.go b/pkg/commands/oscommands/os_windows.go similarity index 81% rename from pkg/commands/os_windows.go rename to pkg/commands/oscommands/os_windows.go index fcb498db3..e41dc9975 100644 --- a/pkg/commands/os_windows.go +++ b/pkg/commands/oscommands/os_windows.go @@ -1,4 +1,4 @@ -package commands +package oscommands func getPlatform() *Platform { return &Platform{ @@ -7,6 +7,6 @@ func getPlatform() *Platform { shell: "cmd", shellArg: "/c", escapedQuote: `\"`, - fallbackEscapedQuote: "\\'", + FallbackEscapedQuote: "\\'", } } diff --git a/pkg/commands/pull_request_test.go b/pkg/commands/pull_request_test.go index c75551592..574a65af8 100644 --- a/pkg/commands/pull_request_test.go +++ b/pkg/commands/pull_request_test.go @@ -5,6 +5,7 @@ import ( "strings" "testing" + "github.com/jesseduffield/lazygit/pkg/models" "github.com/stretchr/testify/assert" ) diff --git a/pkg/config/dummies.go b/pkg/config/dummies.go new file mode 100644 index 000000000..034d9b88b --- /dev/null +++ b/pkg/config/dummies.go @@ -0,0 +1,26 @@ +package config + +import ( + "github.com/spf13/viper" + yaml "gopkg.in/yaml.v2" +) + +// NewDummyAppConfig creates a new dummy AppConfig for testing +func NewDummyAppConfig() *AppConfig { + userConfig := viper.New() + userConfig.SetConfigType("yaml") + if err := LoadDefaults(userConfig, GetDefaultConfig()); err != nil { + panic(err) + } + appConfig := &AppConfig{ + Name: "lazygit", + Version: "unversioned", + Commit: "", + BuildDate: "", + Debug: false, + BuildSource: "", + UserConfig: userConfig, + } + _ = yaml.Unmarshal([]byte{}, appConfig.AppState) + return appConfig +} diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 6dc3bf12c..8c85a468f 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -22,6 +22,7 @@ import ( "github.com/golang-collections/collections/stack" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/commands/patch" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/i18n" @@ -90,7 +91,7 @@ type Gui struct { g *gocui.Gui Log *logrus.Entry GitCommand *commands.GitCommand - OSCommand *commands.OSCommand + OSCommand *oscommands.OSCommand SubProcess *exec.Cmd State *guiState Config config.AppConfigurer @@ -384,7 +385,7 @@ func (gui *Gui) resetState() { // for now the split view will always be on // NewGui builds a new gui handler -func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *commands.OSCommand, tr *i18n.Localizer, config config.AppConfigurer, updater *updates.Updater, filterPath string, showRecentRepos bool) (*Gui, error) { +func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *oscommands.OSCommand, tr *i18n.Localizer, config config.AppConfigurer, updater *updates.Updater, filterPath string, showRecentRepos bool) (*Gui, error) { gui := &Gui{ Log: log, GitCommand: gitCommand, diff --git a/pkg/gui/reset_menu_panel.go b/pkg/gui/reset_menu_panel.go index e75c20aad..26b3cb427 100644 --- a/pkg/gui/reset_menu_panel.go +++ b/pkg/gui/reset_menu_panel.go @@ -4,10 +4,10 @@ import ( "fmt" "github.com/fatih/color" - "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" ) -func (gui *Gui) resetToRef(ref string, strength string, options commands.RunCommandOptions) error { +func (gui *Gui) resetToRef(ref string, strength string, options oscommands.RunCommandOptions) error { if err := gui.GitCommand.ResetToCommit(ref, strength, options); err != nil { return gui.surfaceError(err) } @@ -41,7 +41,7 @@ func (gui *Gui) createResetMenu(ref string) error { ), }, onPress: func() error { - return gui.resetToRef(ref, strength, commands.RunCommandOptions{}) + return gui.resetToRef(ref, strength, oscommands.RunCommandOptions{}) }, } } diff --git a/pkg/gui/undoing.go b/pkg/gui/undoing.go index 2224c2b1f..d6f7c99e2 100644 --- a/pkg/gui/undoing.go +++ b/pkg/gui/undoing.go @@ -2,7 +2,7 @@ package gui import ( "github.com/jesseduffield/gocui" - "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/utils" ) @@ -156,7 +156,7 @@ type handleHardResetWithAutoStashOptions struct { // only to be used in the undo flow for now func (gui *Gui) handleHardResetWithAutoStash(commitSha string, options handleHardResetWithAutoStashOptions) error { reset := func() error { - if err := gui.resetToRef(commitSha, "hard", commands.RunCommandOptions{EnvVars: options.EnvVars}); err != nil { + if err := gui.resetToRef(commitSha, "hard", oscommands.RunCommandOptions{EnvVars: options.EnvVars}); err != nil { return gui.surfaceError(err) } return nil diff --git a/pkg/tasks/tasks.go b/pkg/tasks/tasks.go index 223d36c98..56fe81db0 100644 --- a/pkg/tasks/tasks.go +++ b/pkg/tasks/tasks.go @@ -9,7 +9,7 @@ import ( "sync" "time" - "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/sirupsen/logrus" ) @@ -50,7 +50,7 @@ func (m *ViewBufferManager) NewCmdTask(r io.Reader, cmd *exec.Cmd, linesToRead i return func(stop chan struct{}) error { go func() { <-stop - if err := commands.Kill(cmd); err != nil { + if err := oscommands.Kill(cmd); err != nil { if !strings.Contains(err.Error(), "process already finished") { m.Log.Errorf("error when running cmd task: %v", err) } diff --git a/pkg/test/test.go b/pkg/test/test.go index b3db699d0..38eabc6a4 100644 --- a/pkg/test/test.go +++ b/pkg/test/test.go @@ -1,11 +1,12 @@ package test import ( - "github.com/go-errors/errors" "os" "os/exec" "path/filepath" + "github.com/go-errors/errors" + "github.com/jesseduffield/lazygit/pkg/utils" ) diff --git a/pkg/updates/updates.go b/pkg/updates/updates.go index ecad64d37..ba09b0a4c 100644 --- a/pkg/updates/updates.go +++ b/pkg/updates/updates.go @@ -15,7 +15,7 @@ import ( "github.com/kardianos/osext" - "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/i18n" "github.com/sirupsen/logrus" @@ -25,7 +25,7 @@ import ( type Updater struct { Log *logrus.Entry Config config.AppConfigurer - OSCommand *commands.OSCommand + OSCommand *oscommands.OSCommand Tr *i18n.Localizer } @@ -40,7 +40,7 @@ const ( ) // NewUpdater creates a new updater -func NewUpdater(log *logrus.Entry, config config.AppConfigurer, osCommand *commands.OSCommand, tr *i18n.Localizer) (*Updater, error) { +func NewUpdater(log *logrus.Entry, config config.AppConfigurer, osCommand *oscommands.OSCommand, tr *i18n.Localizer) (*Updater, error) { contextLogger := log.WithField("context", "updates") return &Updater{ diff --git a/pkg/utils/dummies.go b/pkg/utils/dummies.go new file mode 100644 index 000000000..ab6d041dd --- /dev/null +++ b/pkg/utils/dummies.go @@ -0,0 +1,14 @@ +package utils + +import ( + "io/ioutil" + + "github.com/sirupsen/logrus" +) + +// NewDummyLog creates a new dummy Log for testing +func NewDummyLog() *logrus.Entry { + log := logrus.New() + log.Out = ioutil.Discard + return log.WithField("test", "test") +} diff --git a/pkg/commands/errors.go b/pkg/utils/errors.go similarity index 95% rename from pkg/commands/errors.go rename to pkg/utils/errors.go index 4723eb95d..cd3cb686c 100644 --- a/pkg/commands/errors.go +++ b/pkg/utils/errors.go @@ -1,4 +1,4 @@ -package commands +package utils import "github.com/go-errors/errors"