Reverts the Go-bundle package of 53caa3ba; the run's program is the directory ./cmd/mesh-judge under the go.mod the build reads. Builds: design 47 G §712, §676, §491, A-268 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
101 lines
4.3 KiB
Go
101 lines
4.3 KiB
Go
package index
|
|
|
|
import (
|
|
"context"
|
|
"maps"
|
|
"slices"
|
|
"strings"
|
|
|
|
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/seats/meshcatalog"
|
|
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/packagename"
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
)
|
|
|
|
// Each entry carries its artifacts' package names (design 47 G §676, §491, §478, §504, §412): at take-in the indexer reads
|
|
// each artifact's package name from the revision's own files at the artifact's path, the module of its go.mod for a Go
|
|
// package, the name of its package.json for an npm package, the module's and the artifact's names joined by / for an image artifact (§694), and writes it into
|
|
// the entry's artifact as package, {ecosystem, name}. The manifest validator judges §491 from these fields.
|
|
|
|
// Package ecosystems of an artifact's package (§676).
|
|
const (
|
|
EcosystemGo = "go"
|
|
EcosystemNpm = "npm"
|
|
// EcosystemImage is an image artifact's package ecosystem (§694).
|
|
EcosystemImage = "image"
|
|
)
|
|
|
|
// ArtifactRefOf is the artifact reference of a module's artifact, <module>:<artifact>.
|
|
func ArtifactRefOf(module, artifact string) string { return module + ":" + artifact }
|
|
|
|
// withArtifacts gives e its manifest's artifacts, by reference, with the package name of each package artifact (an image's is its module's name and its artifact's, §694). A
|
|
// name the forge does not answer is said and left out of the artifact, for the next entry to read again (the cache keeps only
|
|
// what was read); a manifest that does not decode leaves the entry as it is.
|
|
func (ix *Indexer) withArtifacts(ctx context.Context, e meshcatalog.CatalogEntry, m catalogue.Manifest) meshcatalog.CatalogEntry {
|
|
if m.Build == nil {
|
|
return e
|
|
}
|
|
for _, a := range m.Build.Artifacts {
|
|
art := meshcatalog.Artifact{Ref: ArtifactRefOf(e.Module, a.Name), Language: a.Language, Kind: a.Kind}
|
|
if pkg := ix.packageOf(ctx, e, a); pkg != nil {
|
|
art.Package = pkg
|
|
}
|
|
e.Artifacts = append(e.Artifacts, art)
|
|
}
|
|
slices.SortFunc(e.Artifacts, func(a, b meshcatalog.Artifact) int { return strings.Compare(a.Ref, b.Ref) })
|
|
return e
|
|
}
|
|
|
|
// packageOf is the package name of artifact a of the entry e: read through the forge at the entry's commit, kept per
|
|
// repository, commit, path and artifact so a later entry of the same commit reads nothing; nil for an artifact that names
|
|
// none (a program, an archive) or whose name cannot be read now.
|
|
func (ix *Indexer) packageOf(ctx context.Context, e meshcatalog.CatalogEntry, a catalogue.Artifact) *meshcatalog.ArtifactPackage {
|
|
switch a.Kind {
|
|
case catalogue.ArtifactPackage:
|
|
case catalogue.ArtifactImage:
|
|
// An image's package name is its module's name and its artifact's joined by `/`, read from no file (§694).
|
|
return &meshcatalog.ArtifactPackage{Ecosystem: EcosystemImage, Name: e.Module + "/" + a.Name}
|
|
default:
|
|
return nil
|
|
}
|
|
if ix.ReadFile == nil || e.Commit == "" {
|
|
return nil
|
|
}
|
|
ecosystem := EcosystemNpm
|
|
if a.Language == "go" {
|
|
ecosystem = EcosystemGo
|
|
}
|
|
key := e.Repository + "\x00" + e.Commit + "\x00" + e.Path + "\x00" + a.Name
|
|
ix.namesMu.Lock()
|
|
name, ok := ix.packageNames[key]
|
|
ix.namesMu.Unlock()
|
|
if !ok {
|
|
var err error
|
|
if name, err = packagename.Of(ctx, packagename.ReadFile(ix.ReadFile), e.Repository, e.Commit, e.Path, a); err != nil {
|
|
ix.logf("catalog graph: the package name of %s at %.12s is not read, so its entry carries none until the next entry: %v", ArtifactRefOf(e.Module, a.Name), e.Commit, err)
|
|
return nil
|
|
}
|
|
ix.namesMu.Lock()
|
|
if ix.packageNames == nil {
|
|
ix.packageNames = map[string]string{}
|
|
}
|
|
ix.packageNames[key] = name
|
|
ix.namesMu.Unlock()
|
|
}
|
|
return &meshcatalog.ArtifactPackage{Ecosystem: ecosystem, Name: name}
|
|
}
|
|
|
|
// packageEntries is the entry of each module whose manifest decodes, with its artifacts' package names as the take-in reads
|
|
// them, for the judge of §491 to read the names from.
|
|
func (ix *Indexer) packageEntries(ctx context.Context, held map[string]meshcatalog.ModulesByModuleValue, raws map[string][]byte) []meshcatalog.CatalogEntry {
|
|
var out []meshcatalog.CatalogEntry
|
|
for _, name := range slices.Sorted(maps.Keys(raws)) {
|
|
m, err := catalogue.Decode(raws[name])
|
|
if err != nil {
|
|
continue
|
|
}
|
|
cur := held[name]
|
|
out = append(out, ix.withArtifacts(ctx, meshcatalog.CatalogEntry{Module: name, Repository: cur.Repository, Path: cur.Path, Commit: cur.Commit}, m))
|
|
}
|
|
return out
|
|
}
|