github.com/daniel-garcia/glide@v0.0.0-20160218012856-2eab91fab790/action/get.go (about) 1 package action 2 3 import ( 4 "fmt" 5 "path/filepath" 6 "strings" 7 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 "github.com/Masterminds/glide/util" 13 ) 14 15 // Get fetches one or more dependencies and installs. 16 // 17 // This includes resolving dependency resolution and re-generating the lock file. 18 func Get(names []string, installer *repo.Installer, insecure, skipRecursive bool) { 19 base := gpath.Basepath() 20 EnsureGopath() 21 EnsureVendorDir() 22 conf := EnsureConfig() 23 glidefile, err := gpath.Glide() 24 if err != nil { 25 msg.Die("Could not find Glide file: %s", err) 26 } 27 28 // Add the packages to the config. 29 if err := addPkgsToConfig(conf, names, insecure); err != nil { 30 msg.Die("Failed to get new packages: %s", err) 31 } 32 33 // Fetch the new packages. Can't resolve versions via installer.Update if 34 // get is called while the vendor/ directory is empty so we checkout 35 // everything. 36 installer.Checkout(conf, false) 37 38 // Prior to resolving dependencies we need to start working with a clone 39 // of the conf because we'll be making real changes to it. 40 confcopy := conf.Clone() 41 42 if !skipRecursive { 43 // Get all repos and update them. 44 // TODO: Can we streamline this in any way? The reason that we update all 45 // of the dependencies is that we need to re-negotiate versions. For example, 46 // if an existing dependency has the constraint >1.0 and this new package 47 // adds the constraint <2.0, then this may re-resolve the existing dependency 48 // to be between 1.0 and 2.0. But changing that dependency may then result 49 // in that dependency's dependencies changing... so we sorta do the whole 50 // thing to be safe. 51 err = installer.Update(confcopy) 52 if err != nil { 53 msg.Die("Could not update packages: %s", err) 54 } 55 } 56 57 // Set Reference 58 if err := repo.SetReference(confcopy); err != nil { 59 msg.Err("Failed to set references: %s", err) 60 } 61 62 // VendoredCleanup 63 if installer.UpdateVendored { 64 repo.VendoredCleanup(confcopy) 65 } 66 67 // Write YAML 68 if err := conf.WriteFile(glidefile); err != nil { 69 msg.Die("Failed to write glide YAML file: %s", err) 70 } 71 if !skipRecursive { 72 // Write lock 73 writeLock(conf, confcopy, base) 74 } else { 75 msg.Warn("Skipping lockfile generation because full dependency tree is not being calculated") 76 } 77 } 78 79 func writeLock(conf, confcopy *cfg.Config, base string) { 80 hash, err := conf.Hash() 81 if err != nil { 82 msg.Die("Failed to generate config hash. Unable to generate lock file.") 83 } 84 lock := cfg.NewLockfile(confcopy.Imports, hash) 85 if err := lock.WriteFile(filepath.Join(base, gpath.LockFile)); err != nil { 86 msg.Die("Failed to write glide lock file: %s", err) 87 } 88 } 89 90 // addPkgsToConfig adds the given packages to the config file. 91 // 92 // Along the way it: 93 // - ensures that this package is not in the ignore list 94 // - checks to see if this is already in the dependency list. 95 // - splits version of of package name and adds the version attribute 96 // - separates repo from packages 97 // - sets up insecure repo URLs where necessary 98 // - generates a list of subpackages 99 func addPkgsToConfig(conf *cfg.Config, names []string, insecure bool) error { 100 101 msg.Info("Preparing to install %d package.", len(names)) 102 103 for _, name := range names { 104 var version string 105 parts := strings.Split(name, "#") 106 if len(parts) > 1 { 107 name = parts[0] 108 version = parts[1] 109 } 110 111 root, subpkg := util.NormalizeName(name) 112 if len(root) == 0 { 113 return fmt.Errorf("Package name is required for %q.", name) 114 } 115 116 if conf.HasDependency(root) { 117 118 // Check if the subpackage is present. 119 if subpkg != "" { 120 dep := conf.Imports.Get(root) 121 if dep.HasSubpackage(subpkg) { 122 msg.Warn("Package %q is already in glide.yaml. Skipping", name) 123 } else { 124 dep.Subpackages = append(dep.Subpackages, subpkg) 125 msg.Info("Adding sub-package %s to existing import %s", subpkg, root) 126 } 127 } else { 128 msg.Warn("Package %q is already in glide.yaml. Skipping", root) 129 } 130 continue 131 } 132 133 if conf.HasIgnore(root) { 134 msg.Warn("Package %q is set to be ignored in glide.yaml. Skipping", root) 135 continue 136 } 137 138 dep := &cfg.Dependency{ 139 Name: root, 140 } 141 142 if version != "" { 143 dep.Reference = version 144 } 145 146 // When retriving from an insecure location set the repo to the 147 // insecure location. 148 if insecure { 149 dep.Repository = "http://" + root 150 } 151 152 if len(subpkg) > 0 { 153 dep.Subpackages = []string{subpkg} 154 } 155 156 if dep.Reference != "" { 157 msg.Info("Importing %s with the version %s", dep.Name, dep.Reference) 158 } else { 159 msg.Info("Importing %s", dep.Name) 160 } 161 162 conf.Imports = append(conf.Imports, dep) 163 } 164 return nil 165 }