From 6a3ace66ac9a07080f963d85196b257be4458e17 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Mon, 27 Jun 2016 12:17:33 -0600 Subject: [PATCH] Glide install skips fetch when it is up to date For 'glide install', this lazily computes whether the existing vendor checkouts are already at the right commit. If they are, those deps are skipped during the concurrent update. This is safe to do in install because the dependency graph is already computed, so there should never be a case where the glide.lock file does not contain a negotiable dependency graph. --- repo/installer.go | 41 +++++++++++++++++++++++++++++++++++++++-- repo/vcs.go | 4 ++-- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/repo/installer.go b/repo/installer.go index fee26c46..420ac278 100644 --- a/repo/installer.go +++ b/repo/installer.go @@ -111,8 +111,8 @@ func (i *Installer) Install(lock *cfg.Lockfile, conf *cfg.Config) (*cfg.Config, msg.Info("Downloading dependencies. Please wait...") - ConcurrentUpdate(newConf.Imports, cwd, i, newConf) - ConcurrentUpdate(newConf.DevImports, cwd, i, newConf) + LazyConcurrentUpdate(newConf.Imports, cwd, i, newConf) + LazyConcurrentUpdate(newConf.DevImports, cwd, i, newConf) return newConf, nil } @@ -302,6 +302,43 @@ func (i *Installer) List(conf *cfg.Config) []*cfg.Dependency { return conf.Imports } +// LazyConcurrentUpdate updates only deps that are not already checkout out at the right version. +// +// This is only safe when updating from a lock file. +func LazyConcurrentUpdate(deps []*cfg.Dependency, cwd string, i *Installer, c *cfg.Config) error { + + newDeps := []*cfg.Dependency{} + for _, dep := range deps { + destPath := filepath.Join(i.VendorPath(), dep.Name) + + // Get a VCS object for this directory + repo, err := dep.GetRepo(destPath) + if err != nil { + newDeps = append(newDeps, dep) + continue + } + + ver, err := repo.Version() + if err != nil { + newDeps = append(newDeps, dep) + continue + } + + if ver == dep.Reference { + msg.Info("--> Found desired version %s %s!", dep.Name, dep.Reference) + continue + } + + msg.Debug("--> Queue %s for update (%s != %s).", dep.Name, ver, dep.Reference) + newDeps = append(newDeps, dep) + } + if len(newDeps) > 0 { + return ConcurrentUpdate(newDeps, cwd, i, c) + } + + return nil +} + // ConcurrentUpdate takes a list of dependencies and updates in parallel. func ConcurrentUpdate(deps []*cfg.Dependency, cwd string, i *Installer, c *cfg.Config) error { done := make(chan struct{}, concurrentWorkers) diff --git a/repo/vcs.go b/repo/vcs.go index 31bed500..3f5f80d1 100644 --- a/repo/vcs.go +++ b/repo/vcs.go @@ -203,14 +203,14 @@ func VcsVersion(dep *cfg.Dependency, vend string) error { } ver := dep.Reference - // Referenes in Git can begin with a ^ which is similar to semver. + // References in Git can begin with a ^ which is similar to semver. // 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) } else { - // Create the constraing first to make sure it's valid before + // Create the constraint first to make sure it's valid before // working on the repo. constraint, err := semver.NewConstraint(ver)