Example #1
0
// Makes sure that the dependencies for the tasks in the project form a
// valid dependency graph (no cycles).
func checkDependencyGraph(project *model.Project) []ValidationError {
	errs := []ValidationError{}

	// map of task name and variant -> BuildVariantTask
	tasksByNameAndVariant := map[model.TVPair]model.BuildVariantTask{}

	// generate task nodes for every task and variant combination
	visited := map[model.TVPair]bool{}
	allNodes := []model.TVPair{}
	for _, bv := range project.BuildVariants {
		for _, t := range bv.Tasks {
			t.Populate(project.GetSpecForTask(t.Name))
			node := model.TVPair{bv.Name, t.Name}

			tasksByNameAndVariant[node] = t
			visited[node] = false
			allNodes = append(allNodes, node)
		}
	}

	// run through the task nodes, checking their dependency graphs for cycles
	for _, node := range allNodes {
		// the visited nodes
		if err := dependencyCycleExists(node, visited, tasksByNameAndVariant); err != nil {
			errs = append(errs,
				ValidationError{
					Message: fmt.Sprintf(
						"dependency error for '%v' task: %v", node.TaskName, err),
				},
			)
		}
	}

	return errs
}