github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/src/pkg/message/progress.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: 2021-Present The Jackal Authors 3 4 // Package message provides a rich set of functions for displaying messages to the user. 5 package message 6 7 import ( 8 "os" 9 10 "github.com/pterm/pterm" 11 ) 12 13 const padding = " " 14 15 // ProgressBar is a struct used to drive a pterm ProgressbarPrinter. 16 type ProgressBar struct { 17 progress *pterm.ProgressbarPrinter 18 startText string 19 } 20 21 // NewProgressBar creates a new ProgressBar instance from a total value and a format. 22 func NewProgressBar(total int64, text string) *ProgressBar { 23 var progress *pterm.ProgressbarPrinter 24 if NoProgress { 25 Info(text) 26 } else { 27 progress, _ = pterm.DefaultProgressbar. 28 WithTotal(int(total)). 29 WithShowCount(false). 30 WithTitle(padding + text). 31 WithRemoveWhenDone(true). 32 WithMaxWidth(TermWidth). 33 WithWriter(os.Stderr). 34 Start() 35 } 36 37 return &ProgressBar{ 38 progress: progress, 39 startText: text, 40 } 41 } 42 43 // Update updates the ProgressBar with completed progress and new text. 44 func (p *ProgressBar) Update(complete int64, text string) { 45 if NoProgress { 46 debugPrinter(2, text) 47 return 48 } 49 p.progress.UpdateTitle(padding + text) 50 chunk := int(complete) - p.progress.Current 51 p.Add(chunk) 52 } 53 54 // UpdateTitle updates the ProgressBar with new text. 55 func (p *ProgressBar) UpdateTitle(text string) { 56 if NoProgress { 57 debugPrinter(2, text) 58 return 59 } 60 p.progress.UpdateTitle(padding + text) 61 } 62 63 // Add updates the ProgressBar with completed progress. 64 func (p *ProgressBar) Add(n int) { 65 if p.progress != nil { 66 if p.progress.Current+n >= p.progress.Total { 67 // @RAZZLE TODO: This is a hack to prevent the progress bar from going over 100% and causing TUI ugliness. 68 overflow := p.progress.Current + n - p.progress.Total 69 p.progress.Total += overflow + 1 70 } 71 p.progress.Add(n) 72 } 73 } 74 75 // Write updates the ProgressBar with the number of bytes in a buffer as the completed progress. 76 func (p *ProgressBar) Write(data []byte) (int, error) { 77 n := len(data) 78 if p.progress != nil { 79 p.Add(n) 80 } 81 return n, nil 82 } 83 84 // Successf marks the ProgressBar as successful in the CLI. 85 func (p *ProgressBar) Successf(format string, a ...any) { 86 p.Stop() 87 pterm.Success.Printfln(format, a...) 88 } 89 90 // Stop stops the ProgressBar from continuing. 91 func (p *ProgressBar) Stop() { 92 if p.progress != nil { 93 _, _ = p.progress.Stop() 94 } 95 } 96 97 // Errorf marks the ProgressBar as failed in the CLI. 98 func (p *ProgressBar) Errorf(err error, format string, a ...any) { 99 p.Stop() 100 WarnErrf(err, format, a...) 101 } 102 103 // GetCurrent returns the current total 104 func (p *ProgressBar) GetCurrent() int { 105 if p.progress != nil { 106 return p.progress.Current 107 } 108 return -1 109 }