From d19a73f8eeabdb18cdee1f9ce7c51664f6ff6f80 Mon Sep 17 00:00:00 2001 From: Matt Keeler Date: Thu, 12 Mar 2026 12:38:46 -0400 Subject: [PATCH] Fix task fingerprinting to account for the dir sources and generates --- internal/fingerprint/fingerprint_key.go | 60 +++++++++++++++++++++++ internal/fingerprint/sources_checksum.go | 2 +- internal/fingerprint/sources_timestamp.go | 2 +- 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 internal/fingerprint/fingerprint_key.go diff --git a/internal/fingerprint/fingerprint_key.go b/internal/fingerprint/fingerprint_key.go new file mode 100644 index 0000000000..34b79f89e4 --- /dev/null +++ b/internal/fingerprint/fingerprint_key.go @@ -0,0 +1,60 @@ +package fingerprint + +import ( + "encoding/json" + "fmt" + + "github.com/zeebo/xxh3" + + "github.com/go-task/task/v3/taskfile/ast" +) + +type fingerprintIdentity struct { + Task string `json:"task"` + Dir string `json:"dir"` + Sources []string `json:"sources,omitempty"` + Generates []string `json:"generates,omitempty"` +} + +func taskFingerprintKey(t *ast.Task) string { + name := taskIdentityName(t) + identity := fingerprintIdentity{ + Task: name, + Dir: t.Dir, + Sources: globPatterns(t.Sources), + Generates: globPatterns(t.Generates), + } + + encoded, err := json.Marshal(identity) + if err != nil { + return normalizeFilename(name) + } + + return normalizeFilename(fmt.Sprintf("%s-%x", name, xxh3.Hash(encoded))) +} + +func taskIdentityName(t *ast.Task) string { + if t.FullName != "" { + return t.FullName + } + return t.Task +} + +func globPatterns(globs []*ast.Glob) []string { + if len(globs) == 0 { + return nil + } + + patterns := make([]string, 0, len(globs)) + for _, glob := range globs { + if glob == nil { + continue + } + if glob.Negate { + patterns = append(patterns, "!"+glob.Glob) + continue + } + patterns = append(patterns, glob.Glob) + } + return patterns +} diff --git a/internal/fingerprint/sources_checksum.go b/internal/fingerprint/sources_checksum.go index 16a98c1640..23cde9d89f 100644 --- a/internal/fingerprint/sources_checksum.go +++ b/internal/fingerprint/sources_checksum.go @@ -115,7 +115,7 @@ func (c *ChecksumChecker) checksum(t *ast.Task) (string, error) { } func (checker *ChecksumChecker) checksumFilePath(t *ast.Task) string { - return filepath.Join(checker.tempDir, "checksum", normalizeFilename(t.Name())) + return filepath.Join(checker.tempDir, "checksum", taskFingerprintKey(t)) } var checksumFilenameRegexp = regexp.MustCompile("[^A-z0-9]") diff --git a/internal/fingerprint/sources_timestamp.go b/internal/fingerprint/sources_timestamp.go index b1a6f299d5..2ca5b6b9f6 100644 --- a/internal/fingerprint/sources_timestamp.go +++ b/internal/fingerprint/sources_timestamp.go @@ -147,5 +147,5 @@ func (*TimestampChecker) OnError(t *ast.Task) error { } func (checker *TimestampChecker) timestampFilePath(t *ast.Task) string { - return filepath.Join(checker.tempDir, "timestamp", normalizeFilename(t.Task)) + return filepath.Join(checker.tempDir, "timestamp", taskFingerprintKey(t)) }