|  | package cmd | 
|  |  | 
|  | import ( | 
|  | "errors" | 
|  | "fmt" | 
|  | "io/ioutil" | 
|  | "os" | 
|  | "sync" | 
|  |  | 
|  | "github.com/Masterminds/cookoo" | 
|  | "github.com/Masterminds/glide/cfg" | 
|  | ) | 
|  |  | 
|  | // LockFileExists checks if a lock file exists. If not it jumps to the update | 
|  | // command. | 
|  | func LockFileExists(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) { | 
|  | fname := p.Get("filename", "glide.lock").(string) | 
|  | if _, err := os.Stat(fname); err != nil { | 
|  | Info("Lock file (glide.lock) does not exist. Performing update.") | 
|  | return false, &cookoo.Reroute{"update"} | 
|  | } | 
|  |  | 
|  | return true, nil | 
|  | } | 
|  |  | 
|  | // LoadLockFile loads the lock file to the context and checks if it is correct | 
|  | // for the loaded cfg file. | 
|  | func LoadLockFile(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) { | 
|  | fname := p.Get("filename", "glide.lock").(string) | 
|  | conf := p.Get("conf", nil).(*cfg.Config) | 
|  |  | 
|  | yml, err := ioutil.ReadFile(fname) | 
|  | if err != nil { | 
|  | return nil, err | 
|  | } | 
|  | lock, err := cfg.LockfileFromYaml(yml) | 
|  | if err != nil { | 
|  | return nil, err | 
|  | } | 
|  |  | 
|  | hash, err := conf.Hash() | 
|  | if err != nil { | 
|  | return nil, err | 
|  | } | 
|  |  | 
|  | Warn("Lockfile hash: %s", lock.Hash) | 
|  | Warn("glide.yaml generated hash: %s", hash) | 
|  | y, _ := conf.Marshal() | 
|  | fmt.Println(y) | 
|  |  | 
|  | if hash != lock.Hash { | 
|  | return nil, errors.New("Lock file does not match YAML configuration. Consider running 'update'") | 
|  | } | 
|  |  | 
|  | return lock, nil | 
|  | } | 
|  |  | 
|  | // Install installs the dependencies from a Lockfile. | 
|  | func Install(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) { | 
|  | lock := p.Get("lock", nil).(*cfg.Lockfile) | 
|  | conf := p.Get("conf", nil).(*cfg.Config) | 
|  | force := p.Get("force", true).(bool) | 
|  | home := p.Get("home", "").(string) | 
|  | cache := p.Get("cache", false).(bool) | 
|  | cacheGopath := p.Get("cacheGopath", false).(bool) | 
|  | useGopath := p.Get("useGopath", false).(bool) | 
|  |  | 
|  | cwd, err := VendorPath(c) | 
|  | if err != nil { | 
|  | return false, err | 
|  | } | 
|  |  | 
|  | // Create a config setup based on the Lockfile data to process with | 
|  | // existing commands. | 
|  | newConf := &cfg.Config{} | 
|  | newConf.Name = conf.Name | 
|  |  | 
|  | newConf.Imports = make(cfg.Dependencies, len(lock.Imports)) | 
|  | for k, v := range lock.Imports { | 
|  | newConf.Imports[k] = &cfg.Dependency{ | 
|  | Name:        v.Name, | 
|  | Reference:   v.Version, | 
|  | Repository:  v.Repository, | 
|  | VcsType:     v.VcsType, | 
|  | Subpackages: v.Subpackages, | 
|  | Arch:        v.Arch, | 
|  | Os:          v.Os, | 
|  | } | 
|  | } | 
|  |  | 
|  | newConf.DevImports = make(cfg.Dependencies, len(lock.DevImports)) | 
|  | for k, v := range lock.DevImports { | 
|  | newConf.DevImports[k] = &cfg.Dependency{ | 
|  | Name:        v.Name, | 
|  | Reference:   v.Version, | 
|  | Repository:  v.Repository, | 
|  | VcsType:     v.VcsType, | 
|  | Subpackages: v.Subpackages, | 
|  | Arch:        v.Arch, | 
|  | Os:          v.Os, | 
|  | } | 
|  | } | 
|  |  | 
|  | newConf.DeDupe() | 
|  |  | 
|  | if len(newConf.Imports) == 0 { | 
|  | Info("No dependencies found. Nothing installed.\n") | 
|  | return false, nil | 
|  | } | 
|  |  | 
|  | // for _, dep := range newConf.Imports { | 
|  | // 	if err := VcsUpdate(dep, cwd, home, force, cache, cacheGopath, useGopath); err != nil { | 
|  | // 		Warn("Update failed for %s: %s\n", dep.Name, err) | 
|  | // 	} | 
|  | // } | 
|  |  | 
|  | done := make(chan struct{}, concurrentWorkers) | 
|  | in := make(chan *cfg.Dependency, concurrentWorkers) | 
|  | var wg sync.WaitGroup | 
|  |  | 
|  | for i := 0; i < concurrentWorkers; i++ { | 
|  | go func(ch <-chan *cfg.Dependency) { | 
|  | for { | 
|  | select { | 
|  | case dep := <-ch: | 
|  | if err := VcsUpdate(dep, cwd, home, force, cache, cacheGopath, useGopath); err != nil { | 
|  | Warn("Update failed for %s: %s\n", dep.Name, err) | 
|  | } | 
|  | wg.Done() | 
|  | case <-done: | 
|  | return | 
|  | } | 
|  | } | 
|  | }(in) | 
|  | } | 
|  |  | 
|  | for _, dep := range newConf.Imports { | 
|  | wg.Add(1) | 
|  | in <- dep | 
|  | } | 
|  |  | 
|  | wg.Wait() | 
|  | // Close goroutines setting the version | 
|  | for i := 0; i < concurrentWorkers; i++ { | 
|  | done <- struct{}{} | 
|  | } | 
|  |  | 
|  | return newConf, nil | 
|  | } |