Add a progress indicator.
diff --git a/action/create.go b/action/create.go index 5a8d6c4..31972c0 100644 --- a/action/create.go +++ b/action/create.go
@@ -93,7 +93,7 @@ } for _, i := range deps { - msg.Info("Found imported reference to %s\n", i.Name) + msg.Info("Found imported reference to %s", i.Name) config.Imports = append(config.Imports, i) } } @@ -124,7 +124,7 @@ root, subpkg := util.NormalizeName(n) if !config.HasDependency(root) { - msg.Info("Found reference to %s\n", n) + msg.Info("Found reference to %s", n) d := &cfg.Dependency{ Name: root, } @@ -137,7 +137,7 @@ subpkg = strings.TrimPrefix(subpkg, "/") d := config.Imports.Get(root) if !d.HasSubpackage(subpkg) { - msg.Info("Adding sub-package %s to %s\n", subpkg, root) + msg.Info("Adding sub-package %s to %s", subpkg, root) d.Subpackages = append(d.Subpackages, subpkg) } }
diff --git a/action/ensure.go b/action/ensure.go index c57bbac..6168f73 100644 --- a/action/ensure.go +++ b/action/ensure.go
@@ -99,7 +99,7 @@ } msg.Error("Could not find any of %s/src.\n", strings.Join(gps, "/src, ")) - msg.Info("As of Glide 0.5/Go 1.5, this is required.\n") + msg.Info("As of Glide 0.5/Go 1.5, this is required.") msg.Die("Wihtout src, cannot continue.") return "" }
diff --git a/action/rebuild.go b/action/rebuild.go index d53b774..8cebfa1 100644 --- a/action/rebuild.go +++ b/action/rebuild.go
@@ -24,10 +24,10 @@ msg.Die("Could not get vendor path: %s", err) } - msg.Info("Building dependencies.\n") + msg.Info("Building dependencies.") if len(conf.Imports) == 0 { - msg.Info("No dependencies found. Nothing built.\n") + msg.Info("No dependencies found. Nothing built.") return } @@ -87,7 +87,7 @@ } func buildPath(path string) error { - msg.Info("Running go build %s\n", path) + msg.Info("Running go build %s", path) // . in a filepath.Join is removed so it needs to be prepended separately. p := "." + string(filepath.Separator) + filepath.Join("vendor", path) out, err := exec.Command("go", "install", p).CombinedOutput()
diff --git a/action/update.go b/action/update.go index 5d56a51..15b4b80 100644 --- a/action/update.go +++ b/action/update.go
@@ -17,6 +17,9 @@ EnsureVendorDir() conf := EnsureConfig() + msg.StartProgress("Updating dependencies...") + defer msg.StopProgress("Update complete") + // Delete unused packages if installer.DeleteUnused { dependency.DeleteUnused(conf)
diff --git a/dependency/delete.go b/dependency/delete.go index 39a6367..8a0e5c0 100644 --- a/dependency/delete.go +++ b/dependency/delete.go
@@ -92,7 +92,7 @@ // Perform the actual delete. for _, path := range markForDelete { localPath := strings.TrimPrefix(path, searchPath) - msg.Info("Removing unused package: %s\n", localPath) + msg.Info("Removing unused package: %s", localPath) rerr := os.RemoveAll(path) if rerr != nil { return rerr
diff --git a/gb/gb.go b/gb/gb.go index 5a07c62..aa1816d 100644 --- a/gb/gb.go +++ b/gb/gb.go
@@ -24,7 +24,7 @@ return []*cfg.Dependency{}, nil } - msg.Info("Found GB manifest file.\n") + msg.Info("Found GB manifest file.") buf := []*cfg.Dependency{} file, err := os.Open(path) if err != nil {
diff --git a/glide.lock b/glide.lock index ef461c7..233399f 100644 --- a/glide.lock +++ b/glide.lock
@@ -1,8 +1,12 @@ -hash: 1d4d06656329894abc78c0ac256169337c947260b784fee7ed02a0e405c0f63b -updated: 2016-01-28T11:15:09.190330904-05:00 +hash: 45950a5c234a3741dbbb86a8f0fb4bd2757e3d19e571a8fe6e9372cbb878517c +updated: 2016-02-11T22:12:03.12669949-07:00 imports: - name: github.com/codegangsta/cli - version: c31a7975863e7810c92e2e288a9ab074f9a88f29 + version: 0ab42fd482c27cf2c95e7794ad3bb2082c2ab2d7 +- name: github.com/Masterminds/kitt + version: 7e843d5f21a5f009f5119a91ea3868eabb19b20f + subpackages: + - progress - name: github.com/Masterminds/semver version: 513f3dcb3ecfb1248831fb5cb06a23a3cd5935dc - name: github.com/Masterminds/vcs
diff --git a/glide.yaml b/glide.yaml index 09401c9..436abb1 100644 --- a/glide.yaml +++ b/glide.yaml
@@ -15,3 +15,4 @@ - package: github.com/codegangsta/cli - package: github.com/Masterminds/semver version: ^1.0.0 +- package: github.com/Masterminds/kitt
diff --git a/godep/godep.go b/godep/godep.go index 6785a0d..7670793 100644 --- a/godep/godep.go +++ b/godep/godep.go
@@ -53,7 +53,7 @@ if _, err := os.Stat(path); err != nil { return []*cfg.Dependency{}, nil } - msg.Info("Found Godeps.json file.\n") + msg.Info("Found Godeps.json file.") buf := []*cfg.Dependency{}
diff --git a/gpm/gpm.go b/gpm/gpm.go index 41de69d..9190a11 100644 --- a/gpm/gpm.go +++ b/gpm/gpm.go
@@ -27,10 +27,10 @@ if i, err := os.Stat(path); err != nil { return []*cfg.Dependency{}, nil } else if i.IsDir() { - msg.Info("Godeps is a directory. This is probably a Godep project.\n") + msg.Info("Godeps is a directory. This is probably a Godep project.") return []*cfg.Dependency{}, nil } - msg.Info("Found Godeps file.\n") + msg.Info("Found Godeps file.") buf := []*cfg.Dependency{}
diff --git a/msg/msg.go b/msg/msg.go index 7c9f705..ec8cfbc 100644 --- a/msg/msg.go +++ b/msg/msg.go
@@ -6,6 +6,8 @@ "os" "strings" "sync" + + "github.com/Masterminds/kitt/progress" ) // Messanger provides the underlying implementation that displays output to @@ -31,15 +33,30 @@ // PanicOnDie if true Die() will panic instead of exiting. PanicOnDie bool + // InProgress indicates whether the Messanger is currently in a progress meter. + InProgress bool + // The default exit code to use when dyping ecode int // If an error was been sent. hasErrored bool + + meter ProgressMeter +} + +type ProgressMeter interface { + Start(string) + Message(string) + Done(string) } // NewMessanger creates a default Messanger to display output. func NewMessanger() *Messanger { + //var mtr ProgressMeter = (nilMeter)(0) + mtr := progress.NewIndicator() + mtr.Frames = Cylon + mtr.Interval = CylonInterval m := &Messanger{ Quiet: false, IsDebugging: false, @@ -48,6 +65,8 @@ Stderr: os.Stderr, PanicOnDie: false, ecode: 1, + meter: mtr, + InProgress: false, } return m @@ -67,6 +86,10 @@ // Info logs information using the Default Messanger func Info(msg string, args ...interface{}) { + if Default.InProgress { + Default.meter.Message(fmt.Sprintf(msg, args...)) + return + } Default.Info(msg, args...) }
diff --git a/msg/progress.go b/msg/progress.go new file mode 100644 index 0000000..c06acf2 --- /dev/null +++ b/msg/progress.go
@@ -0,0 +1,57 @@ +package msg + +import ( + "fmt" + "time" +) + +var Cylon = []string{ + " 〖\033[0;31m ◼︎\033[m〗", + " 〖\033[0;31m ◼︎ \033[m〗", + " 〖\033[0;31m ◼︎▫︎ \033[m〗", + " 〖\033[0;31m ◼︎ ▫︎▫︎\033[m〗", + " 〖\033[0;31m ◼︎ ▫︎▫︎ \033[m〗", + " 〖\033[0;31m ◼︎ ▫︎▫︎ \033[m〗", + " 〖\033[0;31m ◼︎ ▫︎▫︎ \033[m〗", + " 〖\033[0;31m ◼︎ ▫︎▫︎ \033[m〗", + " 〖\033[0;31m◼︎ ▫︎▫︎ \033[m〗", + " 〖\033[0;31m◼︎ \033[m〗", + " 〖\033[0;31m▫︎◼︎ \033[m〗", + " 〖\033[0;31m▫︎▫︎◼︎ \033[m〗", + " 〖\033[0;31m ▫︎▫︎◼︎ \033[m〗", + " 〖\033[0;31m ▫︎▫︎◼︎ \033[m〗", + " 〖\033[0;31m ▫︎▫︎◼︎ \033[m〗", + " 〖\033[0;31m ▫︎▫︎◼︎ \033[m〗", + " 〖\033[0;31m ▫︎▫︎◼︎\033[m〗", +} + +const CylonInterval = 100 * time.Millisecond + +func StartProgress(msg string) { + Default.InProgress = true + Default.meter.Start(msg) +} + +func Progress(msg string, v ...interface{}) { + if Default.InProgress { + Default.meter.Message(fmt.Sprintf(msg, v...)) + } +} + +func StopProgress(msg string) { + Default.meter.Done(msg) + Default.InProgress = false +} + +// nilMeter is an implementation of ProgressMeter that prints messages to Info. +type nilMeter int + +func (n nilMeter) Start(s string) { + Info(s) +} +func (n nilMeter) Message(s string) { + Info(s) +} +func (n nilMeter) Done(s string) { + Info(s) +}
diff --git a/repo/installer.go b/repo/installer.go index 7ab1727..678818a 100644 --- a/repo/installer.go +++ b/repo/installer.go
@@ -4,6 +4,7 @@ "fmt" "os" "path/filepath" + "runtime" "strings" "sync" @@ -235,8 +236,6 @@ var lock sync.Mutex var returnErr error - msg.Info("Downloading dependencies. Please wait...") - for ii := 0; ii < concurrentWorkers; ii++ { go func(ch <-chan *cfg.Dependency) { for { @@ -268,6 +267,8 @@ in <- dep } + runtime.Gosched() + msg.Info("Fetching %d dependencies", len(deps)) wg.Wait() // Close goroutines setting the version
diff --git a/repo/set_reference.go b/repo/set_reference.go index d40615b..6a63187 100644 --- a/repo/set_reference.go +++ b/repo/set_reference.go
@@ -18,7 +18,7 @@ } if len(conf.Imports) == 0 { - msg.Info("No references set.\n") + msg.Info("No references set.") return nil }
diff --git a/repo/vcs.go b/repo/vcs.go index c54531f..3fa59d7 100644 --- a/repo/vcs.go +++ b/repo/vcs.go
@@ -30,17 +30,17 @@ return nil } - msg.Info("Fetching updates for %s.\n", dep.Name) + msg.Info("Fetching updates for %s.", dep.Name) if filterArchOs(dep) { - msg.Info("%s is not used for %s/%s.\n", dep.Name, runtime.GOOS, runtime.GOARCH) + msg.Info("%s is not used for %s/%s.", dep.Name, runtime.GOOS, runtime.GOARCH) return nil } // If destination doesn't exist we need to perform an initial checkout. if _, err := os.Stat(dest); os.IsNotExist(err) { if err = VcsGet(dep, dest, home, cache, cacheGopath, useGopath); err != nil { - msg.Warn("Unable to checkout %s\n", dep.Name) + msg.Warn("Unable to checkout %s", dep.Name) return err } } else { @@ -187,7 +187,7 @@ // If there is a ^ prefix we assume it's a semver constraint rather than // part of the git/VCS commit id. if repo.IsReference(ver) && !strings.HasPrefix(ver, "^") { - msg.Info("Setting version for %s to %s.\n", dep.Name, ver) + msg.Info("Setting version for %s to %s.", dep.Name, ver) } else { // Create the constraing first to make sure it's valid before @@ -222,7 +222,7 @@ } } if found { - msg.Info("Detected semantic version. Setting version for %s to %s.\n", dep.Name, ver) + msg.Info("Detected semantic version. Setting version for %s to %s.", dep.Name, ver) } else { msg.Warn("Unable to find semantic version for constraint %s %s\n", dep.Name, ver) }