github.com/mfycheng/glide@v0.11.2-0.20160818232903-be8a502f4bc4/action/update.go (about)

     1  package action
     2  
     3  import (
     4  	"io/ioutil"
     5  	"path/filepath"
     6  
     7  	"github.com/Masterminds/glide/cache"
     8  	"github.com/Masterminds/glide/cfg"
     9  	"github.com/Masterminds/glide/msg"
    10  	gpath "github.com/Masterminds/glide/path"
    11  	"github.com/Masterminds/glide/repo"
    12  )
    13  
    14  // Update updates repos and the lock file from the main glide yaml.
    15  func Update(installer *repo.Installer, skipRecursive, stripVendor bool) {
    16  	cache.SystemLock()
    17  
    18  	base := "."
    19  	EnsureGopath()
    20  	EnsureVendorDir()
    21  	conf := EnsureConfig()
    22  
    23  	// Try to check out the initial dependencies.
    24  	if err := installer.Checkout(conf); err != nil {
    25  		msg.Die("Failed to do initial checkout of config: %s", err)
    26  	}
    27  
    28  	// Set the versions for the initial dependencies so that resolved dependencies
    29  	// are rooted in the correct version of the base.
    30  	if err := repo.SetReference(conf, installer.ResolveTest); err != nil {
    31  		msg.Die("Failed to set initial config references: %s", err)
    32  	}
    33  
    34  	// Prior to resolving dependencies we need to start working with a clone
    35  	// of the conf because we'll be making real changes to it.
    36  	confcopy := conf.Clone()
    37  
    38  	if !skipRecursive {
    39  		// Get all repos and update them.
    40  		err := installer.Update(confcopy)
    41  		if err != nil {
    42  			msg.Die("Could not update packages: %s", err)
    43  		}
    44  
    45  		// Set references. There may be no remaining references to set since the
    46  		// installer set them as it went to make sure it parsed the right imports
    47  		// from the right version of the package.
    48  		msg.Info("Setting references for remaining imports")
    49  		if err := repo.SetReference(confcopy, installer.ResolveTest); err != nil {
    50  			msg.Err("Failed to set references: %s (Skip to cleanup)", err)
    51  		}
    52  	}
    53  
    54  	err := installer.Export(confcopy)
    55  	if err != nil {
    56  		msg.Die("Unable to export dependencies to vendor directory: %s", err)
    57  	}
    58  
    59  	// Write glide.yaml (Why? Godeps/GPM/GB?)
    60  	// I think we don't need to write a new Glide file because update should not
    61  	// change anything important. It will just generate information about
    62  	// transative dependencies, all of which belongs exclusively in the lock
    63  	// file, not the glide.yaml file.
    64  	// TODO(mattfarina): Detect when a new dependency has been added or removed
    65  	// from the project. A removed dependency should warn and an added dependency
    66  	// should be added to the glide.yaml file. See issue #193.
    67  
    68  	if !skipRecursive {
    69  		// Write lock
    70  		hash, err := conf.Hash()
    71  		if err != nil {
    72  			msg.Die("Failed to generate config hash. Unable to generate lock file.")
    73  		}
    74  		lock, err := cfg.NewLockfile(confcopy.Imports, confcopy.DevImports, hash)
    75  		if err != nil {
    76  			msg.Die("Failed to generate lock file: %s", err)
    77  		}
    78  		wl := true
    79  		if gpath.HasLock(base) {
    80  			yml, err := ioutil.ReadFile(filepath.Join(base, gpath.LockFile))
    81  			if err == nil {
    82  				l2, err := cfg.LockfileFromYaml(yml)
    83  				if err == nil {
    84  					f1, err := l2.Fingerprint()
    85  					f2, err2 := lock.Fingerprint()
    86  					if err == nil && err2 == nil && f1 == f2 {
    87  						wl = false
    88  					}
    89  				}
    90  			}
    91  		}
    92  		if wl {
    93  			if err := lock.WriteFile(filepath.Join(base, gpath.LockFile)); err != nil {
    94  				msg.Err("Could not write lock file to %s: %s", base, err)
    95  				return
    96  			}
    97  		} else {
    98  			msg.Info("Versions did not change. Skipping glide.lock update.")
    99  		}
   100  
   101  		msg.Info("Project relies on %d dependencies.", len(confcopy.Imports))
   102  	} else {
   103  		msg.Warn("Skipping lockfile generation because full dependency tree is not being calculated")
   104  	}
   105  
   106  	if stripVendor {
   107  		msg.Info("Removing nested vendor and Godeps/_workspace directories...")
   108  		err := gpath.StripVendor()
   109  		if err != nil {
   110  			msg.Err("Unable to strip vendor directories: %s", err)
   111  		}
   112  	}
   113  }