Esempio n. 1
0
// CheckLatest checks whether this version of Helm is the latest version.
//
// This does not ensure that this is the latest. If a newer version is found,
// this generates a message indicating that.
//
// The passed-in version is the base version that will be checked against the
// remote release list.
func CheckLatest(version string) {
	ver, err := release.LatestVersion()
	if err != nil {
		log.Warn("Skipped Helm version check: %s", err)
		return
	}

	current, err := semver.NewVersion(version)
	if err != nil {
		log.Warn("Local version %s is not well-formed", version)
		return
	}
	remote, err := semver.NewVersion(ver)
	if err != nil {
		log.Warn("Remote version %s is not well-formed", ver)
		return
	}

	if remote.GreaterThan(current) {
		log.Warn("A new version of Helm is available. You have %s. The latest is %v", version, ver)
		if dl, err := release.LatestDownloadURL(); err == nil {
			log.Info("Download version %s here: %s", ver, dl)
		}
	}

}
Esempio n. 2
0
func (m *memCache) put(name, version string) {
	m.Lock()
	defer m.Unlock()
	m.t[name] = true
	sv, err := semver.NewVersion(version)
	if err != nil {
		msg.Debug("Ignoring %s version %s: %s", name, version, err)
		return
	}

	latest, found := m.latest[name]
	if found {
		lv, err := semver.NewVersion(latest)
		if err == nil {
			if sv.GreaterThan(lv) {
				m.latest[name] = version
			}
		}
	} else {
		m.latest[name] = version
	}

	found = false
	for _, v := range m.versions[name] {
		if v == version {
			found = true
		}
	}
	if !found {
		m.versions[name] = append(m.versions[name], version)
	}
}
Esempio n. 3
0
func versionEquals(v1, v2 string) bool {
	sv1, err := semver.NewVersion(v1)
	if err != nil {
		// Fallback to string comparison.
		return v1 == v2
	}
	sv2, err := semver.NewVersion(v2)
	if err != nil {
		return false
	}
	return sv1.Equal(sv2)
}
Esempio n. 4
0
File: index.go Progetto: slack/helm
// Less returns true if the version of entry a is less than the version of entry b.
func (c ChartVersions) Less(a, b int) bool {
	// Failed parse pushes to the back.
	i, err := semver.NewVersion(c[a].Version)
	if err != nil {
		return true
	}
	j, err := semver.NewVersion(c[b].Version)
	if err != nil {
		return false
	}
	return i.LessThan(j)
}
Esempio n. 5
0
func getWizard(dep *cfg.Dependency) {
	var remote string
	if dep.Repository != "" {
		remote = dep.Repository
	} else {
		remote = "https://" + dep.Name
	}

	// Lookup dependency info and store in cache.
	msg.Info("--> Gathering release information for %s", dep.Name)
	wizardFindVersions(dep)

	memlatest := cache.MemLatest(remote)
	if memlatest != "" {
		dres := wizardAskLatest(memlatest, dep)
		if dres {
			dep.Reference = memlatest

			sv, err := semver.NewVersion(dep.Reference)
			if err == nil {
				res := wizardAskRange(sv, dep)
				if res == "m" {
					dep.Reference = "^" + sv.String()
				} else if res == "p" {
					dep.Reference = "~" + sv.String()
				}
			}
		}
	}
}
Esempio n. 6
0
// Resolve resolves dependencies and returns a lock file with the resolution.
func (r *Resolver) Resolve(reqs *chartutil.Requirements) (*chartutil.RequirementsLock, error) {
	d, err := HashReq(reqs)
	if err != nil {
		return nil, err
	}

	// Now we clone the dependencies, locking as we go.
	locked := make([]*chartutil.Dependency, len(reqs.Dependencies))
	for i, d := range reqs.Dependencies {
		// Right now, we're just copying one entry to another. What we need to
		// do here is parse the requirement as a SemVer range, and then look up
		// whether a version in index.yaml satisfies this constraint. If so,
		// we need to clone the dep, setting Version appropriately.
		// If not, we need to error out.
		if _, err := semver.NewVersion(d.Version); err != nil {
			return nil, fmt.Errorf("dependency %q has an invalid version: %s", d.Name, err)
		}
		locked[i] = &chartutil.Dependency{
			Name:       d.Name,
			Repository: d.Repository,
			Version:    d.Version,
		}
	}

	return &chartutil.RequirementsLock{
		Generated:    time.Now(),
		Digest:       d,
		Dependencies: locked,
	}, nil
}
Esempio n. 7
0
func benchCheckVersion(c, v string, b *testing.B) {
	version, _ := semver.NewVersion(v)
	constraint, _ := semver.NewConstraint(c)

	for i := 0; i < b.N; i++ {
		constraint.Check(version)
	}
}
Esempio n. 8
0
func benchValidateVersion(c, v string, b *testing.B) {
	version, _ := semver.NewVersion(v)
	constraint, _ := semver.NewConstraint(c)

	for i := 0; i < b.N; i++ {
		constraint.Validate(version)
	}
}
Esempio n. 9
0
func (m *memCache) setCurrent(name, version string) {
	m.Lock()
	defer m.Unlock()

	if m.c[name] == "" {
		m.c[name] = version
	} else {
		// If we already have a version try to see if the new or old one is
		// semver and use that one.
		_, err := semver.NewVersion(m.c[name])
		if err != nil {
			_, err2 := semver.NewVersion(version)
			if err2 == nil {
				m.c[name] = version
			}
		}
	}
}
Esempio n. 10
0
// Resolve resolves dependencies and returns a lock file with the resolution.
func (r *Resolver) Resolve(reqs *chartutil.Requirements, repoNames map[string]string) (*chartutil.RequirementsLock, error) {
	d, err := HashReq(reqs)
	if err != nil {
		return nil, err
	}

	// Now we clone the dependencies, locking as we go.
	locked := make([]*chartutil.Dependency, len(reqs.Dependencies))
	missing := []string{}
	for i, d := range reqs.Dependencies {
		constraint, err := semver.NewConstraint(d.Version)
		if err != nil {
			return nil, fmt.Errorf("dependency %q has an invalid version/constraint format: %s", d.Name, err)
		}

		repoIndex, err := repo.LoadIndexFile(r.helmhome.CacheIndex(repoNames[d.Name]))
		if err != nil {
			return nil, fmt.Errorf("no cached repo found. (try 'helm repo update'). %s", err)
		}

		vs, ok := repoIndex.Entries[d.Name]
		if !ok {
			return nil, fmt.Errorf("%s chart not found in repo %s", d.Name, d.Repository)
		}

		locked[i] = &chartutil.Dependency{
			Name:       d.Name,
			Repository: d.Repository,
		}
		found := false
		// The version are already sorted and hence the first one to satisfy the constraint is used
		for _, ver := range vs {
			v, err := semver.NewVersion(ver.Version)
			if err != nil || len(ver.URLs) == 0 {
				// Not a legit entry.
				continue
			}
			if constraint.Check(v) {
				found = true
				locked[i].Version = v.Original()
				break
			}
		}

		if !found {
			missing = append(missing, d.Name)
		}
	}
	if len(missing) > 0 {
		return nil, fmt.Errorf("Can't get a valid version for repositories %s. Try changing the version constraint in requirements.yaml", strings.Join(missing, ", "))
	}
	return &chartutil.RequirementsLock{
		Generated:    time.Now(),
		Digest:       d,
		Dependencies: locked,
	}, nil
}
Esempio n. 11
0
// Filter a list of versions to only included semantic versions. The response
// is a mapping of the original version to the semantic version.
func getSemVers(refs []string) []*semver.Version {
	sv := []*semver.Version{}
	for _, r := range refs {
		v, err := semver.NewVersion(r)
		if err == nil {
			sv = append(sv, v)
		}
	}

	return sv
}
Esempio n. 12
0
// VersionOK returns true if the given version meets the constraints.
//
// It returns false if the version string or constraint is unparsable or if the
// version does not meet the constraint.
func (d *Dependency) VersionOK(version string) bool {
	c, err := semver.NewConstraint(d.Version)
	if err != nil {
		return false
	}
	v, err := semver.NewVersion(version)
	if err != nil {
		return false
	}

	return c.Check(v)
}
Esempio n. 13
0
// Less compares a to b, and returns true if a is less than b.
func (s scoreSorter) Less(a, b int) bool {
	first := s[a]
	second := s[b]

	if first.Score > second.Score {
		return false
	}
	if first.Score < second.Score {
		return true
	}
	if first.Name == second.Name {
		v1, err := semver.NewVersion(first.Chart.Version)
		if err != nil {
			return true
		}
		v2, err := semver.NewVersion(second.Chart.Version)
		if err != nil {
			return true
		}
		return v1.GreaterThan(v2)
	}
	return first.Name < second.Name
}
Esempio n. 14
0
// CheckLatest checks whether this version of Helm Classic is the latest version.
//
// This does not ensure that this is the latest. If a newer version is found,
// this generates a message indicating that.
//
// The passed-in version is the base version that will be checked against the
// remote release list.
func CheckLatest(version string) {
	ver, err := release.LatestVersion()
	if err != nil {
		log.Warn("Skipped Helm Classic version check: %s", err)
		return
	}

	current, err := semver.NewVersion(version)
	if err != nil {
		log.Warn("Local version %s is not well-formed", version)
		return
	}
	remote, err := semver.NewVersion(ver)
	if err != nil {
		log.Warn("Remote version %s is not well-formed", ver)
		return
	}

	if remote.GreaterThan(current) {
		log.Warn("A new version of Helm Classic is available. You have %s. The latest is %v", version, ver)
		log.Info("Download version %s by running: %s", ver, "curl -s https://get.helm.sh | bash")
	}

}
Esempio n. 15
0
func getSemverTags() []*semver.Version {
	rowTags := git("tag")

	tags := bytes.Split(rowTags, []byte("\n"))
	tags = tags[:len(tags)-1]

	vs := make([]*semver.Version, 0)

	for _, r := range tags {
		v, err := semver.NewVersion(string(r))
		if err == nil {
			vs = append(vs, v)
		}
	}

	sort.Sort(sort.Reverse(semver.Collection(vs)))
	return vs
}
Esempio n. 16
0
func validateChartVersion(cf *chart.Metadata) error {
	if cf.Version == "" {
		return errors.New("version is required")
	}

	version, err := semver.NewVersion(cf.Version)

	if err != nil {
		return fmt.Errorf("version '%s' is not a valid SemVer", cf.Version)
	}

	c, err := semver.NewConstraint("> 0")
	valid, msg := c.Validate(version)

	if !valid && len(msg) > 0 {
		return fmt.Errorf("version %v", msg[0])
	}

	return nil
}
Esempio n. 17
0
func validateChartVersion(cf *chart.Metadata) (lintError support.LintError) {
	if cf.Version == "" {
		lintError = fmt.Errorf("Chart.yaml: 'version' value is required")
		return
	}

	version, err := semver.NewVersion(cf.Version)

	if err != nil {
		lintError = fmt.Errorf("Chart.yaml: version '%s' is not a valid SemVer", cf.Version)
		return
	}

	c, err := semver.NewConstraint("> 0")
	valid, msg := c.Validate(version)

	if !valid && len(msg) > 0 {
		lintError = fmt.Errorf("Chart.yaml: 'version' %v", msg[0])
	}

	return
}
Esempio n. 18
0
// ConfigWizard reads configuration from a glide.yaml file and attempts to suggest
// improvements. The wizard is interactive.
func ConfigWizard(base string) {
	_, err := gpath.Glide()
	glidefile := gpath.GlideFile
	if err != nil {
		msg.Info("Unable to find a glide.yaml file. Would you like to create one now? Yes (Y) or No (N)")
		bres := msg.PromptUntilYorN()
		if bres {
			// Guess deps
			conf := guessDeps(base, false)
			// Write YAML
			if err := conf.WriteFile(glidefile); err != nil {
				msg.Die("Could not save %s: %s", glidefile, err)
			}
		} else {
			msg.Err("Unable to find configuration file. Please create configuration information to continue.")
		}
	}

	conf := EnsureConfig()

	err = cache.Setup()
	if err != nil {
		msg.Die("Problem setting up cache: %s", err)
	}

	msg.Info("Looking for dependencies to make suggestions on")
	msg.Info("--> Scanning for dependencies not using version ranges")
	msg.Info("--> Scanning for dependencies using commit ids")
	var deps []*cfg.Dependency
	for _, dep := range conf.Imports {
		if wizardLookInto(dep) {
			deps = append(deps, dep)
		}
	}
	for _, dep := range conf.DevImports {
		if wizardLookInto(dep) {
			deps = append(deps, dep)
		}
	}

	msg.Info("Gathering information on each dependency")
	msg.Info("--> This may take a moment. Especially on a codebase with many dependencies")
	msg.Info("--> Gathering release information for dependencies")
	msg.Info("--> Looking for dependency imports where versions are commit ids")
	for _, dep := range deps {
		wizardFindVersions(dep)
	}

	var changes int
	for _, dep := range deps {
		var remote string
		if dep.Repository != "" {
			remote = dep.Repository
		} else {
			remote = "https://" + dep.Name
		}

		// First check, ask if the tag should be used instead of the commit id for it.
		cur := cache.MemCurrent(remote)
		if cur != "" && cur != dep.Reference {
			wizardSugOnce()
			var dres bool
			asked, use, val := wizardOnce("current")
			if !use {
				dres = wizardAskCurrent(cur, dep)
			}
			if !asked {
				as := wizardRemember()
				wizardSetOnce("current", as, dres)
			}

			if asked && use {
				dres = val.(bool)
			}

			if dres {
				msg.Info("Updating %s to use the tag %s instead of commit id %s", dep.Name, cur, dep.Reference)
				dep.Reference = cur
				changes++
			}
		}

		// Second check, if no version is being used and there's a semver release ask about latest.
		memlatest := cache.MemLatest(remote)
		if dep.Reference == "" && memlatest != "" {
			wizardSugOnce()
			var dres bool
			asked, use, val := wizardOnce("latest")
			if !use {
				dres = wizardAskLatest(memlatest, dep)
			}
			if !asked {
				as := wizardRemember()
				wizardSetOnce("latest", as, dres)
			}

			if asked && use {
				dres = val.(bool)
			}

			if dres {
				msg.Info("Updating %s to use the release %s instead of no release", dep.Name, memlatest)
				dep.Reference = memlatest
				changes++
			}
		}

		// Third check, if the version is semver offer to use a range instead.
		sv, err := semver.NewVersion(dep.Reference)
		if err == nil {
			wizardSugOnce()
			var res string
			asked, use, val := wizardOnce("range")
			if !use {
				res = wizardAskRange(sv, dep)
			}
			if !asked {
				as := wizardRemember()
				wizardSetOnce("range", as, res)
			}

			if asked && use {
				res = val.(string)
			}

			if res == "m" {
				r := "^" + sv.String()
				msg.Info("Updating %s to use the range %s instead of commit id %s", dep.Name, r, dep.Reference)
				dep.Reference = r
				changes++
			} else if res == "p" {
				r := "~" + sv.String()
				msg.Info("Updating %s to use the range %s instead of commit id %s", dep.Name, r, dep.Reference)
				dep.Reference = r
				changes++
			}
		}
	}

	if changes > 0 {
		msg.Info("Configuration changes have been made. Would you like to write these")
		msg.Info("changes to your configuration file? Yes (Y) or No (N)")
		dres := msg.PromptUntilYorN()
		if dres {
			msg.Info("Writing updates to configuration file (%s)", glidefile)
			if err := conf.WriteFile(glidefile); err != nil {
				msg.Die("Could not save %s: %s", glidefile, err)
			}
			msg.Info("You can now edit the glide.yaml file.:")
			msg.Info("--> For more information on versions and ranges see https://glide.sh/docs/versions/")
			msg.Info("--> For details on additional metadata see https://glide.sh/docs/glide.yaml/")
		} else {
			msg.Warn("Change not written to configuration file")
		}
	} else {
		msg.Info("No proposed changes found. Have a nice day.")
	}
}
Esempio n. 19
0
func determineDependency(v, dep *cfg.Dependency, dest string) *cfg.Dependency {
	repo, err := v.GetRepo(dest)
	if err != nil {
		singleWarn("Unable to access repo for %s\n", v.Name)
		singleInfo("Keeping %s %s", v.Name, v.Reference)
		return v
	}

	vIsRef := repo.IsReference(v.Reference)
	depIsRef := repo.IsReference(dep.Reference)

	// Both are references and they are different ones.
	if vIsRef && depIsRef {
		singleWarn("Conflict: %s ref is %s, but also asked for %s\n", v.Name, v.Reference, dep.Reference)
		singleInfo("Keeping %s %s", v.Name, v.Reference)
		return v
	} else if vIsRef {
		// The current one is a reference and the suggestion is a SemVer constraint.
		con, err := semver.NewConstraint(dep.Reference)
		if err != nil {
			singleWarn("Version issue for %s: '%s' is neither a reference or semantic version constraint\n", dep.Name, dep.Reference)
			singleInfo("Keeping %s %s", v.Name, v.Reference)
			return v
		}

		ver, err := semver.NewVersion(v.Reference)
		if err != nil {
			// The existing version is not a semantic version.
			singleWarn("Conflict: %s version is %s, but also asked for %s\n", v.Name, v.Reference, dep.Reference)
			singleInfo("Keeping %s %s", v.Name, v.Reference)
			return v
		}

		if con.Check(ver) {
			singleInfo("Keeping %s %s because it fits constraint '%s'", v.Name, v.Reference, dep.Reference)
			return v
		}
		singleWarn("Conflict: %s version is %s but does not meet constraint '%s'\n", v.Name, v.Reference, dep.Reference)
		singleInfo("Keeping %s %s", v.Name, v.Reference)
		return v
	} else if depIsRef {

		con, err := semver.NewConstraint(v.Reference)
		if err != nil {
			singleWarn("Version issue for %s: '%s' is neither a reference or semantic version constraint\n", v.Name, v.Reference)
			singleInfo("Keeping %s %s", v.Name, v.Reference)
			return v
		}

		ver, err := semver.NewVersion(dep.Reference)
		if err != nil {
			singleWarn("Conflict: %s version is %s, but also asked for %s\n", v.Name, v.Reference, dep.Reference)
			singleInfo("Keeping %s %s", v.Name, v.Reference)
			return v
		}

		if con.Check(ver) {
			v.Reference = dep.Reference
			singleInfo("Using %s %s because it fits constraint '%s'", v.Name, v.Reference, v.Reference)
			return v
		}
		singleWarn("Conflict: %s semantic version constraint is %s but '%s' does not meet the constraint\n", v.Name, v.Reference, v.Reference)
		singleInfo("Keeping %s %s", v.Name, v.Reference)
		return v
	}
	// Neither is a vcs reference and both could be semantic version
	// constraints that are different.

	_, err = semver.NewConstraint(dep.Reference)
	if err != nil {
		// dd.Reference is not a reference or a valid constraint.
		singleWarn("Version %s %s is not a reference or valid semantic version constraint\n", dep.Name, dep.Reference)
		singleInfo("Keeping %s %s", v.Name, v.Reference)
		return v
	}

	_, err = semver.NewConstraint(v.Reference)
	if err != nil {
		// existing.Reference is not a reference or a valid constraint.
		// We really should never end up here.
		singleWarn("Version %s %s is not a reference or valid semantic version constraint\n", v.Name, v.Reference)

		v.Reference = dep.Reference
		v.Pin = ""
		singleInfo("Using %s %s because it is a valid version", v.Name, v.Reference)
		return v
	}

	// Both versions are constraints. Try to merge them.
	// If either comparison has an || skip merging. That's complicated.
	ddor := strings.Index(dep.Reference, "||")
	eor := strings.Index(v.Reference, "||")
	if ddor == -1 && eor == -1 {
		// Add the comparisons together.
		newRef := v.Reference + ", " + dep.Reference
		v.Reference = newRef
		v.Pin = ""
		singleInfo("Combining %s semantic version constraints %s and %s", v.Name, v.Reference, dep.Reference)
		return v
	}
	singleWarn("Conflict: %s version is %s, but also asked for %s\n", v.Name, v.Reference, dep.Reference)
	singleInfo("Keeping %s %s", v.Name, v.Reference)
	return v
}
Esempio n. 20
0
// mergeDeps merges any dependency array into deps.
func mergeDeps(orig map[string]*yaml.Dependency, add []*yaml.Dependency, vend string) []string {
	mod := []string{}
	for _, dd := range add {
		// Add it unless it's already there.
		if existing, ok := orig[dd.Name]; !ok {
			orig[dd.Name] = dd
			Debug("Adding %s to the scan list", dd.Name)
			mod = append(mod, dd.Name)
		} else if existing.Reference == "" && dd.Reference != "" {
			// If a nested dep has finer dependency references than outside,
			// set the reference.
			existing.Reference = dd.Reference
			mod = append(mod, dd.Name)
		} else if dd.Reference != "" && existing.Reference != "" && dd.Reference != existing.Reference {
			// Check if one is a version and the other is a constraint. If the
			// version is in the constraint use that.
			dest := path.Join(vend, dd.Name)
			repo, err := existing.GetRepo(dest)
			if err != nil {
				Warn("Unable to access repo for %s\n", existing.Name)
				Info("Keeping %s %s", existing.Name, existing.Reference)
				continue
			}

			eIsRef := repo.IsReference(existing.Reference)
			ddIsRef := repo.IsReference(dd.Reference)

			// Both are references and different ones.
			if eIsRef && ddIsRef {
				Warn("Conflict: %s ref is %s, but also asked for %s\n", existing.Name, existing.Reference, dd.Reference)
				Info("Keeping %s %s", existing.Name, existing.Reference)
			} else if eIsRef {
				// Test ddIsRef is a constraint and if eIsRef is a semver
				// within that
				con, err := semver.NewConstraint(dd.Reference)
				if err != nil {
					Warn("Version issue for %s: '%s' is neither a reference or semantic version constraint\n", dd.Name, dd.Reference)
					Info("Keeping %s %s", existing.Name, existing.Reference)
					continue
				}

				ver, err := semver.NewVersion(existing.Reference)
				if err != nil {
					// The existing version is not a semantic version.
					Warn("Conflict: %s version is %s, but also asked for %s\n", existing.Name, existing.Reference, dd.Reference)
					Info("Keeping %s %s", existing.Name, existing.Reference)
					continue
				}

				if con.Check(ver) {
					Info("Keeping %s %s because it fits constraint '%s'", existing.Name, existing.Reference, dd.Reference)
				} else {
					Warn("Conflict: %s version is %s but does not meet constraint '%s'\n", existing.Name, existing.Reference, dd.Reference)
					Info("Keeping %s %s", existing.Name, existing.Reference)
				}

			} else if ddIsRef {
				// Test eIsRef is a constraint and if ddIsRef is a semver
				// within that
				con, err := semver.NewConstraint(existing.Reference)
				if err != nil {
					Warn("Version issue for %s: '%s' is neither a reference or semantic version constraint\n", existing.Name, existing.Reference)
					Info("Keeping %s %s", existing.Name, existing.Reference)
					continue
				}

				ver, err := semver.NewVersion(dd.Reference)
				if err != nil {
					// The dd version is not a semantic version.
					Warn("Conflict: %s version is %s, but also asked for %s\n", existing.Name, existing.Reference, dd.Reference)
					Info("Keeping %s %s", existing.Name, existing.Reference)
					continue
				}

				if con.Check(ver) {
					// Use the specific version if noted instead of the existing
					// constraint.
					existing.Reference = dd.Reference
					mod = append(mod, dd.Name)
					Info("Using %s %s because it fits constraint '%s'", existing.Name, dd.Reference, existing.Reference)
				} else {
					Warn("Conflict: %s semantic version constraint is %s but '%s' does not meet the constraint\n", existing.Name, existing.Reference, dd.Reference)
					Info("Keeping %s %s", existing.Name, existing.Reference)
				}
			} else {
				// Neither is a vcs reference and both could be semantic version
				// constraints that are different.

				_, err := semver.NewConstraint(dd.Reference)
				if err != nil {
					// dd.Reference is not a reference or a valid constraint.
					Warn("Version %s %s is not a reference or valid semantic version constraint\n", dd.Name, dd.Reference)
					Info("Keeping %s %s", existing.Name, existing.Reference)
					continue
				}

				_, err = semver.NewConstraint(existing.Reference)
				if err != nil {
					// existing.Reference is not a reference or a valid constraint.
					// We really should never end up here.
					Warn("Version %s %s is not a reference or valid semantic version constraint\n", existing.Name, existing.Reference)

					existing.Reference = dd.Reference
					mod = append(mod, dd.Name)
					Info("Using %s %s because it is a valid version", existing.Name, existing.Reference)
					continue
				}

				// Both versions are constraints. Try to merge them.
				// If either comparison has an || skip merging. That's complicated.
				ddor := strings.Index(dd.Reference, "||")
				eor := strings.Index(existing.Reference, "||")
				if ddor == -1 && eor == -1 {
					// Add the comparisons together.
					newRef := existing.Reference + ", " + dd.Reference
					existing.Reference = newRef
					mod = append(mod, dd.Name)
					Info("Combining %s semantic version constraints %s and %s", existing.Name, existing.Reference, dd.Reference)
				} else {
					Warn("Conflict: %s version is %s, but also asked for %s\n", existing.Name, existing.Reference, dd.Reference)
					Info("Keeping %s %s", existing.Name, existing.Reference)
				}
			}
		}
	}
	return mod
}
Esempio n. 21
0
func benchNewVersion(v string, b *testing.B) {
	for i := 0; i < b.N; i++ {
		semver.NewVersion(v)
	}
}