The builder, its tools bundle, the assigner (process and bundle) and the view's tools bundle answered their seat list's again tool to the modules node-tools and mesh-healers. Their lists are now the operator, seat:node-tool-runner and seat:mesh-healers, resolved by a holder function: - meshcatalogclient's Branches.Claimant (moved from the builder's versions.HolderOf, which now asks it) names the claimant of mesh-module-assigner from the trunk's half, and Branches.SeatHolders follows that claimant's seat-holders view through the part's wiring. It drops the view and follows the new claimant's on a catalog change, asks nothing on a timer, and answers seatlist.HoldersIn. - the assigner answers HoldersIn from its own seat-holders picture (its world in the process, the watched copy in the bundle). The builder's and the view's manifests consume seat:mesh-module-assigner.views.seat-holders. The assigner's seat-holders first-view tool answers both, by module as A-131 has it. Builds: design 47 G A-298, A-295, A-296, A-210, A-131, §717, §616, §614 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
106 lines
3.9 KiB
Go
106 lines
3.9 KiB
Go
package versions
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
"strings"
|
|
|
|
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/clients/meshcatalogclient"
|
|
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/seats/meshcatalog"
|
|
)
|
|
|
|
// Entries are the catalog graph entries of the halves the builder follows, one per module and watched branch (design 47 G §348,
|
|
// §614): where a package's name in its ecosystem is read from, each artifact's `package` (§676), never the indexer's state.
|
|
type Entries func() []meshcatalog.CatalogEntry
|
|
|
|
// artifactOf is the artifact name of an artifact reference `<module>:<artifact>` of module.
|
|
func artifactOf(module, ref string) (string, bool) {
|
|
m, a, ok := strings.Cut(ref, ":")
|
|
return a, ok && m == module && a != ""
|
|
}
|
|
|
|
// NamesFrom answers a package's name in its ecosystem from the entries (design 47 G §348): the name the entry of module gives the
|
|
// artifact; known is false when no entry names one for it.
|
|
func NamesFrom(all Entries) PackageNames {
|
|
return func(_ context.Context, module, artifact string) (string, bool, error) {
|
|
for _, e := range all() {
|
|
if e.Module != module {
|
|
continue
|
|
}
|
|
for _, a := range e.Artifacts {
|
|
if name, ok := artifactOf(module, a.Ref); ok && name == artifact && a.Package != nil && a.Package.Name != "" {
|
|
return a.Package.Name, true, nil
|
|
}
|
|
}
|
|
}
|
|
return "", false, nil
|
|
}
|
|
}
|
|
|
|
// CarriersFrom are the module artifacts a package's name in its ecosystem is the name of, as the entries hold them (design 47 G
|
|
// §572, §478), each distinct module and artifact once, sorted; a name no entry carries answers none.
|
|
func CarriersFrom(all Entries) func(ctx context.Context, name string) ([]Built, error) {
|
|
return func(_ context.Context, name string) ([]Built, error) {
|
|
seen := map[Built]bool{}
|
|
var out []Built
|
|
for _, e := range all() {
|
|
for _, a := range e.Artifacts {
|
|
artifact, ok := artifactOf(e.Module, a.Ref)
|
|
if !ok || a.Package == nil || a.Package.Name != name || seen[Built{e.Module, artifact}] {
|
|
continue
|
|
}
|
|
seen[Built{e.Module, artifact}] = true
|
|
out = append(out, Built{e.Module, artifact})
|
|
}
|
|
}
|
|
sort.Slice(out, func(i, j int) bool { return out[i].Module+"/"+out[i].Artifact < out[j].Module+"/"+out[j].Artifact })
|
|
return out, nil
|
|
}
|
|
}
|
|
|
|
// ModuleFrom is the module and artifact a package's name is built from, from the entries (CarriersFrom); more than one entry
|
|
// carrying it is an error naming them.
|
|
func ModuleFrom(all Entries) func(ctx context.Context, name string) (module, artifact string, found bool, err error) {
|
|
return moduleOfCarriers(CarriersFrom(all))
|
|
}
|
|
|
|
// EntriesOf are the entries of every half the branch follower holds, the followed branches in the order they came.
|
|
func EntriesOf(branches *meshcatalogclient.Branches) Entries {
|
|
return func() []meshcatalog.CatalogEntry {
|
|
var out []meshcatalog.CatalogEntry
|
|
for _, br := range branches.Followed() {
|
|
if cat, ok := branches.Catalog(br); ok {
|
|
if half, ok := cat.View(); ok {
|
|
for _, e := range half.Entries {
|
|
out = append(out, e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
}
|
|
|
|
// HolderOf finds the module that holds a seat: its claimant in the trunk's half, as meshcatalogclient's Branches.Claimant
|
|
// answers it (design 47 G A-82, A-298).
|
|
func HolderOf(branches *meshcatalogclient.Branches) func(seat string) (string, bool) {
|
|
return branches.Claimant
|
|
}
|
|
|
|
// RequirementsFrom answers the versions of a package the entries of every followed half require, each once, in order: what a
|
|
// consumer's entry names for it in its packages (design 47 G A-119), the floor's third source.
|
|
func RequirementsFrom(all Entries) func(ctx context.Context, name string) ([]string, error) {
|
|
return func(_ context.Context, name string) ([]string, error) {
|
|
seen := map[string]bool{}
|
|
var out []string
|
|
for _, e := range all() {
|
|
if v := e.Packages[name]; v != "" && !seen[v] {
|
|
seen[v] = true
|
|
out = append(out, v)
|
|
}
|
|
}
|
|
sort.Strings(out)
|
|
return out, nil
|
|
}
|
|
}
|