fix rendering and variable width issues on progress bar
This commit is contained in:
parent
f321b13a03
commit
aabd71aede
1 changed files with 34 additions and 15 deletions
|
@ -42,6 +42,19 @@ func NewBar(message string, maxValue, initialValue int64) *Bar {
|
|||
}
|
||||
}
|
||||
|
||||
// formatDuration limits the rendering of a time.Duration to 2 units
|
||||
func formatDuration(d time.Duration) string {
|
||||
if d >= 100*time.Hour {
|
||||
return "99h+"
|
||||
}
|
||||
|
||||
if d >= time.Hour {
|
||||
return fmt.Sprintf("%dh%dm", int(d.Hours()), int(d.Minutes())%60)
|
||||
}
|
||||
|
||||
return d.Round(time.Second).String()
|
||||
}
|
||||
|
||||
func (b *Bar) String() string {
|
||||
termWidth, _, err := term.GetSize(int(os.Stderr.Fd()))
|
||||
if err != nil {
|
||||
|
@ -65,39 +78,43 @@ func (b *Bar) String() string {
|
|||
}
|
||||
|
||||
fmt.Fprintf(&pre, "%3.0f%% ", math.Floor(b.percent()))
|
||||
|
||||
fmt.Fprintf(&suf, "(%s/%s", format.HumanBytes(b.currentValue), format.HumanBytes(b.maxValue))
|
||||
|
||||
stats := b.Stats()
|
||||
rate := int64(stats.rate)
|
||||
if rate > 0 {
|
||||
fmt.Fprintf(&suf, ", %s/s", format.HumanBytes(rate))
|
||||
rate := stats.rate
|
||||
if stats.value > b.initialValue && stats.value < b.maxValue {
|
||||
fmt.Fprintf(&suf, ", %s/s", format.HumanBytes(int64(rate)))
|
||||
}
|
||||
|
||||
fmt.Fprintf(&suf, ")")
|
||||
|
||||
elapsed := time.Since(b.started)
|
||||
if b.percent() < 100 && rate > 0 {
|
||||
fmt.Fprintf(&suf, " [%s:%s]", elapsed.Round(time.Second), stats.remaining)
|
||||
} else {
|
||||
fmt.Fprintf(&suf, " ")
|
||||
var timing string
|
||||
if stats.value > b.initialValue && stats.value < b.maxValue {
|
||||
timing = fmt.Sprintf("[%s:%s]", formatDuration(elapsed), formatDuration(stats.remaining))
|
||||
}
|
||||
|
||||
mid.WriteString("▕")
|
||||
// 44 is the maximum width for the stats on the right of the progress bar
|
||||
if suf.Len() < 44 {
|
||||
suf.WriteString(strings.Repeat(" ", 44-suf.Len()-len(timing)))
|
||||
}
|
||||
|
||||
suf.WriteString(timing)
|
||||
|
||||
// add 3 extra spaces: 2 boundary characters and 1 space at the end
|
||||
f := termWidth - pre.Len() - suf.Len() - 3
|
||||
n := int(float64(f) * b.percent() / 100)
|
||||
|
||||
if n > 0 {
|
||||
if f > 0 {
|
||||
mid.WriteString("▕")
|
||||
mid.WriteString(strings.Repeat("█", n))
|
||||
if f-n > 0 {
|
||||
mid.WriteString(strings.Repeat(" ", f-n))
|
||||
}
|
||||
mid.WriteString("▏")
|
||||
}
|
||||
|
||||
if f-n > 0 {
|
||||
mid.WriteString(strings.Repeat(" ", f-n))
|
||||
}
|
||||
|
||||
mid.WriteString("▏")
|
||||
|
||||
return pre.String() + mid.String() + suf.String()
|
||||
}
|
||||
|
||||
|
@ -140,6 +157,8 @@ func (b *Bar) Stats() Stats {
|
|||
var remaining time.Duration
|
||||
if rate > 0 {
|
||||
remaining = time.Second * time.Duration((float64(b.maxValue-b.currentValue))/(float64(rate)))
|
||||
} else {
|
||||
remaining = time.Duration(math.MaxInt64)
|
||||
}
|
||||
|
||||
b.stats = Stats{
|
||||
|
|
Loading…
Reference in a new issue