diff --git a/ui/build/exec.go b/ui/build/exec.go index 5c312bcd9..e435c53be 100644 --- a/ui/build/exec.go +++ b/ui/build/exec.go @@ -15,7 +15,10 @@ package build import ( + "bufio" + "io" "os/exec" + "strings" ) // Cmd is a wrapper of os/exec.Cmd that integrates with the build context for @@ -139,3 +142,34 @@ func (c *Cmd) RunAndPrintOrFatal() { st.Finish() c.reportError(err) } + +// RunAndStreamOrFatal will run the command, while running print +// any output, then handle any errors with a call to ctx.Fatal +func (c *Cmd) RunAndStreamOrFatal() { + out, err := c.StdoutPipe() + if err != nil { + c.ctx.Fatal(err) + } + c.Stderr = c.Stdout + + st := c.ctx.Status.StartTool() + + c.StartOrFatal() + + buf := bufio.NewReaderSize(out, 2*1024*1024) + for { + // Attempt to read whole lines, but write partial lines that are too long to fit in the buffer or hit EOF + line, err := buf.ReadString('\n') + if line != "" { + st.Print(strings.TrimSuffix(line, "\n")) + } else if err == io.EOF { + break + } else if err != nil { + c.ctx.Fatal(err) + } + } + + err = c.Wait() + st.Finish() + c.reportError(err) +} diff --git a/ui/build/ninja.go b/ui/build/ninja.go index 7994f3a2d..b41ac208a 100644 --- a/ui/build/ninja.go +++ b/ui/build/ninja.go @@ -103,7 +103,7 @@ func runNinja(ctx Context, config Config) { }() ctx.Status.Status("Starting ninja...") - cmd.RunAndPrintOrFatal() + cmd.RunAndStreamOrFatal() } type statusChecker struct { diff --git a/ui/build/soong.go b/ui/build/soong.go index 2ce1ac935..338841702 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -120,7 +120,7 @@ func runSoong(ctx Context, config Config) { "--frontend_file", fifo, "-f", filepath.Join(config.SoongOutDir(), file)) cmd.Sandbox = soongSandbox - cmd.RunAndPrintOrFatal() + cmd.RunAndStreamOrFatal() } ninja("minibootstrap", ".minibootstrap/build.ninja")