Ask the planner what a pull request reaches; map a changed file onto modules in one place (hq ADR 0238)
touchedBy is now the only mapping of changed files onto modules — touched, added, and read by no build — and reachOfMerge the planner's whole answer with the dependency walk. The merge handler, the plan what-if, the merge gate's width and composition, and a pull request's check all ask it, so planning and gating cannot disagree. The gate composes the definitions of the modules a merge would rebuild or add, not every one in the tree, and the check says the dependents a merge would build after them.
This commit is contained in:
@@ -44,7 +44,7 @@ func TestThePullRequestIsMappedOntoTheModuleGraph(t *testing.T) {
|
||||
{"a file no module's build reads touches no module (issue 280)",
|
||||
pull("novox", "mesh-catalog", "main", []string{"merge-check.sh", "README.md"}), "", "", "", true, ""},
|
||||
{"files the announcer could not list: everything built from it",
|
||||
link.PullUpdated{Owner: "novox", Repo: "mesh-catalog", Base: "main", PathsTruncated: true,
|
||||
link.PullUpdated{Owner: "novox", Repo: "mesh-catalog", Base: "main", Commit: "abc", PathsTruncated: true,
|
||||
Paths: []string{"README.md"}}, "gitea,keycloak,nats", "",
|
||||
"modules/gitea/module.json,modules/keycloak/module.json,modules/nats/module.json", true, ""},
|
||||
{"a new module, said by the head", pull("novox", "mesh-catalog", "main",
|
||||
@@ -67,7 +67,7 @@ func TestThePullRequestIsMappedOntoTheModuleGraph(t *testing.T) {
|
||||
{"a repository adding a module at its root", pull("someone", "newapp", "main", []string{"module.json", "x.js"}),
|
||||
"", ".", "module.json", true, ""},
|
||||
} {
|
||||
s := pullScope(c.p, entries, nil)
|
||||
s := pullScope(c.p, entries, nil, nil)
|
||||
got := []string{strings.Join(s.Modules, ","), strings.Join(s.New, ","), strings.Join(s.Manifests, ",")}
|
||||
want := []string{c.modules, c.new, c.manifest}
|
||||
for i, what := range []string{"modules", "new", "manifests"} {
|
||||
@@ -88,7 +88,7 @@ func TestThePullRequestIsMappedOntoTheModuleGraph(t *testing.T) {
|
||||
func TestAPullRequestTouchesWhatPackagesItsRepository(t *testing.T) {
|
||||
entries := []inventory.Entry{fromRepo("node-tools", "http://forge.internal:20000/novox/mesh-tools.git", "node-tools")}
|
||||
read := map[string][]inventory.ReadRepository{"node-tools": {{Repository: "http://forge.internal:20000/novox/mesh-sdk.git"}}}
|
||||
s := pullScope(link.PullUpdated{Owner: "novox", Repo: "mesh-sdk", Base: "main", Paths: []string{"go/x.go"}}, entries, read)
|
||||
s := pullScope(link.PullUpdated{Owner: "novox", Repo: "mesh-sdk", Base: "main", Commit: "abc", Paths: []string{"go/x.go"}}, entries, read, nil)
|
||||
if strings.Join(s.Modules, ",") != "node-tools" || len(s.Manifests) != 0 {
|
||||
t.Fatalf("a change to what node-tools packages touched %v (manifests %v)", s.Modules, s.Manifests)
|
||||
}
|
||||
@@ -115,3 +115,57 @@ func TestAChecksLayersAreEachSaidAndAnErrorIsNeverAPass(t *testing.T) {
|
||||
t.Fatalf("the layers said %+v / %+v", c.Gate, c.RepoCheck)
|
||||
}
|
||||
}
|
||||
|
||||
// **The check asks the planner, never a mapping of its own** (novox/hq ADR 0238): what a pull request
|
||||
// reaches is reachOfMerge's answer — the same that plans a merge — so a file at the root touches no
|
||||
// module in both, and what stands on a touched module is named as its dependents in both.
|
||||
func TestAPullRequestReachesWhatAMergeOfItWouldPlan(t *testing.T) {
|
||||
const catalogue = "http://forge.internal:20000/novox/mesh-catalog.git"
|
||||
nats := fromRepo("nats", catalogue, "modules/nats")
|
||||
nats.Source.BuiltFrom = "old"
|
||||
gitea := fromRepo("gitea", catalogue, "modules/gitea")
|
||||
gitea.Source.BuiltFrom = "old"
|
||||
tools := fromRepo("node-tools", "http://forge.internal:20000/novox/mesh-tools.git", "node-tools")
|
||||
entries := []inventory.Entry{nats, gitea, tools}
|
||||
// node-tools stands on the bus's image; a code edge, so a plan takes it along.
|
||||
edges := []inventory.Edge{{From: "node-tools", To: "nats", Kind: inventory.EdgeStandsOn}}
|
||||
read := map[string][]inventory.ReadRepository{}
|
||||
|
||||
for _, c := range []struct {
|
||||
what string
|
||||
paths []string
|
||||
moved, dependents string
|
||||
width int
|
||||
unread string
|
||||
}{
|
||||
{"a file at the root, read by no build", []string{"merge-check.sh"}, "", "", 0, "merge-check.sh"},
|
||||
{"the bus's own directory", []string{"modules/nats/Dockerfile"}, "nats", "node-tools", 2, ""},
|
||||
{"both, and a README", []string{"modules/gitea/index.ts", "modules/nats/x", "README.md"}, "gitea,nats", "node-tools", 3, "README.md"},
|
||||
} {
|
||||
p := link.PullUpdated{Owner: "novox", Repo: "mesh-catalog", Base: "main", Commit: "head", Paths: c.paths}
|
||||
s := pullScope(p, entries, read, edges)
|
||||
m := link.SourceMoved{Owner: "novox", Repo: "mesh-catalog", Base: "main", Commit: "head", Paths: c.paths}
|
||||
r := reachOfMerge(m, entries, read, edges)
|
||||
if got := strings.Join(s.Modules, ","); got != c.moved || got != strings.Join(r.Moved(), ",") {
|
||||
t.Errorf("%s: the check reaches %q, the planner %v, wanted %q", c.what, got, r.Moved(), c.moved)
|
||||
}
|
||||
if got := strings.Join(s.Dependents, ","); got != c.dependents {
|
||||
t.Errorf("%s: dependents %q, wanted %q", c.what, got, c.dependents)
|
||||
}
|
||||
if s.Width != c.width || s.Width != len(r.Plan.Modules) {
|
||||
t.Errorf("%s: a merge would build %d, the planner says %d, wanted %d", c.what, s.Width, len(r.Plan.Modules), c.width)
|
||||
}
|
||||
if got := strings.Join(s.Unread, ","); got != c.unread {
|
||||
t.Errorf("%s: unread %q, wanted %q", c.what, got, c.unread)
|
||||
}
|
||||
}
|
||||
|
||||
// A repository whose build another module's recipe packages: that module is reached through the
|
||||
// planner's `read`, and what stands on it after it.
|
||||
read["gitea"] = []inventory.ReadRepository{{Repository: "http://forge.internal:20000/novox/mesh-sdk.git"}}
|
||||
s := pullScope(link.PullUpdated{Owner: "novox", Repo: "mesh-sdk", Base: "main", Commit: "head",
|
||||
Paths: []string{"src/index.ts"}}, entries, read, edges)
|
||||
if strings.Join(s.Modules, ",") != "gitea" || len(s.Manifests) != 0 {
|
||||
t.Fatalf("a change to the source gitea packages reaches %v (manifests %v)", s.Modules, s.Manifests)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user