mesh/merge-gate head 104533e8c0c9 merged into trunk cdfc63cf102b — fail: builds mesh-sdk (+41 dependent(s)) → ace, g14, novox, shanks; no bus step; 9 wait(…
mesh/repo-check head 104533e8c0c9 merged into trunk cdfc63cf102b — pass: THE CHANGE ALTERS ITS OWN CHECK (go/merge-check.sh): main's version judged it; the…
mesh/delivery-group group feat/r4e rejected: a member's own check failed
mesh/delivery superseded: a newer head of the same pull request
mesh/check failed: unit: modules/gitea.type-check: index.ts(263,29): error TS2345: Argument of type 'BranchProtection | null | undefined' is not assig…
catalogue.ParseManifestForInputs (issue 1751): a manifest falling back to a predefined key was narrowed by the indexer and not by a build module, two computations of one tree (novox/hq ADR 0499 clause 2).
114 lines
5.3 KiB
Go
114 lines
5.3 KiB
Go
package buildstep
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
"git.novox.be/novox/mesh-sdk/go/forgekey"
|
|
)
|
|
|
|
// A module whose every artifact names its paths takes its tree from them (novox/hq ADR 0499 clause 2): ModuleTrees asks
|
|
// git for each named path's object at the commit, keeps them in Paths and answers their delivery.NamedTree as Tree; a
|
|
// module naming none keeps its directory's tree, as before.
|
|
func TestModuleTreesNarrowsAModuleWhoseArtifactsNameTheirPaths(t *testing.T) {
|
|
root := t.TempDir()
|
|
sdk := `{"module":"mesh-sdk","version":"1","build":{"artifacts":[{"name":"lib","kind":"package","language":"typescript","paths":["src","package.json"]}]}}`
|
|
writeTreeFile(t, root, "module.json", sdk)
|
|
writeTreeFile(t, root, "modules/b/module.json", `{"module":"b","version":"1"}`)
|
|
merge := strings.Repeat("c", 40)
|
|
var lsTree []string
|
|
run := func(ctx context.Context, env []string, name string, args ...string) forgekey.Ran {
|
|
switch args[2] {
|
|
case "ls-files":
|
|
return forgekey.Ran{Stdout: "module.json\nmodules/b/module.json\n"}
|
|
case "rev-parse":
|
|
return forgekey.Ran{Stdout: "tree-of-" + args[3] + "\n"}
|
|
case "ls-tree":
|
|
lsTree = append(lsTree, strings.Join(args[4:], " "))
|
|
return forgekey.Ran{Stdout: "100644 blob " + strings.Repeat("b", 40) + "\tpackage.json\x00" +
|
|
"040000 tree " + strings.Repeat("a", 40) + "\tsrc\x00"}
|
|
}
|
|
return forgekey.Ran{Status: 1, Stderr: "unexpected " + args[2]}
|
|
}
|
|
got, err := ModuleTrees(context.Background(), run, nil, root, merge)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
paths := map[string]string{"src": strings.Repeat("a", 40), "package.json": strings.Repeat("b", 40)}
|
|
want, _ := delivery.NamedTree(hexOf(sdk), paths)
|
|
if g := got["."]; g.Tree != want || len(g.Paths) != 2 || g.Paths["src"] != paths["src"] || g.Paths["package.json"] != paths["package.json"] {
|
|
t.Fatalf("the root module = %+v, want tree %s and paths %v", g, want, paths)
|
|
}
|
|
if len(lsTree) != 1 || lsTree[0] != merge+" -- package.json src" {
|
|
t.Fatalf("git ls-tree ran as %v", lsTree)
|
|
}
|
|
if g := got["modules/b"]; g.Tree != "tree-of-"+merge+":modules/b" || g.Paths != nil {
|
|
t.Fatalf("a module naming no path was narrowed: %+v", g)
|
|
}
|
|
}
|
|
|
|
// A named path absent at the commit fails the answer, naming the module and the path: a tree computed without it would
|
|
// pin a build source that does not exist.
|
|
func TestModuleTreesFailsNamingANamedPathAbsentAtTheCommit(t *testing.T) {
|
|
root := t.TempDir()
|
|
writeTreeFile(t, root, "modules/a/module.json", `{"module":"a","version":"1","build":{"artifacts":[{"name":"lib","kind":"package","language":"typescript","paths":["src","gone"]}]}}`)
|
|
run := func(ctx context.Context, env []string, name string, args ...string) forgekey.Ran {
|
|
switch args[2] {
|
|
case "ls-files":
|
|
return forgekey.Ran{Stdout: "modules/a/module.json\n"}
|
|
case "rev-parse":
|
|
return forgekey.Ran{Stdout: "t\n"}
|
|
case "ls-tree":
|
|
if strings.Join(args[4:], " ") != strings.Repeat("c", 40)+" -- modules/a/gone modules/a/src" {
|
|
return forgekey.Ran{Status: 1, Stderr: "wrong arguments " + strings.Join(args[3:], " ")}
|
|
}
|
|
return forgekey.Ran{Stdout: "040000 tree " + strings.Repeat("a", 40) + "\tmodules/a/src\x00"}
|
|
}
|
|
return forgekey.Ran{Status: 1}
|
|
}
|
|
_, err := ModuleTrees(context.Background(), run, nil, root, strings.Repeat("c", 40))
|
|
if err == nil || !strings.Contains(err.Error(), `"gone"`) || !strings.Contains(err.Error(), "modules/a") {
|
|
t.Fatalf("an absent named path gave %v", err)
|
|
}
|
|
}
|
|
|
|
// A manifest whose config value falls back to a predefined key is narrowed here as the indexer narrows it: both read it
|
|
// with catalogue.ParseManifestForInputs (issue 1751), so a build module holding no published list computes the same
|
|
// tree (ADR 0499 clause 2).
|
|
func TestModuleTreesNarrowsAManifestFallingBackToAPredefinedKey(t *testing.T) {
|
|
was := catalogue.ReplacePublished(nil) // the build modules' case: no published list
|
|
defer catalogue.ReplacePublished(was)
|
|
root := t.TempDir()
|
|
raw := `{"module":"xterm","version":"1","config":{"size":{"type":"number","description":"The text size.","predefined":"font-size","default":12,"runtime":true}},` +
|
|
`"build":{"artifacts":[{"name":"lib","kind":"package","language":"typescript","paths":["src"]}]}}`
|
|
if _, err := catalogue.ParseManifest([]byte(raw)); err == nil {
|
|
t.Fatal("ParseManifest reads the manifest with no list; the test proves nothing")
|
|
}
|
|
if _, err := catalogue.ParseManifestForInputs([]byte(raw)); err != nil {
|
|
t.Fatalf("the indexer's read refuses the manifest: %v", err)
|
|
}
|
|
writeTreeFile(t, root, "module.json", raw)
|
|
run := func(ctx context.Context, env []string, name string, args ...string) forgekey.Ran {
|
|
switch args[2] {
|
|
case "ls-files":
|
|
return forgekey.Ran{Stdout: "module.json\n"}
|
|
case "rev-parse":
|
|
return forgekey.Ran{Stdout: "whole\n"}
|
|
case "ls-tree":
|
|
return forgekey.Ran{Stdout: "040000 tree " + strings.Repeat("a", 40) + "\tsrc\x00"}
|
|
}
|
|
return forgekey.Ran{Status: 1}
|
|
}
|
|
got, err := ModuleTrees(context.Background(), run, nil, root, strings.Repeat("c", 40))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
want, _ := delivery.NamedTree(hexOf(raw), map[string]string{"src": strings.Repeat("a", 40)})
|
|
if g := got["."]; g.Tree != want || g.Paths["src"] == "" {
|
|
t.Fatalf("the module = %+v, want the named tree %s", g, want)
|
|
}
|
|
}
|