func ExpandInputsOutputs(target Target) (map[string]os.FileInfo, map[string]os.FileInfo, error) { inputs, err := target.Inputs() if err != nil { return nil, nil, err } inputInfo := bkglob.MatchAllWithFileInfo(bkglob.NewSlice(inputs...)...) inputs = []string{} for input := range inputInfo { inputs = append(inputs, input) } outputs, err := target.Outputs(inputs) if err != nil { return nil, nil, err } outputInfo := bkglob.MatchAllWithFileInfo(bkglob.NewSlice(outputs...)...) return inputInfo, outputInfo, nil }
// SortTargets orders targets by dependencies. // // The algorithm is based on // http://blog.jupo.org/2012/04/06/topological-sorting-acyclic-directed-graphs/ func SortTargets(targets []Target) ([]Target, error) { deps := []*targetDeps{} // First, build deps slice. for index, t := range targets { inputs, err := t.Inputs() if err != nil { return nil, err } inputs = glob.MatchAll(glob.NewSlice(inputs...)...) outputs, err := t.Outputs(inputs) if err != nil { return nil, err } deps = append(deps, &targetDeps{ index: index, target: t, inputs: inputs, outputs: outputs, }) } // Next, populate edges from input globs and outputs. for ai, a := range deps { for bi, b := range deps { if ai == bi { continue } deploop: for _, i := range a.inputs { for _, o := range b.outputs { if i == o { a.edges = append(a.edges, bi) break deploop } } } } } outDeps, err := topologicalSortDeps(deps) if err != nil { return nil, err } out := []Target{} for _, t := range outDeps { out = append(out, t.target) } return out, nil }