Пример #1
0
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
}
Пример #2
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
}
Пример #3
0
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
}