diff options
Diffstat (limited to 'pkg/commands/os.go')
-rw-r--r-- | pkg/commands/os.go | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/pkg/commands/os.go b/pkg/commands/os.go index 02d79a339..32d22ea5a 100644 --- a/pkg/commands/os.go +++ b/pkg/commands/os.go @@ -7,6 +7,7 @@ import ( "path/filepath" "regexp" "strings" + "sync" "github.com/go-errors/errors" @@ -301,3 +302,63 @@ func (c *OSCommand) GetLazygitPath() string { func (c *OSCommand) RunCustomCommand(command string) *exec.Cmd { 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 +func (c *OSCommand) PipeCommands(commandStrings ...string) error { + + cmds := make([]*exec.Cmd, len(commandStrings)) + + for i, str := range commandStrings { + cmds[i] = c.ExecutableFromString(str) + } + + for i := 0; i < len(cmds)-1; i++ { + stdout, err := cmds[i].StdoutPipe() + if err != nil { + return err + } + + cmds[i+1].Stdin = stdout + } + + // keeping this here in case I adapt this code for some other purpose in the future + // cmds[len(cmds)-1].Stdout = os.Stdout + + finalErrors := []string{} + + wg := sync.WaitGroup{} + wg.Add(len(cmds)) + + for _, cmd := range cmds { + currentCmd := cmd + go func() { + stderr, err := currentCmd.StderrPipe() + if err != nil { + c.Log.Error(err) + } + + if err := currentCmd.Start(); err != nil { + c.Log.Error(err) + } + + if b, err := ioutil.ReadAll(stderr); err == nil { + if len(b) > 0 { + finalErrors = append(finalErrors, string(b)) + } + } + + if err := currentCmd.Wait(); err != nil { + c.Log.Error(err) + } + + wg.Done() + }() + } + + wg.Wait() + + if len(finalErrors) > 0 { + return errors.New(strings.Join(finalErrors, "\n")) + } + return nil +} |