Skip to content

Commit

Permalink
Add simple byte-counting export progress-bar
Browse files Browse the repository at this point in the history
  • Loading branch information
ribasushi committed Mar 28, 2020
1 parent faacfbb commit ce72271
Showing 1 changed file with 69 additions and 0 deletions.
69 changes: 69 additions & 0 deletions core/commands/dag/dag.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package dagcmd

import (
"errors"
"fmt"
"io"
"math"
"os"
"strings"
"time"

"github.com/ipfs/go-ipfs/core/commands/cmdenv"
"github.com/ipfs/go-ipfs/core/coredag"
Expand All @@ -23,6 +26,12 @@ import (
//gipfree "github.com/ipld/go-ipld-prime/impl/free"
//gipselector "github.com/ipld/go-ipld-prime/traversal/selector"
//gipselectorbuilder "github.com/ipld/go-ipld-prime/traversal/selector/builder"

"gopkg.in/cheggaaa/pb.v1"
)

const (
progressOptionName = "progress"
)

var DagCmd = &cmds.Command{
Expand Down Expand Up @@ -261,6 +270,9 @@ The output of blocks happens in strict DAG-traversal, first-seen, order.
Arguments: []cmds.Argument{
cmds.StringArg("root", true, false, "CID of a root to recursively export").EnableStdin(),
},
Options: []cmds.Option{
cmds.BoolOption(progressOptionName, "p", "Display progress on CLI. Defaults to true when STDERR is a TTY."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {

c, err := cid.Decode(req.Arguments[0])
Expand Down Expand Up @@ -334,4 +346,61 @@ The output of blocks happens in strict DAG-traversal, first-seen, order.

return err
},
PostRun: cmds.PostRunMap{
cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error {

var showProgress bool
val, specified := res.Request().Options[progressOptionName]
if !specified {
// default based on TTY availability
errStat, _ := os.Stderr.Stat()
if 0 != (errStat.Mode() & os.ModeCharDevice) {
showProgress = true
}
} else if val.(bool) {
showProgress = true
}

// simple passthrough, no progress
if !showProgress {
return cmds.Copy(re, res)
}

bar := pb.New64(0).SetUnits(pb.U_BYTES)
bar.Output = os.Stderr
bar.ShowSpeed = true
bar.ShowElapsedTime = true
bar.RefreshRate = 500 * time.Millisecond
bar.Start()

var processedOneResponse bool
for {
v, err := res.Next()
if err == io.EOF {

// We only write the final bar update on success
// On error it looks too weird
bar.Finish()

return re.Close()
} else if err != nil {
return re.CloseWithError(err)
} else if processedOneResponse {
return re.CloseWithError(errors.New("unexpected multipart response during emit, please file a bugreport"))
}

r, ok := v.(io.Reader)
if !ok {
// some sort of encoded response, this should not be happening
return errors.New("unexpected non-stream passed to PostRun: please file a bugreport")
}

processedOneResponse = true

if err := re.Emit(bar.NewProxyReader(r)); err != nil {
return err
}
}
},
},
}

0 comments on commit ce72271

Please sign in to comment.