Skip to content

Commit 0db3480

Browse files
authored
[install UX] incrementally show the output in-line (#506)
## Summary Thanks to @mikeland86's suggestion we can have snappy incremental in-line updates of what the `nix-env --install` is doing. ## How was it tested? added `buf` to a devbox.json and did `devbox shell`
1 parent 2f526a8 commit 0db3480

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

internal/impl/devbox.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package impl
66

77
import (
8+
"bufio"
89
"fmt"
910
"io"
1011
"os"
@@ -726,8 +727,47 @@ func (d *Devbox) installNixProfile() (err error) {
726727
}
727728

728729
cmd.Env = nix.DefaultEnv()
729-
_, err = cmd.Output()
730+
731+
// Get a pipe to read from standard out
732+
pipe, err := cmd.StdoutPipe()
730733
if err != nil {
734+
return errors.New("unable to open stdout pipe")
735+
}
736+
737+
// Use the same writer for standard error
738+
cmd.Stderr = cmd.Stdout
739+
740+
// Make a new channel which will be used to ensure we get all output
741+
done := make(chan struct{})
742+
743+
// Create a scanner which scans pipe in a line-by-line fashion
744+
scanner := bufio.NewScanner(pipe)
745+
746+
// Use the scanner to scan the output line by line and log it
747+
// It's running in a goroutine so that it doesn't block
748+
go func() {
749+
750+
// Read line by line and process it
751+
for scanner.Scan() {
752+
line := scanner.Text()
753+
step.Display(fmt.Sprintf("%s %s", msg, line))
754+
}
755+
756+
// We're all done, unblock the channel
757+
done <- struct{}{}
758+
}()
759+
760+
// Start the command and check for errors
761+
if err := cmd.Start(); err != nil {
762+
step.Fail(msg)
763+
return errors.Errorf("error starting command %s: %v", cmd, err)
764+
}
765+
766+
// Wait for all output to be processed
767+
<-done
768+
769+
// Wait for the command to finish
770+
if err = cmd.Wait(); err != nil {
731771
step.Fail(msg)
732772
return errors.Errorf("error running command %s: %v", cmd, err)
733773
}

internal/ux/stepper/stepper.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,9 @@ func (s *Stepper) Success(format string, a ...any) {
4545
s.spinner.FinalMSG = fmt.Sprintf("%s %s\n", color.GreenString("✓"), msg)
4646
s.spinner.Stop()
4747
}
48+
49+
func (s *Stepper) Display(format string, a ...any) {
50+
msg := fmt.Sprintf(format, a...)
51+
// we need to add a space prefix to give a small gap between the spinner animation and the msg
52+
s.spinner.Suffix = fmt.Sprintf(" %s", msg)
53+
}

0 commit comments

Comments
 (0)