diff --git a/pkg/commands/exec_live_default.go b/pkg/commands/exec_live_default.go index acc0bcf18..5ee5bdf75 100644 --- a/pkg/commands/exec_live_default.go +++ b/pkg/commands/exec_live_default.go @@ -47,9 +47,9 @@ func RunCommandWithOutputLiveWrapper(c *OSCommand, command string, output func(s cmdOutput = append(cmdOutput, toOutput) toWrite := output(toOutput) if len(toWrite) > 0 { - // don't do -1 because the next value is the username / password + // don't do len(cmdOutput)-1 because the next value is the username / password cmdOutputOffset = len(cmdOutput) - _, _ = tty.Write([]byte(toWrite + "\n")) + _, _ = tty.WriteString(toWrite + "\n") } } waitForBufio.Done() @@ -59,8 +59,8 @@ func RunCommandWithOutputLiveWrapper(c *OSCommand, command string, output func(s tty.Close() if err != nil { waitForBufio.Wait() - if len(cmdOutput) == cmdOutputOffset { - cmdOutputOffset-- + if cmdOutputOffset > len(cmdOutput)-1 { + cmdOutputOffset = len(cmdOutput) - 1 } return errors.New(err.Error() + ", " + strings.Join(cmdOutput[cmdOutputOffset:], " ")) } diff --git a/pkg/commands/os.go b/pkg/commands/os.go index 827e6c420..ffc0516ad 100644 --- a/pkg/commands/os.go +++ b/pkg/commands/os.go @@ -217,7 +217,7 @@ func (c *OSCommand) CreateTempFile(filename, content string) (string, error) { return "", err } - if _, err := tmpfile.Write([]byte(content)); err != nil { + if _, err := tmpfile.WriteString(content); err != nil { c.Log.Error(err) return "", err } diff --git a/pkg/gui/commit_message_panel.go b/pkg/gui/commit_message_panel.go index 8f14cf6e1..71f18e1f0 100644 --- a/pkg/gui/commit_message_panel.go +++ b/pkg/gui/commit_message_panel.go @@ -65,11 +65,7 @@ func (gui *Gui) waitForPassUname(g *gocui.Gui, currentView *gocui.View, passOrUn credentialsView.Mask = '*' } g.Update(func(g *gocui.Gui) error { - _, err := g.SetViewOnTop("credentials") - if err != nil { - return err - } - err = gui.switchFocus(g, currentView, credentialsView) + err := gui.switchFocus(g, currentView, credentialsView) if err != nil { return err } @@ -124,7 +120,7 @@ func (gui *Gui) handlePushClose(g *gocui.Gui, v *gocui.View) error { return gui.switchFocus(g, nil, gui.getFilesView(g)) } -func (gui *Gui) handlePushFocused(g *gocui.Gui, v *gocui.View) error { +func (gui *Gui) handleCredentialsViewFocused(g *gocui.Gui, v *gocui.View) error { if _, err := g.SetViewOnTop("credentials"); err != nil { return err } diff --git a/pkg/gui/confirmation_panel.go b/pkg/gui/confirmation_panel.go index 99455a30c..cdb01466a 100644 --- a/pkg/gui/confirmation_panel.go +++ b/pkg/gui/confirmation_panel.go @@ -89,6 +89,7 @@ func (gui *Gui) onNewPopupPanel() { _, _ = gui.g.SetViewOnBottom("credentials") } +// it is very important that within this function we never include the original prompt in any error messages, because it may contain e.g. a user password func (gui *Gui) createConfirmationPanel(g *gocui.Gui, currentView *gocui.View, title, prompt string, handleConfirm, handleClose func(*gocui.Gui, *gocui.View) error) error { gui.onNewPopupPanel() g.Update(func(g *gocui.Gui) error { @@ -138,18 +139,27 @@ func (gui *Gui) createMessagePanel(g *gocui.Gui, currentView *gocui.View, title, return gui.createConfirmationPanel(g, currentView, title, prompt, nil, nil) } -func (gui *Gui) createErrorPanel(g *gocui.Gui, message string) error { - go func() { - // when reporting is switched on this log call sometimes introduces - // a delay on the error panel popping up. Here I'm adding a second wait - // so that the error is logged while the user is reading the error message - time.Sleep(time.Second) - gui.Log.Error(message) - }() +// createSpecificErrorPanel allows you to create an error popup, specifying the +// view to be focused when the user closes the popup, and a boolean specifying +// whether we will log the error. If the message may include a user password, +// this function is to be used over the more generic createErrorPanel, with +// willLog set to false +func (gui *Gui) createSpecificErrorPanel(message string, nextView *gocui.View, willLog bool) error { + if willLog { + go func() { + // when reporting is switched on this log call sometimes introduces + // a delay on the error panel popping up. Here I'm adding a second wait + // so that the error is logged while the user is reading the error message + time.Sleep(time.Second) + gui.Log.Error(message) + }() + } - // gui.Log.WithField("staging", "staging").Info("creating confirmation panel") - currentView := g.CurrentView() colorFunction := color.New(color.FgRed).SprintFunc() coloredMessage := colorFunction(strings.TrimSpace(message)) - return gui.createConfirmationPanel(g, currentView, gui.Tr.SLocalize("Error"), coloredMessage, nil, nil) + return gui.createConfirmationPanel(gui.g, nextView, gui.Tr.SLocalize("Error"), coloredMessage, nil, nil) +} + +func (gui *Gui) createErrorPanel(g *gocui.Gui, message string) error { + return gui.createSpecificErrorPanel(message, g.CurrentView(), true) } diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index 883773926..4befe1e0d 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -102,7 +102,7 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error { case "commitMessage": return gui.handleCommitFocused(g, v) case "credentials": - return gui.handlePushFocused(g, v) + return gui.handleCredentialsViewFocused(g, v) case "main": // TODO: pull this out into a 'view focused' function gui.refreshMergePanel(g) @@ -316,14 +316,15 @@ func (gui *Gui) resizeCurrentPopupPanel(g *gocui.Gui) error { // HandleCredentialsPopup handles the views after executing a command that might ask for credentials func (gui *Gui) HandleCredentialsPopup(g *gocui.Gui, popupOpened bool, cmdErr error) { if popupOpened { - _ = g.DeleteView("credentials") + _, _ = gui.g.SetViewOnBottom("credentials") } if cmdErr != nil { errMessage := cmdErr.Error() if strings.Contains(errMessage, "exit status 128") { errMessage = gui.Tr.SLocalize("PassUnameWrong") } - _ = gui.createErrorPanel(g, errMessage) + // we are not logging this error because it may contain a password + _ = gui.createSpecificErrorPanel(errMessage, gui.getFilesView(gui.g), false) } else { _ = gui.closeConfirmationPrompt(g) _ = gui.refreshSidePanels(g)