From 8925b161a75aed3162292c2ed0e2c0135fd91a54 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Sun, 3 Mar 2019 12:44:10 +1100 Subject: windows support for skipping the editor --- pkg/app/app.go | 26 +++++++++++++++----------- pkg/commands/git.go | 35 +++++++++++++++++++++++++++-------- pkg/commands/os.go | 34 +++++++++++++++++++++++++++++----- pkg/commands/os_default_platform.go | 1 - 4 files changed, 71 insertions(+), 25 deletions(-) diff --git a/pkg/app/app.go b/pkg/app/app.go index a8d0a1045..4c895f521 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -22,14 +22,14 @@ import ( type App struct { closers []io.Closer - Config config.AppConfigurer - Log *logrus.Entry - OSCommand *commands.OSCommand - GitCommand *commands.GitCommand - Gui *gui.Gui - Tr *i18n.Localizer - Updater *updates.Updater // may only need this on the Gui - DemonContext string + Config config.AppConfigurer + Log *logrus.Entry + OSCommand *commands.OSCommand + GitCommand *commands.GitCommand + Gui *gui.Gui + Tr *i18n.Localizer + Updater *updates.Updater // may only need this on the Gui + ClientContext string } func newProductionLogger(config config.AppConfigurer) *logrus.Logger { @@ -92,8 +92,8 @@ func NewApp(config config.AppConfigurer) (*App, error) { app.Tr = i18n.NewLocalizer(app.Log) // if we are being called in 'demon' mode, we can just return here - app.DemonContext = os.Getenv("LAZYGIT_CONTEXT") - if app.DemonContext != "" { + app.ClientContext = os.Getenv("LAZYGIT_CLIENT_COMMAND") + if app.ClientContext != "" { return app, nil } @@ -119,10 +119,14 @@ func NewApp(config config.AppConfigurer) (*App, error) { } func (app *App) Run() error { - if app.DemonContext == "INTERACTIVE_REBASE" { + if app.ClientContext == "INTERACTIVE_REBASE" { return app.Rebase() } + if app.ClientContext == "EXIT_IMMEDIATELY" { + os.Exit(0) + } + return app.Gui.RunWithSubprocesses() } diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 33ef6d5ba..9aa556ed4 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -584,11 +584,26 @@ func (c *GitCommand) FastForward(branchName string) error { return c.OSCommand.RunCommand(fmt.Sprintf("git fetch %s %s:%s", upstream, branchName, branchName)) } +func (c *GitCommand) RunSkipEditorCommand(command string) error { + cmd := c.OSCommand.ExecutableFromString(command) + cmd.Env = append( + os.Environ(), + "LAZYGIT_CLIENT_COMMAND=EXIT_IMMEDIATELY", + "EDITOR="+c.OSCommand.GetLazygitPath(), + ) + return c.OSCommand.RunExecutable(cmd) +} + // GenericMerge takes a commandType of "merge" or "rebase" and a command of "abort", "skip" or "continue" // By default we skip the editor in the case where a commit will be made func (c *GitCommand) GenericMerge(commandType string, command string) error { - gitCommand := fmt.Sprintf("git %s %s --%s", c.OSCommand.Platform.skipEditorArg, commandType, command) - return c.OSCommand.RunCommand(gitCommand) + return c.RunSkipEditorCommand( + fmt.Sprintf( + "git %s --%s", + commandType, + command, + ), + ) } func (c *GitCommand) RewordCommit(commits []*Commit, index int) (*exec.Cmd, error) { @@ -635,11 +650,11 @@ func (c *GitCommand) InteractiveRebase(commits []*Commit, index int, action stri return c.OSCommand.RunPreparedCommand(cmd) } +// PrepareInteractiveRebaseCommand returns the cmd for an interactive rebase +// we tell git to run lazygit to edit the todo list, and we pass the client +// lazygit a todo string to write to the todo file func (c *GitCommand) PrepareInteractiveRebaseCommand(baseSha string, todo string, overrideEditor bool) (*exec.Cmd, error) { - ex, err := os.Executable() // get the executable path for git to use - if err != nil { - ex = os.Args[0] // fallback to the first call argument if needed - } + ex := c.OSCommand.GetLazygitPath() debug := "FALSE" if c.OSCommand.Config.GetDebug() == true { @@ -658,7 +673,7 @@ func (c *GitCommand) PrepareInteractiveRebaseCommand(baseSha string, todo string cmd.Env = os.Environ() cmd.Env = append( cmd.Env, - "LAZYGIT_CONTEXT=INTERACTIVE_REBASE", + "LAZYGIT_CLIENT_COMMAND=INTERACTIVE_REBASE", "LAZYGIT_REBASE_TODO="+todo, "DEBUG="+debug, "LANG=en_US.UTF-8", // Force using EN as language @@ -703,7 +718,11 @@ func (c *GitCommand) AmendTo(sha string) error { if err := c.OSCommand.RunCommand(fmt.Sprintf("git commit --fixup=%s", sha)); err != nil { return err } - return c.OSCommand.RunCommand(fmt.Sprintf("git %s rebase --interactive --autostash --autosquash %s^", c.OSCommand.Platform.skipEditorArg, sha)) + return c.RunSkipEditorCommand( + fmt.Sprintf( + "git rebase --interactive --autostash --autosquash %s^", sha, + ), + ) } // EditRebaseTodo sets the action at a given index in the git-rebase-todo file diff --git a/pkg/commands/os.go b/pkg/commands/os.go index c55a7653e..a7a1fdaa4 100644 --- a/pkg/commands/os.go +++ b/pkg/commands/os.go @@ -4,6 +4,7 @@ import ( "io/ioutil" "os" "os/exec" + "path/filepath" "regexp" "strings" @@ -25,7 +26,6 @@ type Platform struct { openCommand string openLinkCommand string fallbackEscapedQuote string - skipEditorArg string } // OSCommand holds all the os commands @@ -59,11 +59,26 @@ func (c *OSCommand) SetCommand(cmd func(string, ...string) *exec.Cmd) { // RunCommandWithOutput wrapper around commands returning their output and error func (c *OSCommand) RunCommandWithOutput(command string) (string, error) { c.Log.WithField("command", command).Info("RunCommand") - splitCmd := str.ToArgv(command) + cmd := c.ExecutableFromString(command) + return sanitisedCommandOutput(cmd.CombinedOutput()) +} + +// RunExecutableWithOutput runs an executable file and returns its output +func (c *OSCommand) RunExecutableWithOutput(cmd *exec.Cmd) (string, error) { + return sanitisedCommandOutput(cmd.CombinedOutput()) +} + +// RunExecutable runs an executable file and returns an error if there was one +func (c *OSCommand) RunExecutable(cmd *exec.Cmd) error { + _, err := c.RunExecutableWithOutput(cmd) + return err +} + +// 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) c.Log.Info(splitCmd) - return sanitisedCommandOutput( - c.command(splitCmd[0], splitCmd[1:]...).CombinedOutput(), - ) + return c.command(splitCmd[0], splitCmd[1:]...) } // RunCommandWithOutputLive runs RunCommandWithOutputLiveWrapper @@ -272,3 +287,12 @@ func (c *OSCommand) RunPreparedCommand(cmd *exec.Cmd) error { } return nil } + +// GetLazygitPath returns the path of the currently executed file +func (c *OSCommand) GetLazygitPath() string { + ex, err := os.Executable() // get the executable path for git to use + if err != nil { + ex = os.Args[0] // fallback to the first call argument if needed + } + return filepath.ToSlash(ex) +} diff --git a/pkg/commands/os_default_platform.go b/pkg/commands/os_default_platform.go index bf13b8e4e..73e453b6b 100644 --- a/pkg/commands/os_default_platform.go +++ b/pkg/commands/os_default_platform.go @@ -15,6 +15,5 @@ func getPlatform() *Platform { openCommand: "open {{filename}}", openLinkCommand: "open {{link}}", fallbackEscapedQuote: "\"", - skipEditorArg: "-c core.editor=true", } } -- cgit v1.2.3