indexer: an image artifact's package is {image, module/artifact}

Builds: design 47 G §694

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-11 22:44:38 +01:00
parent 1dcb310184
commit 0dec003660
2 changed files with 27 additions and 4 deletions
@@ -13,19 +13,21 @@ import (
// 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 manifest's name of an image artifact, and writes it into
// 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 name is an open design question: none is written). A
// 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 {
@@ -45,10 +47,13 @@ func (ix *Indexer) withArtifacts(ctx context.Context, e meshcatalog.CatalogEntry
// 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 image, an archive) or whose name cannot be read now.
// 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
}
@@ -63,8 +63,26 @@ func TestAnEntryCarriesItsArtifactsPackageNames(t *testing.T) {
}
got[a.Ref] = name
}
want := map[string]string{"m:gopkg": "go git.example/m/go", "m:jspkg": "npm @example/m", "m:img": "none", "m:prog": "none"}
want := map[string]string{"m:gopkg": "go git.example/m/go", "m:jspkg": "npm @example/m", "m:img": "image m/img", "m:prog": "none"}
if !reflect.DeepEqual(got, want) {
t.Errorf("artifacts' packages %v, want %v (§676)", got, want)
}
}
// Design 47 G §694: an image artifact's package is {image, <module>/<artifact>}, read from no file, so two modules
// with an image artifact of one name carry two package names.
func TestAnImageArtifactsPackageNameIsItsModulesAndItsOwn(t *testing.T) {
ix := &Indexer{}
names := map[string]bool{}
for _, module := range []string{"a", "b"} {
m := catalogue.Manifest{Module: module, Build: &catalogue.Build{Artifacts: []catalogue.Artifact{{Name: "server", Kind: catalogue.ArtifactImage}}}}
e := ix.withArtifacts(context.Background(), meshcatalog.CatalogEntry{Module: module}, m)
if len(e.Artifacts) != 1 || e.Artifacts[0].Package == nil || e.Artifacts[0].Package.Ecosystem != "image" || e.Artifacts[0].Package.Name != module+"/server" {
t.Fatalf("module %s: artifacts %+v, want the package {image, %s/server} (§694)", module, e.Artifacts, module)
}
names[e.Artifacts[0].Package.Name] = true
}
if len(names) != 2 {
t.Errorf("two modules' image artifacts of one name carry %v, want two package names", names)
}
}