Files
puppet-catalog-tools/internal/impact/git.go
T
unkin-agent 8093933500
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
add the catalog-impact binary
Work out which hosts a puppet-prod change can affect, so a catalog test can
fan out over exactly those hosts instead of the whole estate.

- add cmd/catalog-impact and internal/impact
- map hieradata paths onto fact selectors from the hiera hierarchy
- trace manifest classes back to role classes through include, contain,
  class {} and hiera_include, to a fixed point
- fetch the estate fact table from pdbmux in one query via FactsByName
- widen to all hosts, loudly, for any path that matches no rule
- ship the binary and its completions in the RPM
2026-09-12 16:15:00 +10:00

54 lines
1.5 KiB
Go

package impact
import (
"bytes"
"fmt"
"os/exec"
"strings"
)
// CurrentBranch returns the branch checked out in repo.
func CurrentBranch(repo string) (string, error) {
out, err := git(repo, "rev-parse", "--abbrev-ref", "HEAD")
if err != nil {
return "", err
}
branch := strings.TrimSpace(out)
if branch == "" || branch == "HEAD" {
return "", fmt.Errorf("%s is not on a branch; pass --branch", repo)
}
return branch, nil
}
// ChangedFiles lists the paths that differ between base and branch, using the
// three-dot form so only the branch's own commits count. Renames contribute
// both the old and the new path, because a moved manifest changes the classes
// at both ends.
func ChangedFiles(repo, base, branch string) ([]string, error) {
out, err := git(repo, "diff", "--name-status", "--find-renames", base+"..."+branch)
if err != nil {
return nil, err
}
var files []string
for _, line := range strings.Split(out, "\n") {
fields := strings.Split(strings.TrimSpace(line), "\t")
if len(fields) < 2 || fields[0] == "" {
continue
}
files = append(files, fields[1:]...)
}
return uniqueSorted(files), nil
}
func git(repo string, args ...string) (string, error) {
cmd := exec.Command("git", append([]string{"-C", repo}, args...)...)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
return "", fmt.Errorf("git %s: %w: %s", strings.Join(args, " "), err, strings.TrimSpace(stderr.String()))
}
return stdout.String(), nil
}