// ReverseDeps For each input label, finds all targets which depend upon it.
func ReverseDeps(graph *core.BuildGraph, labels []core.BuildLabel) {

	uniqueTargets := make(map[core.BuildLabel]struct{})

	for _, label := range labels {
		for _, child := range graph.PackageOrDie(label.PackageName).AllChildren(graph.TargetOrDie(label)) {
			for _, target := range graph.ReverseDependencies(child) {
				if parent := target.Parent(graph); parent != nil {
					uniqueTargets[parent.Label] = struct{}{}
				} else {
					uniqueTargets[target.Label] = struct{}{}
				}
			}
		}
	}
	// Check for anything subincluding this guy too
	for _, pkg := range graph.PackageMap() {
		for _, label := range labels {
			if pkg.HasSubinclude(label) {
				uniqueTargets[core.BuildLabel{PackageName: pkg.Name, Name: "all"}] = struct{}{}
			}
		}
	}

	targets := make(core.BuildLabels, 0, len(uniqueTargets))
	for target := range uniqueTargets {
		targets = append(targets, target)
	}
	sort.Sort(targets)
	for _, target := range targets {
		fmt.Printf("%s\n", target)
	}
}
Exemple #2
0
func addJSONTarget(graph *core.BuildGraph, ret *JSONGraph, label core.BuildLabel, done map[core.BuildLabel]struct{}) {
	if _, present := done[label]; present {
		return
	}
	done[label] = struct{}{}
	if label.IsAllTargets() {
		pkg := graph.PackageOrDie(label.PackageName)
		for _, target := range pkg.Targets {
			addJSONTarget(graph, ret, target.Label, done)
		}
		return
	}
	target := graph.TargetOrDie(label)
	if _, present := ret.Packages[label.PackageName]; present {
		ret.Packages[label.PackageName].Targets[label.Name] = makeJSONTarget(graph, target)
	} else {
		ret.Packages[label.PackageName] = JSONPackage{
			Targets: map[string]JSONTarget{
				label.Name: makeJSONTarget(graph, target),
			},
		}
	}
	for _, dep := range target.Dependencies() {
		addJSONTarget(graph, ret, dep.Label, done)
	}
}
Exemple #3
0
func querySomePath1(graph *core.BuildGraph, target1 *core.BuildTarget, label2 core.BuildLabel, print bool) bool {
	// Now we do the same for label2.
	if label2.IsAllTargets() {
		for _, target2 := range graph.PackageOrDie(label2.PackageName).Targets {
			if querySomePath2(graph, target1, target2, false) {
				return true
			}
		}
		return false
	}
	return querySomePath2(graph, target1, graph.TargetOrDie(label2), print)
}
Exemple #4
0
// QuerySomePath finds and returns a path between two targets.
// Useful for a "why on earth do I depend on this thing" type query.
func QuerySomePath(graph *core.BuildGraph, label1 core.BuildLabel, label2 core.BuildLabel) {
	// Awkwardly either target can be :all. This is an extremely useful idiom though so despite
	// trickiness is worth supporting.
	// Of course this calculation is also quadratic but it's not very obvious how to avoid that.
	if label1.IsAllTargets() {
		for _, target := range graph.PackageOrDie(label1.PackageName).Targets {
			if querySomePath1(graph, target, label2, false) {
				return
			}
		}
		fmt.Printf("Couldn't find any dependency path between %s and %s\n", label1, label2)
	} else {
		querySomePath1(graph, graph.TargetOrDie(label1), label2, true)
	}
}
// Queries a set of possible completions for some build labels.
// If 'binary' is true it will complete only targets that are runnable binaries (but not tests).
// If 'test' is true it will similarly complete only targets that are tests.
func QueryCompletions(graph *core.BuildGraph, labels []core.BuildLabel, binary, test bool) {
	for _, label := range labels {
		count := 0
		for _, target := range graph.PackageOrDie(label.PackageName).Targets {
			if (binary && (!target.IsBinary || target.IsTest)) || (test && !target.IsTest) {
				continue
			}
			if !strings.HasPrefix(target.Label.Name, "_") {
				fmt.Printf("%s\n", target.Label)
				count++
			}
		}
		if !binary && count > 1 {
			fmt.Printf("//%s:all\n", label.PackageName)
		}
	}
}