github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/status.go (about) 1 // Copyright (c) 2015-2022 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package cmd 19 20 import ( 21 "io" 22 "sync/atomic" 23 24 "github.com/minio/mc/pkg/probe" 25 "github.com/minio/pkg/v2/console" 26 ) 27 28 // Status implements a interface that can be used in quit mode or with progressbar. 29 type Status interface { 30 Println(data ...interface{}) 31 AddCounts(int64) 32 SetCounts(int64) 33 GetCounts() int64 34 Add(int64) Status 35 Get() int64 36 Start() 37 Finish() 38 PrintMsg(msg message) 39 Update() 40 Total() int64 41 SetTotal(int64) Status 42 SetCaption(string) 43 Read(p []byte) (n int, err error) 44 45 errorIf(err *probe.Error, msg string) 46 fatalIf(err *probe.Error, msg string) 47 } 48 49 // NewQuietStatus returns a quiet status object 50 func NewQuietStatus(hook io.Reader) Status { 51 return &QuietStatus{ 52 accounter: newAccounter(0), 53 hook: hook, 54 } 55 } 56 57 // QuietStatus will only show the progress and summary 58 type QuietStatus struct { 59 // Keep this as first element of struct because it guarantees 64bit 60 // alignment on 32 bit machines. atomic.* functions crash if operand is not 61 // aligned at 64bit. See https://github.com/golang/go/issues/599 62 counts int64 63 *accounter 64 hook io.Reader 65 } 66 67 // Read implements the io.Reader interface 68 func (qs *QuietStatus) Read(p []byte) (n int, err error) { 69 qs.hook.Read(p) 70 return qs.accounter.Read(p) 71 } 72 73 // SetCounts sets number of files uploaded 74 func (qs *QuietStatus) SetCounts(v int64) { 75 atomic.StoreInt64(&qs.counts, v) 76 } 77 78 // GetCounts returns number of files uploaded 79 func (qs *QuietStatus) GetCounts() int64 { 80 return atomic.LoadInt64(&qs.counts) 81 } 82 83 // AddCounts adds 'v' number of files uploaded. 84 func (qs *QuietStatus) AddCounts(v int64) { 85 atomic.AddInt64(&qs.counts, v) 86 } 87 88 // SetTotal sets the total of the progressbar, ignored for quietstatus 89 func (qs *QuietStatus) SetTotal(v int64) Status { 90 qs.accounter.SetTotal(v) 91 return qs 92 } 93 94 // SetCaption sets the caption of the progressbar, ignored for quietstatus 95 func (qs *QuietStatus) SetCaption(_ string) { 96 } 97 98 // Get returns the current number of bytes 99 func (qs *QuietStatus) Get() int64 { 100 return qs.accounter.Get() 101 } 102 103 // Total returns the total number of bytes 104 func (qs *QuietStatus) Total() int64 { 105 return qs.accounter.Get() 106 } 107 108 // Add bytes to current number of bytes 109 func (qs *QuietStatus) Add(v int64) Status { 110 qs.accounter.Add(v) 111 return qs 112 } 113 114 // Println prints line, ignored for quietstatus 115 func (qs *QuietStatus) Println(_ ...interface{}) { 116 } 117 118 // PrintMsg prints message 119 func (qs *QuietStatus) PrintMsg(msg message) { 120 printMsg(msg) 121 } 122 123 // Start is ignored for quietstatus 124 func (qs *QuietStatus) Start() { 125 } 126 127 // Finish displays the accounting summary 128 func (qs *QuietStatus) Finish() { 129 printMsg(qs.accounter.Stat()) 130 } 131 132 // Update is ignored for quietstatus 133 func (qs *QuietStatus) Update() { 134 } 135 136 func (qs *QuietStatus) errorIf(err *probe.Error, msg string) { 137 errorIf(err, msg) 138 } 139 140 func (qs *QuietStatus) fatalIf(err *probe.Error, msg string) { 141 fatalIf(err, msg) 142 } 143 144 // NewProgressStatus returns a progress status object 145 func NewProgressStatus(hook io.Reader) Status { 146 return &ProgressStatus{ 147 progressBar: newProgressBar(0), 148 hook: hook, 149 } 150 } 151 152 // ProgressStatus shows a progressbar 153 type ProgressStatus struct { 154 // Keep this as first element of struct because it guarantees 64bit 155 // alignment on 32 bit machines. atomic.* functions crash if operand is not 156 // aligned at 64bit. See https://github.com/golang/go/issues/599 157 counts int64 158 *progressBar 159 hook io.Reader 160 } 161 162 // Read implements the io.Reader interface 163 func (ps *ProgressStatus) Read(p []byte) (n int, err error) { 164 ps.hook.Read(p) 165 return ps.progressBar.Read(p) 166 } 167 168 // SetCaption sets the caption of the progressbar 169 func (ps *ProgressStatus) SetCaption(s string) { 170 ps.progressBar.SetCaption(s) 171 } 172 173 // SetCounts sets number of files uploaded 174 func (ps *ProgressStatus) SetCounts(v int64) { 175 atomic.StoreInt64(&ps.counts, v) 176 } 177 178 // GetCounts returns number of files uploaded 179 func (ps *ProgressStatus) GetCounts() int64 { 180 return atomic.LoadInt64(&ps.counts) 181 } 182 183 // AddCounts adds 'v' number of files uploaded. 184 func (ps *ProgressStatus) AddCounts(v int64) { 185 atomic.AddInt64(&ps.counts, v) 186 } 187 188 // Get returns the current number of bytes 189 func (ps *ProgressStatus) Get() int64 { 190 return ps.progressBar.Get() 191 } 192 193 // Total returns the total number of bytes 194 func (ps *ProgressStatus) Total() int64 { 195 return ps.progressBar.Get() 196 } 197 198 // SetTotal sets the total of the progressbar 199 func (ps *ProgressStatus) SetTotal(v int64) Status { 200 ps.progressBar.SetTotal(v) 201 return ps 202 } 203 204 // Add bytes to current number of bytes 205 func (ps *ProgressStatus) Add(v int64) Status { 206 ps.progressBar.Add64(v) 207 return ps 208 } 209 210 // Println prints line, ignored for quietstatus 211 func (ps *ProgressStatus) Println(data ...interface{}) { 212 console.Eraseline() 213 console.Println(data...) 214 } 215 216 // PrintMsg prints message 217 func (ps *ProgressStatus) PrintMsg(_ message) { 218 } 219 220 // Start is ignored for quietstatus 221 func (ps *ProgressStatus) Start() { 222 ps.progressBar.Start() 223 } 224 225 // Finish displays the accounting summary 226 func (ps *ProgressStatus) Finish() { 227 ps.progressBar.Finish() 228 } 229 230 // Update is ignored for quietstatus 231 func (ps *ProgressStatus) Update() { 232 ps.progressBar.Update() 233 } 234 235 func (ps *ProgressStatus) errorIf(err *probe.Error, msg string) { 236 // remove progressbar 237 console.Eraseline() 238 errorIf(err, msg) 239 240 ps.progressBar.Update() 241 } 242 243 func (ps *ProgressStatus) fatalIf(err *probe.Error, msg string) { 244 // remove progressbar 245 console.Eraseline() 246 fatalIf(err, msg) 247 248 ps.progressBar.Update() 249 }