Join: one buildstep Toolchain (the seats' value) under the agreement rule; the packages key is the seat's key form (ADR 0634 §2; issue 1966)

This commit is contained in:
2026-11-05 16:33:43 +01:00
parent 4bbb809ef1
commit 9ffdaca898
4 changed files with 21 additions and 12 deletions
@@ -22,7 +22,7 @@ func PackagesKey(module string) (string, error) {
if _, _, ok := trunk.PackageRepository(module); !ok {
return "", fmt.Errorf("index: %q is no mesh Go module's path (it starts with %s)", module, trunk.ForgeModulePrefix)
}
return keys.EscapeName(module), nil
return meshcatalog.PackagesByModuleKey(keys.EscapeName(module)), nil
}
func checkPublished(p meshcatalog.PackagesByModuleValue) error {
@@ -4,6 +4,7 @@ import (
"fmt"
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/sdk/trunk"
"git.novox.be/novox/mesh-sdk/go/keys"
)
@@ -84,5 +85,5 @@ func PackagesKey(module string) (string, error) {
if _, _, ok := trunk.PackageRepository(module); !ok {
return "", fmt.Errorf("view: %q is no mesh Go module's path", module)
}
return keys.EscapeName(module), nil
return meshcatalog.PackagesByModuleKey(keys.EscapeName(module)), nil
}
@@ -13,7 +13,9 @@ import (
"strings"
"testing"
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-view/viewstate"
"git.novox.be/novox/mesh-sdk/go/keys"
)
// The controller's manifest reader is mesh-controller internal/catalogue (ParseManifest), an internal package of another
@@ -179,6 +181,16 @@ func TestManifestIsTakenAndReadsOnly(t *testing.T) { // 1134/AC7
if viewstate.ViewModule != m.Module || viewstate.ViewAnswersBucket != m.Module+"_answers" || viewstate.ReachBucket != m.Module+"_reach" {
t.Errorf("the view names itself %s (%s, %s), its manifest %s", viewstate.ViewModule, viewstate.ViewAnswersBucket, viewstate.ReachBucket, m.Module)
}
// The packages key is the seat's key of its state packages for a module (<module>), as the indexer writes it: the
// escaped path, with no dot, so a reader never takes it for a <package>.<series> key.
const path = "git.novox.be/novox/mesh-sdk/go"
key, err := view.PackagesKey(path)
if want := meshcatalog.PackagesByModuleKey(keys.EscapeName(path)); err != nil || key != want || strings.Contains(key, ".") {
t.Errorf("the packages key of %s is %q (%v), the seat's is %q", path, key, err, want)
}
if module, ok := meshcatalog.ParsePackagesByModuleKey(key); !ok || module != keys.EscapeName(path) {
t.Errorf("the seat does not read %q as a module key: %q %v", key, module, ok)
}
})
for _, a := range m.Build.Artifacts {
// A bundle compiled to a binary is one executable: what the runtime loads is that binary's name, or the controller's
+6 -10
View File
@@ -13,13 +13,9 @@ import (
// ToolchainNoReport is the reason AgreedToolchain gives when no node has reported a language's toolchain.
const ToolchainNoReport = "toolchain not yet reported"
// Toolchain is what a toolchain is identified by: the language, the installed version and the build module's recipe
// version. It has the fields of the mesh-catalog client's Toolchain2, which a caller converts it to.
type Toolchain struct {
Language string
Version string
Recipe string
}
// toolchainID is what a toolchain is identified by: the language, the installed version and the build module's recipe
// version (a Toolchain's other fields, its layout version and its time, do not tell two toolchains apart).
type toolchainID struct{ Language, Version, Recipe string }
// NodeToolchain is one node's entry of a language, as read from a build seat's state toolchains.
type NodeToolchain struct {
@@ -52,14 +48,14 @@ func ToolchainAgreement(entries []NodeToolchain) Agreement {
if len(entries) == 0 {
return Agreement{Wait: ToolchainNoReport}
}
groups := map[Toolchain][]string{}
groups := map[toolchainID][]string{}
for _, e := range entries {
k := Toolchain{Language: e.Language, Version: e.Version, Recipe: e.Recipe}
k := toolchainID{Language: e.Language, Version: e.Version, Recipe: e.Recipe}
groups[k] = append(groups[k], e.Node)
}
for k, nodes := range groups {
if 2*len(nodes) > len(entries) {
a := Agreement{Toolchain: k}
a := Agreement{Toolchain: Toolchain{Language: k.Language, Version: k.Version, Recipe: k.Recipe}}
for _, e := range entries {
if e.Version != k.Version || e.Recipe != k.Recipe {
a.SittingOut = append(a.SittingOut, SittingOut{Node: e.Node, Version: e.Version, Recipe: e.Recipe})