Merge branch 'b7k/registry' into b7l/registry

This commit is contained in:
2026-11-05 16:17:33 +01:00
9 changed files with 43 additions and 51 deletions
@@ -8,7 +8,7 @@ import (
"sync"
"time"
"git.novox.be/novox/mesh-delivery/sdk/buildlog"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
@@ -33,7 +33,7 @@ func NewBuilds() *Builds { return &Builds{records: map[string]delivery.BuildReco
// *The node-engine's own build*) is no build and is passed over, whatever its form. A build's entry that does not read, or
// names no module or repository, is refused and said.
func (b *Builds) Put(value []byte) error {
if !buildlog.IsBuildEntry(value) {
if !builds.IsBuildEntry(value) {
return nil
}
e, err := delivery.DecodeBuildLogEntry(value)
@@ -7,7 +7,7 @@ import (
"slices"
"strings"
"git.novox.be/novox/mesh-delivery/sdk/buildlog"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"git.novox.be/novox/mesh-sdk/go/delivery"
"mesh-delivery-indexer/internal/fingerprint"
@@ -25,7 +25,7 @@ import (
// Imports that cannot be resolved (a package the forge cannot list) are kept with no ImportForm: the next recompute that
// resolves them writes the import form, one rebuild too many, never a stale module.
func (ix *Indexer) ApplyBuildEnd(ctx context.Context, value []byte) error {
if !buildlog.IsBuildEntry(value) {
if !builds.IsBuildEntry(value) {
return nil
}
e, err := delivery.DecodeBuildLogEntry(value)
@@ -14,8 +14,8 @@ import (
"sync/atomic"
"time"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-indexer/takein"
"git.novox.be/novox/mesh-delivery/sdk/buildlog"
stdio "git.novox.be/novox/mesh-sdk/go"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
@@ -912,7 +912,7 @@ func (r Reader) BuildHistory(module string, since time.Time) (HistoryAnswer, err
}
var entries []delivery.BuildLogEntry
for _, le := range page.Entries {
if !buildlog.IsBuildEntry(le.Value) {
if !builds.IsBuildEntry(le.Value) {
continue // an entry of another kind (the old reference form's close, design 51) is no build
}
e, err := delivery.DecodeBuildLogEntry(le.Value)
-21
View File
@@ -1,21 +0,0 @@
// Package buildlog reads the builder's log as mesh-delivery's parts that follow it read it: the indexer and the view.
package buildlog
import (
"encoding/json"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
// IsBuildEntry says whether an entry of the builder's log is a build's start or end, read from its event alone, so an
// entry of another kind (a build's narration, build.said) is passed over before its form is read. One whose event
// cannot be read is taken as a build's, so its decoding says what is wrong with it.
func IsBuildEntry(value []byte) bool {
var e struct {
Event *string `json:"event"`
}
if json.Unmarshal(value, &e) != nil || e.Event == nil {
return true
}
return *e.Event == delivery.BuildStartedEvent || *e.Event == delivery.BuildEndedEvent
}
+18 -7
View File
@@ -1,7 +1,7 @@
// Package forms holds the artifact reference forms the builder writes a done build key in and the assigner holds a want
// by (novox/hq ADR 0618 §1-§2, ADR 0624): logic only those two modules of mesh-delivery share, so it is mesh-delivery's
// and not mesh-sdk's (ADR 0593 §1, ADR 0608 §5). The build key's fields (delivery.BuilderBuild.Needs,
// delivery.BuiltArtifact.References) are the contract, in mesh-sdk.
// and not mesh-sdk's (ADR 0593 §1, ADR 0608 §5). The build key's fields (BuilderBuild.Needs,
// BuiltArtifact.References) are the builder's, in its package `builds`.
package forms
import (
@@ -10,10 +10,21 @@ import (
"strings"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
// artifactStore opens the artifact store's references (delivery.BuiltArtifact).
// BuiltArtifact is one artifact of a done build, as the forms read it: its name, kind, digest and the reference that names
// where it is, with every form it is named in (References, Reference among them; novox/hq ADR 0618, ADR 0624). A reader
// that does not know References reads Reference alone. The builder's build key holds the same fields (its package
// `builds`), whose type is this one, since both read the forms and the forms are logic of the sdk alone.
type BuiltArtifact struct {
Name string `json:"name"`
Kind string `json:"kind,omitempty"`
Digest string `json:"digest"`
Reference string `json:"reference,omitempty"`
References []string `json:"references,omitempty"`
}
// artifactStore opens the artifact store's references (BuiltArtifact).
const artifactStore = "artifact-store://"
// The artifact reference forms (novox/hq ADR 0605 §9, ADR 0618 §1-§2, ADR 0624): each form a done key's reference may be
@@ -55,7 +66,7 @@ type ArtifactForm struct {
// ArtifactForms are the forms a builder knows, oldest first.
type ArtifactForms []ArtifactForm
// Current are the forms the builder writes and the assigner knows: the three first forms (delivery.BuiltArtifact's
// Current are the forms the builder writes and the assigner knows: the three first forms (BuiltArtifact's
// reference by kind), then the registry seat's form of a bundle or an archive.
var Current = ArtifactForms{
// The registry form precedes the artifact-store form: what a build key kept of an image is recorded without the
@@ -105,7 +116,7 @@ func (fs ArtifactForms) Reads(stated []string, form string) bool {
// Needs are the reader capabilities a done build's artifacts carry (ADR 0618 §1): `form:<name>` of every form any of
// its references, single or listed, is written in, sorted. Nil when it names none (no artifact, or no reference).
func (fs ArtifactForms) Needs(artifacts []delivery.BuiltArtifact) []string {
func (fs ArtifactForms) Needs(artifacts []BuiltArtifact) []string {
set := map[string]bool{}
for _, a := range artifacts {
for _, r := range append([]string{a.Reference}, a.References...) {
@@ -206,7 +217,7 @@ func (fs ArtifactForms) Kept(kind string, present, counted map[string][]string)
// its first answered in Reference, since a key names where its artifact is (ADR 0498 clause 1). An answered reference
// in a form that derives an older one (ArtifactForm.Older) answers that older one too, so the build answers one form and
// the key keeps each a counted node reads.
func (fs ArtifactForms) Choose(a delivery.BuiltArtifact, answered []string, present, counted map[string][]string) delivery.BuiltArtifact {
func (fs ArtifactForms) Choose(a BuiltArtifact, answered []string, present, counted map[string][]string) BuiltArtifact {
kept := fs.Kept(a.Kind, present, counted)
answered = fs.withOlder(a.Kind, answered)
type ref struct {
+1
View File
@@ -9,6 +9,7 @@ require git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshcondi
require git.novox.be/novox/mesh-contracts/go v0.0.0-20261104174344-ae5266e77639 // indirect
require (
git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient v0.0.0-00010101000000-000000000000
git.novox.be/novox/mesh-contracts/go/seats/nodeengine v0.0.0-20261104174344-ae5266e77639
github.com/klauspost/compress v1.20.1 // indirect
github.com/nats-io/nats.go v1.54.0 // indirect
+13 -12
View File
@@ -9,8 +9,9 @@ import (
"slices"
"strings"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/sdk/trunk"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"git.novox.be/novox/mesh-sdk/go/delivery"
nodeengine "git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
)
@@ -37,9 +38,9 @@ func decode(data []byte, into *Node) error {
return nil
}
// checkName refuses a module name a key cannot hold (delivery.ModulesKey's rule).
// checkName refuses a module name a key cannot hold (meshcatalogclient.ModulesKey's rule).
func checkName(kind, name string) error {
if _, err := delivery.ModulesKey(name); err != nil {
if _, err := meshcatalogclient.ModulesKey(name); err != nil {
return fmt.Errorf("graph: the %s name %q: %w", kind, name, err)
}
return nil
@@ -67,15 +68,15 @@ const (
// State is the name of the indexer's state of the module graph, as its manifest declares it, and Bucket its
// bucket: one key per module (Key).
State = "graph"
Bucket = delivery.IndexerModule + "_" + State
Bucket = meshcatalogclient.Module + "_" + State
// Read is the line a reader's manifest names in `reads` to read the graph.
Read = delivery.IndexerModule + "." + State
Read = meshcatalogclient.Module + "." + State
// History is the revisions the graph state keeps per key (ADR 0603 §2).
History = 5
)
// Key is the key, in Bucket, of a module: `<module>`, as ModulesKey.
func Key(module string) (string, error) { return delivery.ModulesKey(module) }
func Key(module string) (string, error) { return meshcatalogclient.ModulesKey(module) }
// ParseKey is the inverse of Key.
func ParseKey(key string) (string, error) {
@@ -131,8 +132,8 @@ func (g Node) check() error {
switch {
case (g.FP == "") == (g.None == ""):
return fmt.Errorf("graph: a graph node has either a fingerprint or a reason for none, not both or neither")
case g.FP != "" && !strings.HasPrefix(g.FP, delivery.SourcePrefix2):
return fmt.Errorf("graph: the graph node's fingerprint %q does not start with %s", g.FP, delivery.SourcePrefix2)
case g.FP != "" && !strings.HasPrefix(g.FP, meshcatalogclient.SourcePrefix2):
return fmt.Errorf("graph: the graph node's fingerprint %q does not start with %s", g.FP, meshcatalogclient.SourcePrefix2)
}
if err := checkRepository(g.Repository); err != nil {
return err
@@ -143,7 +144,7 @@ func (g Node) check() error {
}
}
for _, p := range g.Packages {
if _, _, ok := delivery.PackageRepository(p); !ok {
if _, _, ok := trunk.PackageRepository(p); !ok {
return fmt.Errorf("graph: the graph node's package %q is no mesh package's path", p)
}
}
@@ -269,12 +270,12 @@ func (g Graph) Requirers(provision string) []string {
// the module whose directory is the package's directory or the nearest one above it (the longest match, a package
// published from inside a module's directory belonging to that module), or "" when the graph holds none.
func (g Graph) Publisher(pkg string) string {
repository, dir, ok := delivery.PackageRepository(pkg)
repository, dir, ok := trunk.PackageRepository(pkg)
if !ok {
return ""
}
if dir == "" {
dir = delivery.RootPath
dir = meshcatalogclient.RootPath
}
best, bestLen := "", -1
for _, name := range slices.Sorted(maps.Keys(g)) {
@@ -285,7 +286,7 @@ func (g Graph) Publisher(pkg string) string {
switch {
case n.Path == dir:
return name
case n.Path == delivery.RootPath:
case n.Path == meshcatalogclient.RootPath:
if bestLen < 0 {
best, bestLen = name, 0
}
+2 -2
View File
@@ -9,8 +9,8 @@ import (
"testing"
nodeengine "git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
// TestGraphEdges: the module graph's cycle, dependents and providers, each from the edges alone (ADR 0603 §2, ADR 0604 §1).
@@ -30,7 +30,7 @@ func TestGraphEdges(t *testing.T) {
// A base chain, a package and a build module: app stands on base, imports lib's package, is built by build-go.
g := Graph{
"build-go": node("novox/mesh-catalog", "modules/build-go", func(n *Node) { n.Toolchains = gotool }),
"lib": node("novox/lib", delivery.RootPath, nil),
"lib": node("novox/lib", meshcatalogclient.RootPath, nil),
"base": node("novox/mesh-catalog", "modules/base", nil),
"app": node("novox/mesh-catalog", "modules/app", func(n *Node) {
n.Bases, n.Packages, n.Toolchains = []string{"base"}, []string{"git.novox.be/novox/lib"}, gotool
+3 -3
View File
@@ -12,15 +12,15 @@ import (
"path"
"strings"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
// ReadFile reads one file of a repository at a commit; a file the commit does not hold is nil with no error.
type ReadFile func(ctx context.Context, repository, commit, file string) ([]byte, error)
// Of is a package artifact's name in its ecosystem, read at commit from the first of its paths (or the module's directory
// dir, delivery.RootPath or empty for the repository's root) that holds its go.mod (Go) or package.json (TypeScript). A
// dir, meshcatalogclient.RootPath or empty for the repository's root) that holds its go.mod (Go) or package.json (TypeScript). A
// file read that fails, a go.mod that names no module and a package.json that names no name are errors, said.
func Of(ctx context.Context, read ReadFile, repository, commit, dir string, a catalogue.Artifact) (string, error) {
file := "package.json"
@@ -28,7 +28,7 @@ func Of(ctx context.Context, read ReadFile, repository, commit, dir string, a ca
file = "go.mod"
}
base := dir
if base == delivery.RootPath {
if base == meshcatalogclient.RootPath {
base = ""
}
roots := a.Paths