Take a module's tree input from the paths its artifacts name, by mesh-sdk's NamedTree, and keep their objects and each artifact's paths, so a module outside them moves for no change there (issue 1758, I7 and the indexer's I8, ADR 0499 §2 §3)
A merged message or a preview without the objects gives the module none, naming the paths. Every other module keeps its directory's tree. Module.ArtifactPaths is filled for the checker (the lead's interface).
This commit is contained in:
@@ -37,6 +37,8 @@ type moduleInputs struct {
|
||||
Languages map[string]string
|
||||
// None2 is why the module has no fingerprint of the new form.
|
||||
None2 string
|
||||
// ArtifactPaths are the paths each artifact naming them names, as its manifest names them (delivery.Module.ArtifactPaths).
|
||||
ArtifactPaths map[string][]string
|
||||
}
|
||||
|
||||
// baseFP answers a base module's new-form fingerprint, or why it has none.
|
||||
@@ -55,6 +57,15 @@ type baseFP func(module string) (fp, none string)
|
||||
// here, so a fingerprint is never given for a build that could not run. An archive, an image and an upstream resolve
|
||||
// nothing and have no toolchain. A base is a build.on entry that names a module.
|
||||
func inputsOf(module, raw, tree string, locks map[string]string, base baseFP) moduleInputs {
|
||||
return inputsOfNamed(module, raw, tree, locks, nil, base)
|
||||
}
|
||||
|
||||
// inputsOfNamed is inputsOf with the git object of each path the message names for the module's directory (delivery
|
||||
// Forge.Paths, PreviewModule.Paths). A module whose every artifact names its paths takes its tree input from them and its
|
||||
// manifest, by mesh-sdk's one function (delivery.NamedTree), and keeps their objects, so a computation from kept inputs
|
||||
// gives the merge's value (novox/hq ADR 0499 clause 2); a message that does not carry the object of each such path gives it
|
||||
// none, naming the paths (clause 3). Every other module keeps its directory's tree, whatever objects are given.
|
||||
func inputsOfNamed(module, raw, tree string, locks, objects map[string]string, base baseFP) moduleInputs {
|
||||
m, err := readManifest([]byte(raw))
|
||||
if err != nil {
|
||||
return moduleInputs{None2: "the manifest cannot be read: " + err.Error()}
|
||||
@@ -62,10 +73,39 @@ func inputsOf(module, raw, tree string, locks map[string]string, base baseFP) mo
|
||||
if m.Module != module {
|
||||
return moduleInputs{None2: fmt.Sprintf("the manifest is of module %q, not %q", m.Module, module)}
|
||||
}
|
||||
if tree == "" {
|
||||
return moduleInputs{None2: "the merge names no tree for the module's directory"}
|
||||
var artifactPaths map[string][]string
|
||||
if m.Build != nil {
|
||||
for _, a := range m.Build.Artifacts {
|
||||
if len(a.Paths) > 0 {
|
||||
if artifactPaths == nil {
|
||||
artifactPaths = map[string][]string{}
|
||||
}
|
||||
artifactPaths[a.Name] = slices.Clone(a.Paths)
|
||||
}
|
||||
}
|
||||
}
|
||||
kept := delivery.KeptInputs2{Tree: tree}
|
||||
var named map[string]string
|
||||
if paths, every := m.NamedPaths(); every {
|
||||
var missing []string
|
||||
named = map[string]string{}
|
||||
for _, p := range paths {
|
||||
if objects[p] == "" {
|
||||
missing = append(missing, p)
|
||||
continue
|
||||
}
|
||||
named[p] = objects[p]
|
||||
}
|
||||
if len(missing) > 0 {
|
||||
return moduleInputs{None2: "the message carries no git object of the named paths " + strings.Join(missing, ", "), ArtifactPaths: artifactPaths}
|
||||
}
|
||||
if tree, err = delivery.NamedTree(delivery.ManifestDigest([]byte(raw)), named); err != nil {
|
||||
return moduleInputs{None2: err.Error(), ArtifactPaths: artifactPaths}
|
||||
}
|
||||
}
|
||||
if tree == "" {
|
||||
return moduleInputs{None2: "the merge names no tree for the module's directory", ArtifactPaths: artifactPaths}
|
||||
}
|
||||
kept := delivery.KeptInputs2{Tree: tree, Paths: named}
|
||||
contexts := false
|
||||
var missing []string
|
||||
langs := languagesOf(m)
|
||||
@@ -94,7 +134,7 @@ func inputsOf(module, raw, tree string, locks map[string]string, base baseFP) mo
|
||||
}
|
||||
sort.Strings(kept.Bases)
|
||||
sort.Strings(missing)
|
||||
out := moduleInputs{Kept: &kept}
|
||||
out := moduleInputs{Kept: &kept, ArtifactPaths: artifactPaths}
|
||||
if len(langs) > 0 {
|
||||
out.Languages = langs
|
||||
}
|
||||
|
||||
@@ -60,8 +60,8 @@ func (ix *Indexer) applyMerged(ctx context.Context, f delivery.Forge) error {
|
||||
if next.Manifest == "" {
|
||||
next.None2 = "the manifest cannot be read: it cannot be kept as a value"
|
||||
} else {
|
||||
in := inputsOf(name, raw, f.Trees[dir], f.Locks[dir], ix.baseFP(ctx))
|
||||
next.Inputs2, next.None2 = in.Kept, in.None2
|
||||
in := inputsOfNamed(name, raw, f.Trees[dir], f.Locks[dir], f.Paths[dir], ix.baseFP(ctx))
|
||||
next.Inputs2, next.None2, next.ArtifactPaths = in.Kept, in.None2, in.ArtifactPaths
|
||||
}
|
||||
overlay[key] = next
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package index
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
)
|
||||
|
||||
// ADR 0499 clauses 2 and 3 (I7): a module whose every artifact names its paths takes its tree input from them, by mesh-sdk's
|
||||
// one function, and keeps their objects, so a computation from kept inputs gives the merge's value. The manifest is
|
||||
// mesh-sdk's module.json at 9cb4d59 (its lib names src, test, package.json, package-lock.json and tsconfig.json).
|
||||
|
||||
var sdkObjects = map[string]string{"src": "1111111111111111111111111111111111111111", "test": "2222222222222222222222222222222222222222",
|
||||
"package.json": "3333333333333333333333333333333333333333", "package-lock.json": "4444444444444444444444444444444444444444", "tsconfig.json": "5555555555555555555555555555555555555555"}
|
||||
|
||||
func TestAModuleNamingItsPathsTakesItsTreeFromThemAndKeepsTheirObjects(t *testing.T) { // I7, ADR 0499 clause 2
|
||||
ix, mods, _ := manifestsIndexer(t)
|
||||
raw := fixture(t, "sdk-9cb4d59-mesh-sdk")
|
||||
f := withManifests(mergedMsg("novox/mesh-sdk", map[string]string{"": "roottree"}), map[string]string{"": raw}, map[string]map[string]string{"": {"package-lock.json": avahiGoSum}})
|
||||
f.Paths = map[string]map[string]string{"": sdkObjects}
|
||||
if err := ix.Apply(context.Background(), f); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
m, ok := moduleOf(t, mods, "mesh-sdk")
|
||||
if !ok || m.Inputs2 == nil {
|
||||
t.Fatalf("module = %+v (%v)", m, ok)
|
||||
}
|
||||
want, err := delivery.NamedTree(delivery.ManifestDigest([]byte(raw)), sdkObjects)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if m.Inputs2.Tree != want || !reflect.DeepEqual(m.Inputs2.Paths, sdkObjects) {
|
||||
t.Errorf("inputs = %+v, want the named tree %s and the objects kept", m.Inputs2, want)
|
||||
}
|
||||
if got := m.ArtifactPaths["lib"]; strings.Join(got, ",") != "src,test,package.json,package-lock.json,tsconfig.json" {
|
||||
t.Errorf("artifact paths = %v, want lib's paths as its manifest names them", m.ArtifactPaths)
|
||||
}
|
||||
// Recomputed from what is kept, with no merge, the module is the same (ADR 0499 clause 2).
|
||||
before := string(mods.vals["mesh-sdk"])
|
||||
if err := ix.Recompute(context.Background()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(mods.vals["mesh-sdk"]) != before {
|
||||
t.Errorf("a recompute changed the module: %s, was %s", mods.vals["mesh-sdk"], before)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAMessageWithoutTheNamedPathsObjectsGivesTheModuleNoneNamingThem(t *testing.T) { // I7, ADR 0499 clause 3
|
||||
ix, mods, _ := manifestsIndexer(t)
|
||||
raw := fixture(t, "sdk-9cb4d59-mesh-sdk")
|
||||
f := withManifests(mergedMsg("novox/mesh-sdk", map[string]string{"": "roottree"}), map[string]string{"": raw}, nil)
|
||||
if err := ix.Apply(context.Background(), f); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
m, _ := moduleOf(t, mods, "mesh-sdk")
|
||||
if m.FP2 != "" || !strings.Contains(m.None2, "named paths") || !strings.Contains(m.None2, "tsconfig.json") {
|
||||
t.Errorf("module = %+v, want none naming the paths the message did not carry", m)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAModuleNamingNoPathsKeepsItsDirectorysTree(t *testing.T) { // I7, ADR 0499 clause 2: every other module is unchanged
|
||||
in := inputsOfNamed("avahi", catalogueManifest(t, "avahi"), "avahitree", map[string]string{"go.sum": avahiGoSum}, map[string]string{"x": "1111111111111111111111111111111111111111"}, noBases)
|
||||
if in.Kept == nil || in.Kept.Tree != "avahitree" || in.Kept.Paths != nil {
|
||||
t.Errorf("inputs = %+v, want the directory's tree and no paths", in.Kept)
|
||||
}
|
||||
}
|
||||
|
||||
func TestACandidatesModuleTakesTheNamedPathsObjectsFromThePreview(t *testing.T) { // I8, ADR 0499 clause 2 (the merge preview)
|
||||
ix, _, _ := manifestsIndexer(t)
|
||||
raw := fixture(t, "sdk-9cb4d59-mesh-sdk")
|
||||
digest, err := ix.keepManifest(context.Background(), "mesh-sdk", raw)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
named, _ := delivery.NamedTree(digest, sdkObjects)
|
||||
with := delivery.Preview{Modules: map[string]delivery.PreviewModule{".": {Tree: named, Manifest: digest, Paths: sdkObjects}}}
|
||||
without := delivery.Preview{Modules: map[string]delivery.PreviewModule{".": {Tree: "roottree", Manifest: digest}}}
|
||||
if got := ix.candidateModule(context.Background(), "mesh-sdk", ".", without); !strings.Contains(got.None2, "named paths") {
|
||||
t.Errorf("without the objects: %+v, want none naming the named paths", got)
|
||||
}
|
||||
if got := ix.candidateModule(context.Background(), "mesh-sdk", ".", with); strings.Contains(got.None2, "named paths") || got.Manifest != digest {
|
||||
t.Errorf("with the objects: %+v, want them taken (none only for what else is missing)", got)
|
||||
}
|
||||
}
|
||||
@@ -228,7 +228,7 @@ func (ix *Indexer) candidateModule(ctx context.Context, m, dir string, pv delive
|
||||
out.None2 = NonePreviewNoManifest
|
||||
return out
|
||||
}
|
||||
in := inputsOf(m, kept.JSON, pm.Tree, pm.Locks, ix.baseFP(ctx))
|
||||
in := inputsOfNamed(m, kept.JSON, pm.Tree, pm.Locks, pm.Paths, ix.baseFP(ctx))
|
||||
if in.Kept == nil {
|
||||
out.None2 = in.None2
|
||||
return out
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"module": "mesh-sdk",
|
||||
"version": "1",
|
||||
"slug": "sdk",
|
||||
"build": {
|
||||
"artifacts": [
|
||||
{
|
||||
"name": "lib",
|
||||
"kind": "package",
|
||||
"language": "typescript",
|
||||
"paths": ["src", "test", "package.json", "package-lock.json", "tsconfig.json"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"resources": []
|
||||
}
|
||||
Reference in New Issue
Block a user