8093933500
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
54 lines
1.5 KiB
Go
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
|
|
}
|