port smoke to go
This commit is contained in:
parent
b0a9d64f4a
commit
9ed44bfd75
20 changed files with 2118 additions and 1573 deletions
|
|
@ -61,14 +61,14 @@ func printVMSpecLine(out io.Writer, params api.VMCreateParams) {
|
|||
// gets the spec line up front and the progress renderer thereafter.
|
||||
// On context cancel we cooperate with the daemon to cancel the
|
||||
// in-flight op so it doesn't leak partially-created VM state.
|
||||
func (d *deps) runVMCreate(ctx context.Context, socketPath string, stderr io.Writer, params api.VMCreateParams) (model.VMRecord, error) {
|
||||
func (d *deps) runVMCreate(ctx context.Context, socketPath string, stderr io.Writer, params api.VMCreateParams, verbose bool) (model.VMRecord, error) {
|
||||
start := time.Now()
|
||||
printVMSpecLine(stderr, params)
|
||||
begin, err := d.vmCreateBegin(ctx, socketPath, params)
|
||||
if err != nil {
|
||||
return model.VMRecord{}, err
|
||||
}
|
||||
renderer := newVMCreateProgressRenderer(stderr)
|
||||
renderer := newVMCreateProgressRenderer(stderr, verbose)
|
||||
renderer.render(begin.Operation)
|
||||
|
||||
op := begin.Operation
|
||||
|
|
@ -76,6 +76,7 @@ func (d *deps) runVMCreate(ctx context.Context, socketPath string, stderr io.Wri
|
|||
if op.Done {
|
||||
renderer.render(op)
|
||||
if op.Success && op.VM != nil {
|
||||
renderer.clear()
|
||||
elapsed := formatVMCreateElapsed(time.Since(start))
|
||||
_, _ = fmt.Fprintf(stderr, "[vm create] ready in %s\n", style.Dim(stderr, elapsed))
|
||||
return *op.VM, nil
|
||||
|
|
@ -113,13 +114,22 @@ func (d *deps) runVMCreate(ctx context.Context, socketPath string, stderr io.Wri
|
|||
type vmCreateProgressRenderer struct {
|
||||
out io.Writer
|
||||
enabled bool
|
||||
inline bool
|
||||
active bool
|
||||
lastLine string
|
||||
}
|
||||
|
||||
func newVMCreateProgressRenderer(out io.Writer) *vmCreateProgressRenderer {
|
||||
// newVMCreateProgressRenderer wires up progress for `vm create`. On
|
||||
// non-TTY writers it stays disabled (CI/test logs already capture the
|
||||
// spec + ready lines); on TTY it rewrites a single line via \r unless
|
||||
// verbose is set or BANGER_NO_PROGRESS is exported, in which case it
|
||||
// falls back to one line per stage.
|
||||
func newVMCreateProgressRenderer(out io.Writer, verbose bool) *vmCreateProgressRenderer {
|
||||
tty := writerSupportsProgress(out)
|
||||
return &vmCreateProgressRenderer{
|
||||
out: out,
|
||||
enabled: writerSupportsProgress(out),
|
||||
enabled: tty,
|
||||
inline: tty && !verbose && !progressDisabledByEnv(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,9 +142,32 @@ func (r *vmCreateProgressRenderer) render(op api.VMCreateOperation) {
|
|||
return
|
||||
}
|
||||
r.lastLine = line
|
||||
if r.inline {
|
||||
_, _ = fmt.Fprint(r.out, "\r\x1b[K", line)
|
||||
r.active = true
|
||||
return
|
||||
}
|
||||
_, _ = fmt.Fprintln(r.out, line)
|
||||
}
|
||||
|
||||
// clear resets the live inline line so the caller can write a clean
|
||||
// terminating message. No-op outside inline mode.
|
||||
func (r *vmCreateProgressRenderer) clear() {
|
||||
if r == nil || !r.enabled || !r.inline || !r.active {
|
||||
return
|
||||
}
|
||||
_, _ = fmt.Fprint(r.out, "\r\x1b[K")
|
||||
r.active = false
|
||||
r.lastLine = ""
|
||||
}
|
||||
|
||||
// progressDisabledByEnv is the BANGER_NO_PROGRESS escape hatch — a
|
||||
// non-empty value forces line-per-stage output even on a TTY, so users
|
||||
// can pipe `script(1)` / tmux capture without \r artifacts.
|
||||
func progressDisabledByEnv() bool {
|
||||
return strings.TrimSpace(os.Getenv("BANGER_NO_PROGRESS")) != ""
|
||||
}
|
||||
|
||||
// writerSupportsProgress returns true only when out is a terminal.
|
||||
// Keeps stage lines + heartbeat dots out of piped / logged output
|
||||
// where they'd just be noise.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue