func (self *RunContext) Run(cmd string, args ...string) error { cmdObj := exec.Command(cmd, args...) cmdObj.Dir = self.WorkingDirectory log.Debug("%v %v", cmd, args) out, err := cmdObj.CombinedOutput() self.CombinedOutput = string(out) if err != nil { if _, ok := err.(*exec.ExitError); ok { log.Error("%s", out) } else { log.Error("%s", err.Error()) } } return err }
// resolve all dependencies against configuration func (self *Resolver) ResolveDependencies(deps []*Dependency) ([]*Library, error) { masterLibs := []*Library{} resolved := map[string]*Library{} results := make(chan *Library) errors := make(chan error) workQueue := deps for len(workQueue) > 0 { // de-duplicate the queue var err error if workQueue, err = self.DeduplicateDeps(workQueue); err != nil { return nil, err } // look for already resolved deps that may match if workQueue, err = self.LibResolveDeps(resolved, workQueue); err != nil { return nil, err } // spawn goroutines for each dependency to be resolved for _, dep := range workQueue { go func(dep *Dependency) { lib, err := self.Resolve(dep) if err != nil { errors <- err } else { results <- lib } }(dep) } // wait on all goroutines to finish or fail tempQueue := make([]*Dependency, 0) failed := false for ii := 0; ii < len(workQueue); ii++ { log.Debug("working on %s of %s", ii, len(workQueue)) select { case lib := <-results: log.Debug("Reconciled library: %s", lib.Import) resolved[lib.Import] = lib masterLibs = append(masterLibs, lib) for _, importPath := range lib.Provides { log.Debug("Submodule: %s", importPath) resolved[importPath] = lib } tempQueue = append(tempQueue, lib.Dependencies...) case err := <-errors: log.Error(err) failed = true } } if failed { return nil, fmt.Errorf("One or more errors while resolving dependencies.") } workQueue = tempQueue } return masterLibs, nil }
func GrapnelMain() { log.SetFlags(0) rootCmd.Help = fmt.Sprintf("Defaults:\n") + fmt.Sprintf(" Lock file = %s\n", defaultLockFileName) + fmt.Sprintf(" Package file = %s\n", defaultPackageFileName) + fmt.Sprintf(" Config file path = %s\n", strings.Join(configFilePath, ", ")+ "\n"+rootCmd.Help) if err := rootCmd.Execute(os.Args...); err != nil { log.Error(err) rootCmd.ShowHelp(os.Args[0]) } }
func updateFn(cmd *Command, args []string) error { configureLogging() if len(args) > 0 { return fmt.Errorf("Too many arguments for 'update'") } // set unset paramters to the defaults if packageFileName == "" { packageFileName = defaultPackageFileName if lockFileName == "" { // set to default iff there was no package filename set lockFileName = defaultLockFileName } } else if lockFileName == "" { // compose a new lock file path out of the old package path lockFileName = path.Join(path.Dir(packageFileName), "grapnel-lock.toml") } if targetPath == "" { targetPath = defaultTargetPath } log.Debug("package file: %v", packageFileName) log.Debug("lock file: %v", lockFileName) log.Debug("target path: %v", targetPath) // get dependencies from the grapnel file log.Info("loading package file: '%s'", packageFileName) deplist, err := LoadGrapnelDepsfile(packageFileName) if err != nil { return err } else if deplist == nil { // TODO: fail over to update instead? return fmt.Errorf("Cannot open grapnel file: '%s'", packageFileName) } log.Info("loaded %d dependency definitions", len(deplist)) // open it now before we expend any real effort lockFile, err := os.Create(lockFileName) defer lockFile.Close() if err != nil { log.Error("Cannot open lock file: '%s'", lockFileName) return err } log.Info("installing to: %v", targetPath) if err := os.MkdirAll(targetPath, 0755); err != nil { return err } libs := []*Library{} // cleanup defer func() { for _, lib := range libs { lib.Destroy() } }() // resolve all the dependencies resolver, err := getResolver() if err != nil { return err } libs, err = resolver.ResolveDependencies(deplist) if err != nil { return err } // install all the dependencies log.Info("Resolved %v dependencies. Installing.", len(libs)) resolver.InstallLibraries(targetPath, libs) // write the library data out log.Info("Writing lock file") for _, lib := range libs { lib.ToToml(lockFile) } if createDsd { log.Info("Writing dsd file") dsdFileName := path.Join(path.Dir(lockFileName), "grapnel-dsd.sh") if err := resolver.ToDsd(dsdFileName, libs); err != nil { return err } } log.Info("Update complete") return nil }