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  }