func makeJSONTarget(graph *core.BuildGraph, target *core.BuildTarget) JSONTarget { t := JSONTarget{} for in := range core.IterSources(graph, target) { t.Inputs = append(t.Inputs, in.Src) } for _, out := range target.Outputs() { t.Outputs = append(t.Outputs, path.Join(target.Label.PackageName, out)) } for _, src := range target.AllSourcePaths(graph) { t.Sources = append(t.Sources, src) } for _, dep := range target.Dependencies() { t.Deps = append(t.Deps, dep.Label.String()) } for data := range core.IterRuntimeFiles(graph, target, false) { t.Data = append(t.Data, data.Src) } t.Labels = target.Labels t.Requires = target.Requires rawHash := append(build.RuleHash(target, true, false), core.State.Hashes.Config...) t.Hash = base64.RawStdEncoding.EncodeToString(rawHash) t.Test = target.IsTest t.Binary = target.IsBinary t.TestOnly = target.TestOnly return t }
// Calculate the hash of all sources of this rule func sourceHash(graph *core.BuildGraph, target *core.BuildTarget) ([]byte, error) { h := sha1.New() for source := range core.IterSources(graph, target) { result, err := pathHash(source.Src, false) if err != nil { return nil, err } h.Write(result) } for _, tool := range target.Tools { if label := tool.Label(); label != nil { // Note that really it would be more correct to hash the outputs of these rules // in the same way we calculate a hash of sources for the rule, but that is // impractical for some cases (notably npm) where tools can be very large. // Instead we assume calculating the target hash is sufficient. h.Write(mustTargetHash(core.State, graph.TargetOrDie(*label))) } else { result, err := pathHash(tool.FullPaths(graph)[0], false) if err != nil { return nil, err } h.Write(result) } } return h.Sum(nil), nil }
// Symlinks the source files of this rule into its temp directory. func prepareSources(graph *core.BuildGraph, target *core.BuildTarget) error { for source := range core.IterSources(graph, target) { if err := core.PrepareSourcePair(source); err != nil { return err } } return nil }
// PrintHashes prints the various hashes for a target to stdout. // It's used by plz hash --detailed to show a breakdown of the input hashes of a target. func PrintHashes(state *core.BuildState, target *core.BuildTarget) { fmt.Printf("%s:\n", target.Label) fmt.Printf(" Config: %s\n", b64(state.Hashes.Config)) fmt.Printf(" Rule: %s (pre-build)\n", b64(RuleHash(target, false, false))) fmt.Printf(" Rule: %s (post-build)\n", b64(RuleHash(target, false, true))) fmt.Printf(" Source: %s\n", b64(mustSourceHash(state.Graph, target))) // Note that the logic here mimics sourceHash, but I don't want to pollute that with // optional printing nonsense since it's on our hot path. for source := range core.IterSources(state.Graph, target) { fmt.Printf(" Source: %s: %s\n", source.Src, b64(mustPathHash(source.Src))) } for _, tool := range target.Tools { if label := tool.Label(); label != nil { fmt.Printf(" Tool: %s: %s\n", *label, b64(mustShortTargetHash(state, state.Graph.TargetOrDie(*label)))) } else { fmt.Printf(" Tool: %s: %s\n", tool, b64(mustPathHash(tool.FullPaths(state.Graph)[0]))) } } }