Switch to explicitly declaring TrackProgress on UI, using an underlying progress bar specifically stored on the struct. Export UiProgressTracker. These changes allow us to optionaly switch to the NoopProgressTracker when no TTY is set.

This commit is contained in:
Megan Marsh 2020-09-21 16:05:14 -07:00
parent 062b9a0d23
commit ae8d359bf1
7 changed files with 52 additions and 19 deletions

1
go.mod
View File

@ -96,6 +96,7 @@ require (
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/go-testing-interface v1.0.3 // indirect
github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed
github.com/mitchellh/gox v1.0.1 // indirect
github.com/mitchellh/iochan v1.0.0
github.com/mitchellh/mapstructure v1.2.3
github.com/mitchellh/panicwrap v0.0.0-20170106182340-fce601fe5557

3
go.sum
View File

@ -351,6 +351,7 @@ github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0=
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
@ -487,6 +488,8 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZX
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI=
github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4=
github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=

View File

@ -196,6 +196,7 @@ func wrappedMain() int {
Reader: os.Stdin,
Writer: os.Stdout,
ErrorWriter: os.Stdout,
PB: &packer.UiProgressBar{},
}
ui = basicUi
if !inPlugin {
@ -207,8 +208,10 @@ func wrappedMain() int {
}
if backgrounded {
fmt.Fprint(os.Stderr, "Running in background, not using a TTY\n")
basicUi.PB = &packer.NoopProgressTracker{}
} else if TTY, err := openTTY(); err != nil {
fmt.Fprintf(os.Stderr, "No tty available: %s\n", err)
basicUi.PB = &packer.NoopProgressTracker{}
} else {
basicUi.TTY = TTY
defer TTY.Close()

View File

@ -15,26 +15,28 @@ func ProgressBarConfig(bar *pb.ProgressBar, prefix string) {
bar.Prefix(prefix)
}
var defaultUiProgressBar = &uiProgressBar{}
var defaultUiProgressBar = &UiProgressBar{}
// uiProgressBar is a self managed progress bar singleton.
// decorate your struct with a *uiProgressBar to
// UiProgressBar is a self managed progress bar singleton.
// decorate your struct with a *UiProgressBar to
// give it TrackProgress capabilities.
// In TrackProgress if uiProgressBar is nil
// In TrackProgress if UiProgressBar is nil
// defaultUiProgressBar will be used as
// the progress bar.
type uiProgressBar struct {
type UiProgressBar struct {
Noop bool
lock sync.Mutex
pool *pb.Pool
pbs int
pbs int
}
func (p *uiProgressBar) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) io.ReadCloser {
func (p *UiProgressBar) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) io.ReadCloser {
if p == nil {
return defaultUiProgressBar.TrackProgress(src, currentSize, totalSize, stream)
}
if p.Noop {
return stream
}
p.lock.Lock()
defer p.lock.Unlock()

View File

@ -1,3 +1,3 @@
package packer
type uiProgressBar = NoopProgressTracker
type UiProgressBar = NoopProgressTracker

View File

@ -11,7 +11,7 @@ import (
// The following tests rarelly just happen. So we run them 100 times.
func TestProgressTracking_open_close(t *testing.T) {
var bar *uiProgressBar
var bar *UiProgressBar
tracker := bar.TrackProgress("1,", 1, 42, ioutil.NopCloser(nil))
tracker.Close()
@ -21,7 +21,7 @@ func TestProgressTracking_open_close(t *testing.T) {
}
func TestProgressTracking_multi_open_close(t *testing.T) {
var bar *uiProgressBar
var bar *UiProgressBar
g := errgroup.Group{}
for i := 0; i < 100; i++ {
@ -36,7 +36,7 @@ func TestProgressTracking_multi_open_close(t *testing.T) {
}
func TestProgressTracking_races(t *testing.T) {
var bar *uiProgressBar
var bar *UiProgressBar
g := errgroup.Group{}
for i := 0; i < 100; i++ {

View File

@ -40,11 +40,12 @@ type Ui interface {
Message(string)
Error(string)
Machine(string, ...string)
// TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser)
getter.ProgressTracker
}
type NoopUi struct {
NoopProgressTracker
PB NoopProgressTracker
}
var _ Ui = new(NoopUi)
@ -54,13 +55,16 @@ func (*NoopUi) Say(string) { return }
func (*NoopUi) Message(string) { return }
func (*NoopUi) Error(string) { return }
func (*NoopUi) Machine(string, ...string) { return }
func (u *NoopUi) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) io.ReadCloser {
return u.PB.TrackProgress(src, currentSize, totalSize, stream)
}
// ColoredUi is a UI that is colored using terminal colors.
type ColoredUi struct {
Color UiColor
ErrorColor UiColor
Ui Ui
*uiProgressBar
PB getter.ProgressTracker
}
var _ Ui = new(ColoredUi)
@ -189,7 +193,7 @@ type BasicUi struct {
l sync.Mutex
interrupted bool
TTY TTY
*uiProgressBar
PB getter.ProgressTracker
}
var _ Ui = new(BasicUi)
@ -304,11 +308,15 @@ func (rw *BasicUi) Machine(t string, args ...string) {
log.Printf("machine readable: %s %#v", t, args)
}
func (rw *BasicUi) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser) {
return rw.PB.TrackProgress(src, currentSize, totalSize, stream)
}
// MachineReadableUi is a UI that only outputs machine-readable output
// to the given Writer.
type MachineReadableUi struct {
Writer io.Writer
NoopProgressTracker
PB NoopProgressTracker
}
var _ Ui = new(MachineReadableUi)
@ -366,11 +374,15 @@ func (u *MachineReadableUi) Machine(category string, args ...string) {
log.Printf("%d,%s,%s,%s\n", now.Unix(), target, category, argsString)
}
func (u *MachineReadableUi) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser) {
return u.PB.TrackProgress(src, currentSize, totalSize, stream)
}
// TimestampedUi is a UI that wraps another UI implementation and
// prefixes each message with an RFC3339 timestamp
type TimestampedUi struct {
Ui Ui
*uiProgressBar
PB getter.ProgressTracker
}
var _ Ui = new(TimestampedUi)
@ -395,6 +407,10 @@ func (u *TimestampedUi) Machine(message string, args ...string) {
u.Ui.Machine(message, args...)
}
func (u *TimestampedUi) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser) {
return u.Ui.TrackProgress(src, currentSize, totalSize, stream)
}
func (u *TimestampedUi) timestampLine(string string) string {
return fmt.Sprintf("%v: %v", time.Now().Format(time.RFC3339), string)
}
@ -404,7 +420,7 @@ func (u *TimestampedUi) timestampLine(string string) string {
type SafeUi struct {
Sem chan int
Ui Ui
*uiProgressBar
PB getter.ProgressTracker
}
var _ Ui = new(SafeUi)
@ -440,3 +456,11 @@ func (u *SafeUi) Machine(t string, args ...string) {
u.Ui.Machine(t, args...)
<-u.Sem
}
func (u *SafeUi) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser) {
u.Sem <- 1
ret := u.Ui.TrackProgress(src, currentSize, totalSize, stream)
<-u.Sem
return ret
}