Pass a check's changed paths in a file so a change of thousands of files can start (issue 1247)

One environment string over 128 KiB made the container fail to start with no words; the gate reads --changed-file, and a command that cannot start now says its error.
This commit is contained in:
2026-10-19 15:22:00 +02:00
parent a5a43c8f31
commit dd802c81a7
5 changed files with 251 additions and 6 deletions
+25 -1
View File
@@ -154,6 +154,24 @@ type mergeWidthOf struct {
// wideRebuild is how many modules a rebuild may take before the gate says so as a warning.
var wideRebuild = 12
// changedPaths are the paths --changed (comma-separated) and --changed-file (one per line) name together.
func changedPaths(list, file string) ([]string, error) {
out := splitList(list)
if file == "" {
return out, nil
}
raw, err := os.ReadFile(file)
if err != nil {
return nil, fmt.Errorf("--changed-file: %w", err)
}
for _, line := range strings.Split(string(raw), "\n") {
if line = strings.TrimSpace(line); line != "" {
out = append(out, line)
}
}
return out, nil
}
// mergeGateCommand is `gate`:
//
// merge-gate --facts <file> --store <postgres> [--repository owner/repo --tree <dir>] [--changed a,b] [--json]
@@ -167,6 +185,8 @@ func mergeGateCommand(ctx context.Context, args []string) error {
repository := set.String("repository", "", "owner/repository of the change")
tree := set.String("tree", "", "the change's checkout: every module.json in it replaces the mesh's")
changed := set.String("changed", "", "the paths the change touches, comma-separated, for its rebuild's width")
changedFile := set.String("changed-file", "", "a file of the paths the change touches, one per line; the same as "+
"--changed, for a list too long for an argument (novox/hq issue 1247)")
group := set.String("group", "", "a delivery group's other heads, as JSON [{repository, tree, changed}], composed "+
"with this one as one future state (novox/hq ADR 0239)")
asJSON := set.Bool("json", false, "print the verdict as JSON")
@@ -198,7 +218,11 @@ func mergeGateCommand(ctx context.Context, args []string) error {
// verdict at all. What is said goes beside the report.
os.Stdout = os.Stderr
}
v, err := judgeChange(ctx, mergeCheckInput{facts: f, repository: *repository, tree: *tree, changed: splitList(*changed),
changedList, err := changedPaths(*changed, *changedFile)
if err != nil {
return err
}
v, err := judgeChange(ctx, mergeCheckInput{facts: f, repository: *repository, tree: *tree, changed: changedList,
group: others, admin: *admin, say: out, beside: os.Getenv("MESH_CHECK_BESIDE")})
os.Stdout = stdout
if err != nil {
@@ -0,0 +1,31 @@
package main
import (
"os"
"path/filepath"
"reflect"
"strings"
"testing"
)
func TestTheGateJudgesAFileOfPathsAsItDoesTheSameListOfThem(t *testing.T) { // 1247/AC3
paths := []string{"modules/a/x.go", "modules/a/y.go", "modules/b/z.go", "README.md"}
file := filepath.Join(t.TempDir(), "changed.txt")
if err := os.WriteFile(file, []byte(strings.Join(paths, "\n")+"\n"), 0o644); err != nil {
t.Fatal(err)
}
fromFile, err := changedPaths("", file)
if err != nil {
t.Fatal(err)
}
fromList, err := changedPaths(strings.Join(paths, ","), "")
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(fromFile, fromList) || len(fromFile) != len(paths) {
t.Errorf("the file gives %v, the list %v", fromFile, fromList)
}
if _, err := changedPaths("", filepath.Join(t.TempDir(), "none")); err == nil {
t.Error("a file that is not there is read as no paths")
}
}