The catalog graph entry carries what the next revision is computed from and its package versions (milestone 47/G W3.1, inputs)
The lead's ruling on finding 1: an entry gains inputs (what its fingerprint is computed from, the toolchains used, problems, warnings, named paths, the source revisions it was taken in and its fingerprint moved at) and packages becomes name to version, so the indexer's view of the trunk can be read back from the newest trunk revision alone (ModuleValueOf). A revision's entries are the values the recompute wrote, not the values it started from. Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
@@ -6,11 +6,13 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"maps"
|
||||
"reflect"
|
||||
"slices"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
|
||||
"git.novox.be/novox/mesh-delivery/sdk/graph"
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
"git.novox.be/novox/mesh-sdk/go/keys"
|
||||
)
|
||||
|
||||
// The catalog graph (novox/hq ADR 0656; design 47, *Two graphs, one source of truth*): at each revision one entry per
|
||||
@@ -22,13 +24,24 @@ import (
|
||||
const CatalogEntryLayout = 1
|
||||
|
||||
// CatalogEntryOf is the catalog graph entry of one module: the module graph's node of it as a recompute computed it
|
||||
// (its build, provision and verb edges, the verb edges left out on a cycle, ADR 0614), with where the trunk holds it and
|
||||
// its manifest's digest and the main package its process runs (MainOf). The verdict and the acting rules are the revision's to add (they are not the node's).
|
||||
// (its build, provision and verb edges, the verb edges left out on a cycle, ADR 0614), with where the trunk holds it,
|
||||
// its manifest's digest and verdict, the main package its process runs (MainOf), the package versions it builds against
|
||||
// and what the indexer computes its next revision from (Inputs: the lead's ruling on milestone 47/G finding 1), so that
|
||||
// ModuleValueOf gives the module's value back from the entry alone. The acting rules are the revision's to add.
|
||||
func CatalogEntryOf(module string, cur meshcatalog.ModulesByModuleValue, m catalogue.Manifest, n graph.Node) meshcatalog.CatalogEntry {
|
||||
e := meshcatalog.CatalogEntry{V: CatalogEntryLayout, Module: module, Repository: cur.Repository, Path: cur.Path,
|
||||
Commit: cur.Commit, Manifest: cur.Manifest, Fp: n.FP, None: n.None, Bases: n.Bases, Packages: n.Packages,
|
||||
Provides: n.Provides, Requires: n.Requires, Awaits: n.Awaits, Invokes: n.Invokes, Serves: n.Serves, LeftOut: n.LeftOut,
|
||||
Main: MainOf(m)}
|
||||
Commit: cur.Commit, Manifest: cur.Manifest, Verdict: cur.Verdict, Fp: n.FP, None: n.None, Bases: n.Bases,
|
||||
Packages: maps.Clone(cur.Packages), Provides: n.Provides, Requires: n.Requires, Awaits: n.Awaits, Invokes: n.Invokes,
|
||||
Serves: n.Serves, LeftOut: n.LeftOut, Main: MainOf(m)}
|
||||
in := meshcatalog.EntryInputs{Toolchains: maps.Clone(cur.Toolchains), Paths: maps.Clone(cur.Paths), Problems: cur.Problems,
|
||||
Warnings: cur.Warnings, Unknown: cur.Unknown, Src: cur.Src, FpSrc: cur.FpSrc}
|
||||
if cur.Inputs2 != nil {
|
||||
from := meshcatalog.FingerprintInputs(*cur.Inputs2)
|
||||
in.From = &from
|
||||
}
|
||||
if !reflect.ValueOf(in).IsZero() {
|
||||
e.Inputs = &in
|
||||
}
|
||||
for language, t := range n.Toolchains {
|
||||
if e.Toolchains == nil {
|
||||
e.Toolchains = map[string]meshcatalog.BuildEdge{}
|
||||
@@ -38,6 +51,24 @@ func CatalogEntryOf(module string, cur meshcatalog.ModulesByModuleValue, m catal
|
||||
return e
|
||||
}
|
||||
|
||||
// ModuleValueOf is the module's value as the indexer computes with it, read back from its catalog graph entry: the
|
||||
// inverse of CatalogEntryOf, by which the indexer's view of the trunk is the newest trunk revision's entries (the lead's
|
||||
// ruling on milestone 47/G finding 1; ADR 0656 §6: one form of the fact). The old line's fields (the old-form
|
||||
// fingerprint, the reader needs) are not kept.
|
||||
func ModuleValueOf(e meshcatalog.CatalogEntry) meshcatalog.ModulesByModuleValue {
|
||||
v := meshcatalog.ModulesByModuleValue{V: keys.Version, Repository: e.Repository, Path: e.Path, Commit: e.Commit, Manifest: e.Manifest,
|
||||
Verdict: e.Verdict, Fp2: e.Fp, None2: e.None, Packages: maps.Clone(e.Packages)}
|
||||
if in := e.Inputs; in != nil {
|
||||
v.Toolchains, v.Paths, v.Problems, v.Warnings, v.Unknown = maps.Clone(in.Toolchains), maps.Clone(in.Paths), in.Problems, in.Warnings, in.Unknown
|
||||
v.Src, v.FpSrc = in.Src, in.FpSrc
|
||||
if in.From != nil {
|
||||
from := meshcatalog.ModulesByModuleValueInputs2(*in.From)
|
||||
v.Inputs2 = &from
|
||||
}
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// EncodeEntry is an entry's bytes and their sha256 in hex, the name of its object: the same entry in two revisions is
|
||||
// one object (design 47, *An unchanged entry is stored once*).
|
||||
func EncodeEntry(e meshcatalog.CatalogEntry) (string, []byte, error) {
|
||||
|
||||
@@ -176,9 +176,19 @@ func (ix *Indexer) keepTrunkRevision(ctx context.Context, edges map[string]graph
|
||||
if ix.Revisions == nil {
|
||||
return nil
|
||||
}
|
||||
// Each entry is the module's value as this recompute left it in modules (its fingerprint, toolchains, package versions
|
||||
// and inputs written), so the revision holds what the next one is computed from.
|
||||
held, err := ix.heldModules(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
entries := make(map[string]meshcatalog.CatalogEntry, len(edges))
|
||||
for name, e := range edges {
|
||||
entries[name] = CatalogEntryOf(name, e.cur, e.manifest, whole[name])
|
||||
cur, ok := held[name]
|
||||
if !ok {
|
||||
cur = e.cur
|
||||
}
|
||||
entries[name] = CatalogEntryOf(name, cur, e.manifest, whole[name])
|
||||
}
|
||||
ix.mu.Lock()
|
||||
src := int64(ix.source.rev)
|
||||
|
||||
@@ -308,6 +308,19 @@ func TestBasesAreComputedFirstAndNoFingerprintTakesTheBuilder(t *testing.T) { //
|
||||
e.Toolchains["go"] != (meshcatalog.BuildEdge{Module: "mesh-build-go", Version: "go1.27.1", Recipe: "1"}) {
|
||||
t.Errorf("the catalog entry of avahi = %+v", e)
|
||||
}
|
||||
// W3.1's inputs (the lead's ruling on finding 1): an entry carries what the next revision is computed from (the
|
||||
// fingerprint's inputs, the toolchains used, the package versions), so the module's value read back from it is the
|
||||
// value modules held, but for the old line's fields.
|
||||
for name := range mods.vals {
|
||||
m, _ := moduleOf(t, mods, name)
|
||||
m.Fp, m.None, m.Needs = "", "", nil
|
||||
if back := ModuleValueOf(entries[name]); !reflect.DeepEqual(back, m) {
|
||||
t.Errorf("%s read back from its entry = %+v, want %+v", name, back, m)
|
||||
}
|
||||
}
|
||||
if e := entries["avahi"]; e.Inputs == nil || e.Inputs.From == nil || e.Inputs.Toolchains["go"].Version != "go1.27.1" {
|
||||
t.Errorf("the catalog entry of avahi carries inputs %+v, want what its fingerprint is computed from", e.Inputs)
|
||||
}
|
||||
rev, objects, err := CatalogRevisionOf(meshcatalog.CatalogRevision{Revision: 1, Kind: "trunk", Source: 7}, entries)
|
||||
if err != nil || len(rev.Entries) != len(mods.vals) || len(objects) != len(mods.vals) || rev.V != CatalogEntryLayout {
|
||||
t.Fatalf("revision %+v with %d objects (%v), want one entry per module of %d", rev, len(objects), err, len(mods.vals))
|
||||
|
||||
Reference in New Issue
Block a user