IX8: a kind-6 edge names the fields a long-form invoke relies on
The entry's manifest is read by the second reader release (RR2-4), and an invoked verb given as {verb, fields} puts the
fields in its edge's `why`.
Builds: design 47 G §558 (A-208)
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -2,11 +2,13 @@ package index
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"encoding/json"
|
||||
"maps"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/seats/meshcatalog"
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
)
|
||||
|
||||
// The edges of a catalog graph entry (design 47 G §47 to §50, §121; A-208): the indexer writes, in each entry of a revision,
|
||||
@@ -116,13 +118,19 @@ func edgesOf(a meshcatalog.CatalogEntry, all map[string]meshcatalog.CatalogEntry
|
||||
}
|
||||
}
|
||||
// Kind 6: a verb or a tool it invokes and another entry serves (§47), unless its edge lies on a cycle and is left out (ADR 0614 §3).
|
||||
// A verb whose answer's fields it relies on (the long form of `invokes`, §558) names them in the edge's `why`.
|
||||
fields := manifestOf(a).InvokeFields
|
||||
for _, verb := range a.Invokes {
|
||||
if slices.Contains(a.LeftOut, verb) {
|
||||
continue
|
||||
}
|
||||
why := verb
|
||||
if named := fields[verb]; len(named) > 0 {
|
||||
why += " fields " + strings.Join(named, ", ")
|
||||
}
|
||||
for _, m := range modules {
|
||||
if b := all[m]; m != a.Module && slices.Contains(b.Serves, verb) {
|
||||
add(meshcatalog.Edge{Kind: 6, From: primaryOf(b), To: delivers, Word: verb, Why: verb})
|
||||
add(meshcatalog.Edge{Kind: 6, From: primaryOf(b), To: delivers, Word: verb, Why: why})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,6 +140,19 @@ func edgesOf(a meshcatalog.CatalogEntry, all map[string]meshcatalog.CatalogEntry
|
||||
return out
|
||||
}
|
||||
|
||||
// manifestOf is the manifest the entry carries whole, read by the manifest reader; none where it cannot be read.
|
||||
func manifestOf(e meshcatalog.CatalogEntry) catalogue.Manifest {
|
||||
raw, err := json.Marshal(e.Manifest)
|
||||
if err != nil {
|
||||
return catalogue.Manifest{}
|
||||
}
|
||||
m, err := catalogue.Decode(raw)
|
||||
if err != nil {
|
||||
return catalogue.Manifest{}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
type need struct{ by, ref string }
|
||||
|
||||
// needsOf are the artifact references each artifact of the entry's manifest names in its `needs`, with the artifact that names them.
|
||||
|
||||
@@ -64,3 +64,17 @@ func TestAKeptRevisionHoldsTheEdgesOfItsEntries(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Design 47 G §558, A-208: a verb invoked in the long form {verb, fields} gives its kind-6 edge the fields it relies on,
|
||||
// read by the second reader release; the short form names none.
|
||||
func TestAKindSixEdgeNamesTheFieldsALongFormInvokeRelies(t *testing.T) {
|
||||
entries := map[string]meshcatalog.CatalogEntry{
|
||||
"holder": {Module: "holder", Artifacts: []meshcatalog.Artifact{{Ref: "holder:p"}}, Serves: []string{"seat:s.list", "seat:s.get"}},
|
||||
"user": {Module: "user", Artifacts: []meshcatalog.Artifact{{Ref: "user:p"}}, Invokes: []string{"seat:s.get", "seat:s.list"},
|
||||
Manifest: map[string]any{"module": "user", "version": "1.0", "invokes": []any{"seat:s.get", map[string]any{"verb": "seat:s.list", "fields": []any{"binding", "node"}}}}},
|
||||
}
|
||||
got := WithEdges(entries)["user"].Edges
|
||||
if len(got) != 2 || got[0].Why != "seat:s.get" || got[1].Why != "seat:s.list fields binding, node" || got[1].Word != "seat:s.list" {
|
||||
t.Errorf("edges %+v, want the short verb as it is and the long form with its fields", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user