Browse Source

prettier output and progress

show bars for all layers, and print colored lines instead of just using
logrus
Alex Suraci 7 years ago
parent
commit
8d8b4aa22a
4 changed files with 55 additions and 35 deletions
  1. 3 5
      cmd/in/main.go
  2. 30 22
      cmd/in/unpack.go
  3. 6 2
      go.mod
  4. 16 6
      go.sum

+ 3 - 5
cmd/in/main.go

@@ -2,10 +2,12 @@ package main
 
 import (
 	"encoding/json"
+	"fmt"
 	"os"
 	"path/filepath"
 
 	resource "github.com/concourse/registry-image-resource"
+	color "github.com/fatih/color"
 	"github.com/google/go-containerregistry/pkg/name"
 	"github.com/google/go-containerregistry/pkg/v1/remote"
 	"github.com/sirupsen/logrus"
@@ -62,7 +64,7 @@ func main() {
 		return
 	}
 
-	logrus.Infof("fetching %s:%s (%s)", req.Source.Repository, req.Source.Tag, req.Version.Digest)
+	fmt.Fprintf(os.Stderr, "fetching %s@%s\n", color.GreenString(req.Source.Repository), color.YellowString(req.Version.Digest))
 
 	image, err := remote.Image(n)
 	if err != nil {
@@ -71,8 +73,6 @@ func main() {
 		return
 	}
 
-	logrus.Infof("unpacking image")
-
 	err = unpackImage(filepath.Join(dest, "rootfs"), image)
 	if err != nil {
 		logrus.Errorf("failed to extract image: %s", err)
@@ -80,8 +80,6 @@ func main() {
 		return
 	}
 
-	logrus.Infof("writing metadata")
-
 	cfg, err := image.ConfigFile()
 	if err != nil {
 		logrus.Errorf("failed to inspect image config: %s", err)

+ 30 - 22
cmd/in/unpack.go

@@ -9,9 +9,11 @@ import (
 	"strings"
 
 	"github.com/concourse/go-archive/tarfs"
+	"github.com/fatih/color"
 	"github.com/google/go-containerregistry/pkg/v1"
 	"github.com/sirupsen/logrus"
-	pb "gopkg.in/cheggaaa/pb.v1"
+	"github.com/vbauerster/mpb"
+	"github.com/vbauerster/mpb/decor"
 )
 
 const whiteoutPrefix = ".wh."
@@ -27,43 +29,49 @@ func unpackImage(dest string, img v1.Image) error {
 
 	chown := os.Getuid() == 0
 
+	progress := mpb.New(mpb.WithWidth(64), mpb.WithOutput(os.Stderr))
+
+	bars := make([]*mpb.Bar, len(layers))
+
+	for i, layer := range layers {
+		size, err := layer.Size()
+		if err != nil {
+			return err
+		}
+
+		digest, err := layer.Digest()
+		if err != nil {
+			return err
+		}
+
+		bars[i] = progress.AddBar(
+			size,
+			mpb.PrependDecorators(decor.Name(color.HiBlackString(digest.Hex[0:12]))),
+			mpb.AppendDecorators(decor.CountersKibiByte("%.1f/%.1f")),
+		)
+	}
+
 	// iterate over layers in reverse order; no need to write things files that
 	// are modified by later layers anyway
 	for i := len(layers) - 1; i >= 0; i-- {
-		err := extractLayer(dest, layers[i], written, removed, chown)
+		err := extractLayer(dest, layers[i], bars[i], written, removed, chown)
 		if err != nil {
 			return err
 		}
 	}
 
+	progress.Wait()
+
 	return nil
 }
 
-func extractLayer(dest string, layer v1.Layer, written, removed map[string]struct{}, chown bool) error {
-	size, err := layer.Size()
-	if err != nil {
-		return err
-	}
-
-	digest, err := layer.Digest()
-	if err != nil {
-		return err
-	}
-
+func extractLayer(dest string, layer v1.Layer, bar *mpb.Bar, written, removed map[string]struct{}, chown bool) error {
 	r, err := layer.Compressed()
 	if err != nil {
 		return err
 	}
 
-	bar := pb.New64(size).SetUnits(pb.U_BYTES)
-	bar.Output = os.Stderr
-	bar.Prefix(digest.Hex[0:12])
-	bar.SetWidth(80)
-
-	bar.Start()
-	defer bar.Finish()
-
-	gr, err := gzip.NewReader(bar.NewProxyReader(r))
+	gr, err := gzip.NewReader(bar.ProxyReader(r))
 	if err != nil {
 		return err
 	}

+ 6 - 2
go.mod

@@ -1,19 +1,24 @@
 module github.com/concourse/registry-image-resource
 
 require (
+	github.com/VividCortex/ewma v1.1.1 // indirect
 	github.com/concourse/go-archive v0.0.0-20180803203406-784931698f4f
 	github.com/davecgh/go-spew v1.1.0 // indirect
+	github.com/fatih/color v1.7.0
 	github.com/fsnotify/fsnotify v1.4.7 // indirect
 	github.com/golang/protobuf v1.1.0 // indirect
 	github.com/google/go-cmp v0.2.0 // indirect
 	github.com/google/go-containerregistry v0.0.0-20180801194910-5f7b0e489541
 	github.com/hpcloud/tail v1.0.0 // indirect
-	github.com/mattn/go-runewidth v0.0.2 // indirect
+	github.com/kr/pretty v0.1.0 // indirect
+	github.com/mattn/go-colorable v0.0.9 // indirect
+	github.com/mattn/go-isatty v0.0.3 // indirect
 	github.com/onsi/ginkgo v1.6.0 // indirect
 	github.com/onsi/gomega v1.4.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/sirupsen/logrus v1.0.6
 	github.com/stretchr/testify v1.2.2 // indirect
+	github.com/vbauerster/mpb v3.3.1+incompatible
 	golang.org/x/crypto v0.0.0-20180802221240-56440b844dfe // indirect
 	golang.org/x/net v0.0.0-20180801234040-f4c29de78a2a // indirect
 	golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f // indirect
@@ -21,7 +26,6 @@ require (
 	golang.org/x/text v0.3.0 // indirect
 	gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
 	gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
-	gopkg.in/cheggaaa/pb.v1 v1.0.25
 	gopkg.in/fsnotify.v1 v1.4.7 // indirect
 	gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
 	gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect

+ 16 - 6
go.sum

@@ -1,9 +1,11 @@
-github.com/concourse/go-archive v0.0.0-20180803050304-8400900bd01d h1:Pv7E5Y4zVdyd2yAnVC2pVwMbCBPsvwoUe62rhdVn8MM=
-github.com/concourse/go-archive v0.0.0-20180803050304-8400900bd01d/go.mod h1:Xfo080IPQBmVz3I5ehjCddW3phA2mwv0NFwlpjf5CO8=
+github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
+github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
 github.com/concourse/go-archive v0.0.0-20180803203406-784931698f4f h1:Z7s60kZd9kuWiosivO9QPGH1vmfC/lzLDiuWIy0MT+o=
 github.com/concourse/go-archive v0.0.0-20180803203406-784931698f4f/go.mod h1:Xfo080IPQBmVz3I5ehjCddW3phA2mwv0NFwlpjf5CO8=
 github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/golang/protobuf v1.1.0 h1:0iH4Ffd/meGoXqF2lSAhZHt8X+cPgkfn/cb6Cce5Vpc=
@@ -14,8 +16,15 @@ github.com/google/go-containerregistry v0.0.0-20180801194910-5f7b0e489541 h1:smM
 github.com/google/go-containerregistry v0.0.0-20180801194910-5f7b0e489541/go.mod h1:yZAFP63pRshzrEYLXLGPmUt0Ay+2zdjmMN1loCnRLUk=
 github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC63o=
-github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v1.4.1 h1:PZSj/UFNaVp3KxrzHOcS7oyuWA7LoOY/77yCTEFu21U=
@@ -26,6 +35,8 @@ github.com/sirupsen/logrus v1.0.6 h1:hcP1GmhGigz/O7h1WVUM5KklBp1JoNS9FggWKdj/j3s
 github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
 github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/vbauerster/mpb v3.3.1+incompatible h1:895YxWn6TBP+leAp2kml6H+Rccyo6kXcqKZpbig1wuI=
+github.com/vbauerster/mpb v3.3.1+incompatible/go.mod h1:zAHG26FUhVKETRu+MWqYXcI70POlC6N8up9p1dID7SU=
 golang.org/x/crypto v0.0.0-20180802221240-56440b844dfe h1:APBCFlxGVQi3YDSHtTbNXRZhDEuz9rrnVPXZA4YbUx8=
 golang.org/x/crypto v0.0.0-20180802221240-56440b844dfe/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/net v0.0.0-20180801234040-f4c29de78a2a h1:8fCF9zjAir2SP3N+axz9xs+0r4V8dqPzqsWO10t8zoo=
@@ -40,9 +51,8 @@ gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNat
 gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I=
-gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
 gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0=