func getResolver() (*Resolver, error) { resolver := NewResolver() resolver.LibSources["git"] = &GitSCM{} resolver.LibSources["archive"] = &ArchiveSCM{} resolver.AddRewriteRules(BasicRewriteRules) resolver.AddRewriteRules(GitRewriteRules) resolver.AddRewriteRules(ArchiveRewriteRules) // find/validate configuration file if configFileName != "" { if !Exists(configFileName) { return nil, fmt.Errorf("could not locate config file: %s", configFileName) } } else { // search in standard locations for _, item := range configFilePath { path, err := AbsolutePath(item) if err != nil { return nil, err } if Exists(path) { configFileName = path break } } // warn and exit here if we can't locate on the search path if configFileName == "" { log.Warn("Could not locate .grapnelrc file; continuing.") return resolver, nil } } // load the rules from the config file log.Debug("Loading %s", configFileName) if rules, err := LoadRewriteRules(configFileName); err != nil { return nil, err } else { resolver.AddRewriteRules(rules) } return resolver, nil }
func (self *GitSCM) Resolve(dep *Dependency) (*Library, error) { lib := NewLibrary(dep) // fix the tag, and default branch if lib.Branch == "" { lib.Branch = "master" } if lib.Tag == "" { lib.Tag = "HEAD" } log.Info("Fetching Git Dependency: '%s'", lib.Import) // create a dedicated directory and a context for commands tempRoot, err := ioutil.TempDir("", "") if err != nil { return nil, err } lib.TempDir = tempRoot cmd := NewRunContext(tempRoot) // use the configured url and acquire the depified branch log.Info("Fetching remote data for %s", lib.Import) if lib.Url == nil { // try all supported protocols against a URL composed from the import for _, protocol := range []string{"http", "https", "git", "ssh"} { packageUrl := protocol + "://" + lib.Import log.Warn("Synthesizing url from import: '%s'", packageUrl) if err := cmd.Run("git", "clone", packageUrl, "-b", lib.Branch, tempRoot); err != nil { log.Warn("Failed to fetch: '%s'", packageUrl) continue } lib.Url, _ = url.Parse(packageUrl) // pin URL break } if err != nil { return nil, fmt.Errorf("Cannot download dependency: '%s'", lib.Import) } } else if err := cmd.Run("git", "clone", lib.Url.String(), "-b", lib.Branch, tempRoot); err != nil { return nil, fmt.Errorf("Cannot download dependency: '%s'", lib.Url.String()) } // move to the specified commit/tag/hash // check out a depific commit - may be a tag, commit hash or HEAD if err := cmd.Run("git", "checkout", lib.Tag); err != nil { return nil, fmt.Errorf("Failed to checkout tag: '%s'", lib.Tag) } // Pin the Tag to a commit hash if we just have "HEAD" as the 'Tag' if lib.Tag == "HEAD" { if err := cmd.Run("git", "rev-list", "--all", "--max-count=1"); err != nil { return nil, fmt.Errorf("Failed to checkout tag: '%s'", lib.Tag) } else { lib.Tag = strings.TrimSpace(cmd.CombinedOutput) } } // Stop now if we have no semantic version information if lib.VersionSpec.IsUnversioned() { lib.Version = NewVersion(-1, -1, -1) log.Warn("Resolved: %v (unversioned)", lib.Import) stripGitRepo(lib.TempDir) return lib, nil } // find latest version match if err := cmd.Run("git", "for-each-ref", "refs/tags", "--sort=taggerdate", "--format=%(refname:short)"); err != nil { return nil, fmt.Errorf("Failed to acquire ref list for depenency") } else { for _, line := range strings.Split(cmd.CombinedOutput, "\n") { log.Debug("%v", line) if ver, err := ParseVersion(line); err == nil { log.Debug("ver: %v", ver) if dep.VersionSpec.IsSatisfiedBy(ver) { lib.Tag = line lib.Version = ver // move to this tag in the history if err := cmd.Run("git", "checkout", lib.Tag); err != nil { return nil, fmt.Errorf("Failed to checkout tag: '%s'", lib.Tag) } break } } else { log.Debug("Parse git tag err: %v", err) } } } // fail if the tag cannot be determined. if lib.Version == nil { return nil, fmt.Errorf("Cannot find a tag for dependency version specification: %v.", lib.VersionSpec) } log.Info("Resolved: %s %v", lib.Import, lib.Version) stripGitRepo(lib.TempDir) return lib, nil }
func (self *ArchiveSCM) Resolve(dep *Dependency) (*Library, error) { lib := NewLibrary(dep) // create a dedicated directory and a context for commands tempRoot, err := ioutil.TempDir("", "") if err != nil { return nil, err } lib.TempDir = tempRoot cmd := NewRunContext(tempRoot) // prep archive file for write filename := filepath.Join(tempRoot, filepath.Base(lib.Dependency.Url.Path)) file, err := os.OpenFile(filename, os.O_CREATE, 0) if err != nil { return nil, fmt.Errorf("Cannot open archive for writing: %v", err) } defer file.Close() // get the targeted archive response, err := http.Get(lib.Dependency.Url.String()) if err != nil { return nil, fmt.Errorf("Cannot download archive: %v", err) } if err := response.Write(file); err != nil { return nil, fmt.Errorf("Cannot write archive: %v", err) } file.Close() log.Info("Wrote: %s", filename) // extract the file // TODO: change to using built-in libraries whenever possible. switch filepath.Ext(filename) { case "zip": cmd.Run("unzip", filename) case "tar.gz": cmd.Run("tar", "xzf", filename) case "tar": cmd.Run("tar", "xf", filename) } os.Remove(filename) // Stop now if we have no semantic version information if lib.VersionSpec.IsUnversioned() { lib.Version = NewVersion(-1, -1, -1) log.Warn("Resolved: %v (unversioned)", lib.Import) return lib, nil } // get the version number from the filename if ver, err := ParseVersion(filepath.Base(filename)); err == nil { log.Debug("ver: %v", ver) if dep.VersionSpec.IsSatisfiedBy(ver) { lib.Version = ver } } else { log.Debug("Parse archive version err: %v", err) } // fail if the tag cannot be determined. if lib.Version == nil { return nil, fmt.Errorf("Cannot find a version specification on archive: %v.", lib.VersionSpec) } log.Info("Resolved: %s %v", lib.Import, lib.Version) return lib, nil }