func NewDependency(importStr string, urlStr string, versionStr string) (*Dependency, error) { var err error dep := &Dependency{ Import: importStr, } if urlStr == "" { dep.Url = nil } else if dep.Url, err = url.Parse(urlStr); err != nil { return nil, err } else if dep.Url.Scheme == "" { return nil, fmt.Errorf("Url must have a scheme specified.") } if versionStr == "" { dep.VersionSpec = NewVersionSpec(OpEq, -1, -1, -1) } else if dep.VersionSpec, err = ParseVersionSpec(versionStr); err != nil { return nil, err } // figure out import from URL if not set if dep.Import == "" { if dep.Url == nil { return nil, fmt.Errorf("Must have an 'import' or 'url' specified") } else { dep.Import = dep.Url.Host + "/" + dep.Url.Path } } return dep, nil }
func (self *Dependency) SetValues(valueMap map[string]string) error { for _, key := range []string{"import", "type", "branch", "tag", "url", "scheme", "host", "path", "port"} { value, ok := valueMap[key] if !ok { continue // value not in map } // set the value switch key { case "import": self.Import = value case "type": self.Type = value case "branch": self.Branch = value case "tag": self.Tag = value case "url": if urlValue, err := url.Parse(value); err != nil { return fmt.Errorf("Error setting dependency url: %v", err) } else { self.Url = urlValue } } if self.Url != nil { switch key { case "scheme": self.Url.Scheme = value case "host": self.Url.Host = value case "path": self.Url.Path = value case "port": self.Url.Port = value } } else { switch key { case "scheme": self.Url = &url.URL{Scheme: value} case "host": self.Url = &url.URL{Host: value} case "path": self.Url = &url.URL{Path: value} case "port": self.Url = &url.URL{Port: value} } } } return 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 }