mirror of
https://github.com/samuelncui/acp.git
synced 2025-12-23 13:15:16 +00:00
feat: progress bar
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -14,5 +14,6 @@
|
|||||||
# Dependency directories (remove the comment below to include it)
|
# Dependency directories (remove the comment below to include it)
|
||||||
# vendor/
|
# vendor/
|
||||||
|
|
||||||
./go.sum
|
go.sum
|
||||||
output/
|
output/
|
||||||
|
test.sh
|
||||||
|
|||||||
7
copy.go
7
copy.go
@@ -42,7 +42,6 @@ type Copyer struct {
|
|||||||
copyedFiles int64
|
copyedFiles int64
|
||||||
totalFiles int64
|
totalFiles int64
|
||||||
|
|
||||||
progressBarLock sync.Mutex
|
|
||||||
updateProgressBar func(func(bar *progressbar.ProgressBar))
|
updateProgressBar func(func(bar *progressbar.ProgressBar))
|
||||||
|
|
||||||
jobs []*Job
|
jobs []*Job
|
||||||
@@ -69,6 +68,7 @@ func New(ctx context.Context, opts ...Option) (*Copyer, error) {
|
|||||||
|
|
||||||
c := &Copyer{
|
c := &Copyer{
|
||||||
option: opt,
|
option: opt,
|
||||||
|
stage: StageIndex,
|
||||||
writePipe: make(chan *writeJob, 32),
|
writePipe: make(chan *writeJob, 32),
|
||||||
metaPipe: make(chan *metaJob, 8),
|
metaPipe: make(chan *metaJob, 8),
|
||||||
updateProgressBar: func(f func(bar *progressbar.ProgressBar)) {},
|
updateProgressBar: func(f func(bar *progressbar.ProgressBar)) {},
|
||||||
@@ -118,6 +118,11 @@ func (c *Copyer) index(ctx context.Context) {
|
|||||||
for _, s := range c.src {
|
for _, s := range c.src {
|
||||||
c.walk(s.base, s.path)
|
c.walk(s.base, s.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.updateProgressBar(func(bar *progressbar.ProgressBar) {
|
||||||
|
bar.ChangeMax64(atomic.LoadInt64(&c.totalBytes))
|
||||||
|
bar.Describe(fmt.Sprintf("[0/%d] index finished...", atomic.LoadInt64(&c.totalFiles)))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Copyer) copy(ctx context.Context) {
|
func (c *Copyer) copy(ctx context.Context) {
|
||||||
|
|||||||
40
go.sum
40
go.sum
@@ -1,40 +0,0 @@
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
|
||||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
|
||||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
|
||||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
|
|
||||||
github.com/klauspost/cpuid/v2 v2.0.4 h1:g0I61F2K2DjRHz1cnxlkNSBIaePVoJIjjnHui8QHbiw=
|
|
||||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
|
||||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
|
||||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
|
||||||
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
|
||||||
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
|
||||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
|
|
||||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
|
||||||
github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw=
|
|
||||||
github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
|
||||||
github.com/schollz/progressbar/v3 v3.10.1 h1:6A8v8TIcCJL4yemlUJS9gdcpZ++Gy6toOh1JzKQkz+U=
|
|
||||||
github.com/schollz/progressbar/v3 v3.10.1/go.mod h1:R2djRgv58sn00AGysc4fN0ip4piOGd3z88K+zVBjczs=
|
|
||||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
|
||||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
|
|
||||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc=
|
|
||||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
@@ -3,17 +3,39 @@ package acp
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/schollz/progressbar/v3"
|
"github.com/schollz/progressbar/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
barUpdateInterval = time.Nanosecond * 255002861
|
||||||
|
)
|
||||||
|
|
||||||
func (c *Copyer) startProgressBar(ctx context.Context) {
|
func (c *Copyer) startProgressBar(ctx context.Context) {
|
||||||
progressBar := progressbar.DefaultBytes(0, "[0/0] indexing...")
|
var lock sync.Mutex
|
||||||
|
|
||||||
|
// progressBar := progressbar.DefaultBytes(1, "[0/0] indexing...")
|
||||||
|
progressBar := progressbar.NewOptions64(
|
||||||
|
1,
|
||||||
|
progressbar.OptionSetDescription("[0/0] indexing..."),
|
||||||
|
progressbar.OptionSetWriter(os.Stderr),
|
||||||
|
progressbar.OptionShowBytes(true),
|
||||||
|
progressbar.OptionSetWidth(10),
|
||||||
|
progressbar.OptionThrottle(65*time.Millisecond),
|
||||||
|
progressbar.OptionShowCount(),
|
||||||
|
progressbar.OptionOnCompletion(func() {}),
|
||||||
|
progressbar.OptionSpinnerType(14),
|
||||||
|
progressbar.OptionFullWidth(),
|
||||||
|
progressbar.OptionSetRenderBlankState(true),
|
||||||
|
)
|
||||||
|
|
||||||
c.updateProgressBar = func(f func(bar *progressbar.ProgressBar)) {
|
c.updateProgressBar = func(f func(bar *progressbar.ProgressBar)) {
|
||||||
c.progressBarLock.Lock()
|
lock.Lock()
|
||||||
defer c.progressBarLock.Unlock()
|
defer lock.Unlock()
|
||||||
|
|
||||||
if progressBar == nil {
|
if progressBar == nil {
|
||||||
return
|
return
|
||||||
@@ -22,14 +44,12 @@ func (c *Copyer) startProgressBar(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
ticker := time.NewTicker(time.Nanosecond * 255002861) // around 255ms, avoid conflict with progress bar fresh by second
|
ticker := time.NewTicker(barUpdateInterval) // around 255ms, avoid conflict with progress bar fresh by second
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
var lastCopyedBytes int64
|
var lastCopyedBytes int64
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
c.progressBarLock.Lock()
|
switch atomic.LoadInt64(&c.stage) {
|
||||||
|
|
||||||
switch c.stage {
|
|
||||||
case StageIndex:
|
case StageIndex:
|
||||||
go c.updateProgressBar(func(bar *progressbar.ProgressBar) {
|
go c.updateProgressBar(func(bar *progressbar.ProgressBar) {
|
||||||
bar.ChangeMax64(atomic.LoadInt64(&c.totalBytes))
|
bar.ChangeMax64(atomic.LoadInt64(&c.totalBytes))
|
||||||
@@ -37,11 +57,11 @@ func (c *Copyer) startProgressBar(ctx context.Context) {
|
|||||||
})
|
})
|
||||||
case StageCopy:
|
case StageCopy:
|
||||||
currentCopyedBytes := atomic.LoadInt64(&c.copyedBytes)
|
currentCopyedBytes := atomic.LoadInt64(&c.copyedBytes)
|
||||||
diff := int(currentCopyedBytes - lastCopyedBytes)
|
diff := currentCopyedBytes - lastCopyedBytes
|
||||||
lastCopyedBytes = currentCopyedBytes
|
lastCopyedBytes = currentCopyedBytes
|
||||||
|
|
||||||
go c.updateProgressBar(func(bar *progressbar.ProgressBar) {
|
go c.updateProgressBar(func(bar *progressbar.ProgressBar) {
|
||||||
bar.Add(diff)
|
bar.Add64(diff)
|
||||||
})
|
})
|
||||||
case StageFinished:
|
case StageFinished:
|
||||||
currentCopyedBytes := atomic.LoadInt64(&c.copyedBytes)
|
currentCopyedBytes := atomic.LoadInt64(&c.copyedBytes)
|
||||||
@@ -49,7 +69,6 @@ func (c *Copyer) startProgressBar(ctx context.Context) {
|
|||||||
lastCopyedBytes = currentCopyedBytes
|
lastCopyedBytes = currentCopyedBytes
|
||||||
|
|
||||||
copyedFiles, totalFiles := atomic.LoadInt64(&c.copyedFiles), atomic.LoadInt64(&c.totalFiles)
|
copyedFiles, totalFiles := atomic.LoadInt64(&c.copyedFiles), atomic.LoadInt64(&c.totalFiles)
|
||||||
|
|
||||||
c.updateProgressBar(func(bar *progressbar.ProgressBar) {
|
c.updateProgressBar(func(bar *progressbar.ProgressBar) {
|
||||||
bar.Add(diff)
|
bar.Add(diff)
|
||||||
bar.Describe(fmt.Sprintf("[%d/%d] finished!", copyedFiles, totalFiles))
|
bar.Describe(fmt.Sprintf("[%d/%d] finished!", copyedFiles, totalFiles))
|
||||||
@@ -58,6 +77,7 @@ func (c *Copyer) startProgressBar(ctx context.Context) {
|
|||||||
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
|
time.Sleep(barUpdateInterval)
|
||||||
c.updateProgressBar(func(bar *progressbar.ProgressBar) {
|
c.updateProgressBar(func(bar *progressbar.ProgressBar) {
|
||||||
bar.Close()
|
bar.Close()
|
||||||
progressBar = nil
|
progressBar = nil
|
||||||
@@ -65,8 +85,6 @@ func (c *Copyer) startProgressBar(ctx context.Context) {
|
|||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
c.progressBarLock.Unlock()
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user