diff --git a/core/commands/cat.go b/core/commands/cat.go index d48d11a13..389e1b4c2 100644 --- a/core/commands/cat.go +++ b/core/commands/cat.go @@ -1,24 +1,17 @@ package commands import ( - "fmt" "io" cmds "github.com/ipfs/go-ipfs/commands" core "github.com/ipfs/go-ipfs/core" coreunix "github.com/ipfs/go-ipfs/core/coreunix" - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/cheggaaa/pb" context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" ) const progressBarMinSize = 1024 * 1024 * 8 // show progress bar for outputs > 8MiB -type clearlineReader struct { - io.Reader - out io.Writer -} - var CatCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Show IPFS object data", @@ -54,12 +47,10 @@ it contains. return } - bar := pb.New(int(res.Length())).SetUnits(pb.U_BYTES) - bar.Output = res.Stderr() + bar, reader := progressBarForReader(res.Stderr(), res.Output().(io.Reader), int64(res.Length())) bar.Start() - reader := bar.NewProxyReader(res.Output().(io.Reader)) - res.SetOutput(&clearlineReader{reader, res.Stderr()}) + res.SetOutput(reader) }, } @@ -76,11 +67,3 @@ func cat(ctx context.Context, node *core.IpfsNode, paths []string) ([]io.Reader, } return readers, length, nil } - -func (r *clearlineReader) Read(p []byte) (n int, err error) { - n, err = r.Reader.Read(p) - if err == io.EOF { - fmt.Fprintf(r.out, "\033[2K\r") // clear progress bar line on EOF - } - return -} diff --git a/core/commands/get.go b/core/commands/get.go index 7c00a283a..6c6c271bb 100644 --- a/core/commands/get.go +++ b/core/commands/get.go @@ -112,13 +112,35 @@ may also specify the level of compression by specifying '-l=<1-9>'. }, } -func progressBarForReader(out io.Writer, r io.Reader) (*pb.ProgressBar, *pb.Reader) { +type clearlineReader struct { + io.Reader + out io.Writer +} + +func (r *clearlineReader) Read(p []byte) (n int, err error) { + n, err = r.Reader.Read(p) + if err == io.EOF { + // callback + fmt.Fprintf(r.out, "\033[2K\r") // clear progress bar line on EOF + } + return +} + +func progressBarForReader(out io.Writer, r io.Reader, l int64) (*pb.ProgressBar, io.Reader) { // setup bar reader // TODO: get total length of files - bar := pb.New(0).SetUnits(pb.U_BYTES) + bar := pb.New64(l).SetUnits(pb.U_BYTES) bar.Output = out + + // the progress bar lib doesn't give us a way to get the width of the output, + // so as a hack we just use a callback to measure the output, then git rid of it + bar.Callback = func(line string) { + terminalWidth := len(line) + bar.Callback = nil + log.Infof("terminal width: %v\n", terminalWidth) + } barR := bar.NewProxyReader(r) - return bar, barR + return bar, &clearlineReader{barR, out} } type getWriter struct { @@ -159,7 +181,7 @@ func (gw *getWriter) writeArchive(r io.Reader, fpath string) error { defer file.Close() fmt.Fprintf(gw.Out, "Saving archive to %s\n", fpath) - bar, barR := progressBarForReader(gw.Err, r) + bar, barR := progressBarForReader(gw.Err, r, 0) bar.Start() defer bar.Finish() @@ -169,7 +191,7 @@ func (gw *getWriter) writeArchive(r io.Reader, fpath string) error { func (gw *getWriter) writeExtracted(r io.Reader, fpath string) error { fmt.Fprintf(gw.Out, "Saving file(s) to %s\n", fpath) - bar, barR := progressBarForReader(gw.Err, r) + bar, barR := progressBarForReader(gw.Err, r, 0) bar.Start() defer bar.Finish()