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 `:` 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 } }