Example #1
0
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
}
Example #2
0
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
}
Example #3
0
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
}