示例#1
0
func appendConstraint(constraints *versionConstraint, cons string) {
	if constraintPresent(*constraints, cons) {
		return
	}
	newcon, _ := gversion.NewConstraint(cons)
	*constraints = append(*constraints, newcon...)
}
示例#2
0
func (cbv *CookbookVersion) getDependencies(g *depgraph.Graph, nodes map[string]*depgraph.Noun, cbShelf map[string]*Cookbook) {
	depList := cbv.Metadata["dependencies"].(map[string]interface{})
	for r, c2 := range depList {
		if _, ok := nodes[r]; ok {
			if nodes[r].Meta.(*depMeta).noVersion || nodes[r].Meta.(*depMeta).notFound {
				continue
			}
		}
		c := c2.(string)
		var depCb *Cookbook
		var err util.Gerror
		var found bool

		if _, ok := nodes[r]; !ok {
			nodes[r] = &depgraph.Noun{Name: r, Meta: &depMeta{}}
		}
		dep, depPos, dt := checkDependency(nodes[cbv.CookbookName], r)
		if dep == nil {
			dep = &depgraph.Dependency{Name: fmt.Sprintf("%s-%s", cbv.CookbookName, r), Source: nodes[cbv.CookbookName], Target: nodes[r]}
		}
		depCons, _ := gversion.NewConstraint(c)
		dep.Constraints = []depgraph.Constraint{versionConstraint(depCons)}
		if !dt || nodes[cbv.CookbookName].Deps == nil {
			nodes[cbv.CookbookName].Deps = append(nodes[cbv.CookbookName].Deps, dep)
		} else {
			nodes[cbv.CookbookName].Deps[depPos] = dep
		}

		if depCb, found = cbShelf[r]; !found {
			depCb, err = Get(r)
			if err != nil {
				nodes[r].Meta.(*depMeta).notFound = true
				appendConstraint(&nodes[r].Meta.(*depMeta).constraint, c)
				continue
			}
		} else {
			// see if this constraint and a dependency for this
			// cookbook is already in place. If it is, go ahead and
			// move along, we've already been here.
			if dt && constraintPresent(nodes[r].Meta.(*depMeta).constraint, c) {
				continue
			}
		}
		appendConstraint(&nodes[r].Meta.(*depMeta).constraint, c)

		cbShelf[r] = depCb
		depCbv := depCb.latestMultiConstraint(nodes[r].Meta.(*depMeta).constraint)
		if depCbv == nil {
			nodes[r].Meta.(*depMeta).noVersion = true
			continue
		}
		if nodes[r].Meta.(*depMeta).version != "" && nodes[r].Meta.(*depMeta).version != depCbv.Version {
			// Remove any dependencies for this cookbook's node.
			// They'll be filled in
			nodes[r].Deps = make([]*depgraph.Dependency, 0)
		}

		nodes[r].Meta.(*depMeta).version = depCbv.Version

		depCbv.getDependencies(g, nodes, cbShelf)
	}
}
示例#3
0
// DependsCookbooks will, for the given run list and environment constraints,
// return the cookbook dependencies.
func DependsCookbooks(runList []string, envConstraints map[string]string) (map[string]interface{}, error) {
	nodes := make(map[string]*depgraph.Noun)
	runListRef := make([]string, len(runList))

	for i, cbV := range runList {
		var cbName string
		var constraint string
		cx := strings.Split(cbV, "@")
		cbName = strings.Split(cx[0], "::")[0]
		if len(cx) == 2 {
			constraint = fmt.Sprintf("= %s", cx[1])
		}
		nodes[cbName] = &depgraph.Noun{Name: cbName}
		meta := &depMeta{}
		if constraint != "" {
			q, _ := gversion.NewConstraint(constraint)
			meta.constraint = versionConstraint(q)
		}
		nodes[cbName].Meta = meta
		runListRef[i] = cbName
	}

	for k, ec := range envConstraints {
		if _, found := nodes[k]; !found {
			continue
		}
		appendConstraint(&nodes[k].Meta.(*depMeta).constraint, ec)
	}

	graphRoot := &depgraph.Noun{Name: "^runlist_root^"}
	g := &depgraph.Graph{Name: "runlist", Root: graphRoot}

	// fill in constraints for runlist deps now
	for k, n := range nodes {
		d := &depgraph.Dependency{Name: fmt.Sprintf("%s-%s", g.Name, k), Source: graphRoot, Target: n, Constraints: []depgraph.Constraint{versionConstraint(n.Meta.(*depMeta).constraint)}}
		graphRoot.Deps = append(graphRoot.Deps, d)
	}

	cbShelf := make(map[string]*Cookbook)
	for _, cbName := range runListRef {
		if _, found := cbShelf[cbName]; found || nodes[cbName].Meta.(*depMeta).notFound {
			continue
		}
		cb, err := Get(cbName)
		if err != nil {
			nodes[cbName].Meta.(*depMeta).notFound = true
			continue
		}
		cbShelf[cbName] = cb
		cbv := cb.latestMultiConstraint(nodes[cbName].Meta.(*depMeta).constraint)
		if cbv == nil {
			nodes[cbName].Meta.(*depMeta).noVersion = true
			continue
		}
		nodes[cbName].Meta.(*depMeta).version = cbv.Version
		cbv.getDependencies(g, nodes, cbShelf)
	}
	nouns := make([]*depgraph.Noun, 1)
	nouns[0] = graphRoot
	g.Nouns = nouns

	cerr := g.CheckConstraints()

	if cerr != nil {
		err := &DependsError{cerr.(*depgraph.ConstraintError)}
		return nil, err
	}

	cookbookDeps := make(map[string]interface{}, len(cbShelf))
	for k, c := range cbShelf {
		constraints := nodes[k].Meta.(*depMeta).constraint
		cbv := c.latestMultiConstraint(constraints)
		if cbv == nil {
			err := fmt.Errorf("Somehow, and this shouldn't have beenable to happen at this stage, no versions of %s satisfied the constraints '%s'!", c.Name, constraints.String())
			return nil, err
		}
		gcbvJSON := cbv.ToJSON("POST")

		for _, cd := range chkDiv {
			if gcbvJSON[cd] == nil {
				gcbvJSON[cd] = make([]map[string]interface{}, 0)
			}
		}
		cookbookDeps[cbv.CookbookName] = gcbvJSON
	}
	return cookbookDeps, nil
}