diff --git a/pkg/commands/git_cmd_obj_runner.go b/pkg/commands/git_cmd_obj_runner.go index c57c2d2be..96cef3c61 100644 --- a/pkg/commands/git_cmd_obj_runner.go +++ b/pkg/commands/git_cmd_obj_runner.go @@ -21,6 +21,10 @@ func (self *gitCmdObjRunner) RunWithOutput(cmdObj oscommands.ICmdObj) (string, e return self.innerRunner.RunWithOutput(cmdObj) } +func (self *gitCmdObjRunner) RunWithOutputs(cmdObj oscommands.ICmdObj) (string, string, error) { + return self.innerRunner.RunWithOutputs(cmdObj) +} + func (self *gitCmdObjRunner) RunAndProcessLines(cmdObj oscommands.ICmdObj, onLine func(line string) (bool, error)) error { return self.innerRunner.RunAndProcessLines(cmdObj, onLine) } diff --git a/pkg/commands/loaders/files.go b/pkg/commands/loaders/files.go index db37da935..6d14bb590 100644 --- a/pkg/commands/loaders/files.go +++ b/pkg/commands/loaders/files.go @@ -87,7 +87,7 @@ func (c *FileLoader) GitStatus(opts GitStatusOptions) ([]FileStatus, error) { noRenamesFlag = " --no-renames" } - statusLines, err := c.cmd.New(fmt.Sprintf("git status %s --porcelain -z%s", opts.UntrackedFilesArg, noRenamesFlag)).DontLog().RunWithOutput() + statusLines, _, err := c.cmd.New(fmt.Sprintf("git status %s --porcelain -z%s", opts.UntrackedFilesArg, noRenamesFlag)).DontLog().RunWithOutputs() if err != nil { return []FileStatus{}, err } diff --git a/pkg/commands/oscommands/cmd_obj.go b/pkg/commands/oscommands/cmd_obj.go index 1a801c6fe..47a227f17 100644 --- a/pkg/commands/oscommands/cmd_obj.go +++ b/pkg/commands/oscommands/cmd_obj.go @@ -22,6 +22,8 @@ type ICmdObj interface { Run() error // runs the command and returns the output as a string, and an error if any RunWithOutput() (string, error) + // runs the command and returns stdout and stderr as a string, and an error if any + RunWithOutputs() (string, string, error) // runs the command and runs a callback function on each line of the output. If the callback returns true for the boolean value, we kill the process and return. RunAndProcessLines(onLine func(line string) (bool, error)) error @@ -162,6 +164,10 @@ func (self *CmdObj) RunWithOutput() (string, error) { return self.runner.RunWithOutput(self) } +func (self *CmdObj) RunWithOutputs() (string, string, error) { + return self.runner.RunWithOutputs(self) +} + func (self *CmdObj) RunAndProcessLines(onLine func(line string) (bool, error)) error { return self.runner.RunAndProcessLines(self, onLine) } diff --git a/pkg/commands/oscommands/cmd_obj_runner.go b/pkg/commands/oscommands/cmd_obj_runner.go index ba1489fe6..01cc0f460 100644 --- a/pkg/commands/oscommands/cmd_obj_runner.go +++ b/pkg/commands/oscommands/cmd_obj_runner.go @@ -15,6 +15,7 @@ import ( type ICmdObjRunner interface { Run(cmdObj ICmdObj) error RunWithOutput(cmdObj ICmdObj) (string, error) + RunWithOutputs(cmdObj ICmdObj) (string, string, error) RunAndProcessLines(cmdObj ICmdObj, onLine func(line string) (bool, error)) error } @@ -76,6 +77,31 @@ func (self *cmdObjRunner) RunWithOutput(cmdObj ICmdObj) (string, error) { return self.RunWithOutputAux(cmdObj) } +func (self *cmdObjRunner) RunWithOutputs(cmdObj ICmdObj) (string, string, error) { + if cmdObj.Mutex() != nil { + cmdObj.Mutex().Lock() + defer cmdObj.Mutex().Unlock() + } + + if cmdObj.GetCredentialStrategy() != NONE { + err := self.runWithCredentialHandling(cmdObj) + // for now we're not capturing output, just because it would take a little more + // effort and there's currently no use case for it. Some commands call RunWithOutputs + // but ignore the output, hence why we've got this check here. + return "", "", err + } + + if cmdObj.ShouldStreamOutput() { + err := self.runAndStream(cmdObj) + // for now we're not capturing output, just because it would take a little more + // effort and there's currently no use case for it. Some commands call RunWithOutputs + // but ignore the output, hence why we've got this check here. + return "", "", err + } + + return self.RunWithOutputsAux(cmdObj) +} + func (self *cmdObjRunner) RunWithOutputAux(cmdObj ICmdObj) (string, error) { self.log.WithField("command", cmdObj.ToString()).Debug("RunCommand") @@ -90,6 +116,28 @@ func (self *cmdObjRunner) RunWithOutputAux(cmdObj ICmdObj) (string, error) { return output, err } +func (self *cmdObjRunner) RunWithOutputsAux(cmdObj ICmdObj) (string, string, error) { + self.log.WithField("command", cmdObj.ToString()).Debug("RunCommand") + + if cmdObj.ShouldLog() { + self.logCmdObj(cmdObj) + } + + var outBuffer, errBuffer bytes.Buffer + cmd := cmdObj.GetCmd() + cmd.Stdout = &outBuffer + cmd.Stderr = &errBuffer + err := cmd.Run() + + stdout := outBuffer.String() + stderr, err := sanitisedCommandOutput(errBuffer.Bytes(), err) + if err != nil { + self.log.WithField("command", cmdObj.ToString()).Error(stderr) + } + + return stdout, stderr, err +} + func (self *cmdObjRunner) RunAndProcessLines(cmdObj ICmdObj, onLine func(line string) (bool, error)) error { if cmdObj.Mutex() != nil { cmdObj.Mutex().Lock() diff --git a/pkg/commands/oscommands/fake_cmd_obj_runner.go b/pkg/commands/oscommands/fake_cmd_obj_runner.go index d06861251..f553d8c63 100644 --- a/pkg/commands/oscommands/fake_cmd_obj_runner.go +++ b/pkg/commands/oscommands/fake_cmd_obj_runner.go @@ -44,6 +44,11 @@ func (self *FakeCmdObjRunner) RunWithOutput(cmdObj ICmdObj) (string, error) { return output, err } +func (self *FakeCmdObjRunner) RunWithOutputs(cmdObj ICmdObj) (string, string, error) { + output, err := self.RunWithOutput(cmdObj) + return output, "", err +} + func (self *FakeCmdObjRunner) RunAndProcessLines(cmdObj ICmdObj, onLine func(line string) (bool, error)) error { output, err := self.RunWithOutput(cmdObj) if err != nil {