Fill the catalog's versions from every number the builder gave, numbered or published (design 47 G §372, A-350)
The builder numbers fresh versions without publishing them, so a fill from published alone would number again below what the builder already said, and one version would name two contents. The fill and its kind 1 and 3 edges take numbered and published alike; the version-form check and the claimed cut stay. A version the builder numbered without a digest is filled with none. Builds: design 47 G §372, A-350, A-351 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -17,9 +17,9 @@ import (
|
||||
)
|
||||
|
||||
// The first fill of the versions (design 47 G §372): at the first start under G the state versions is filled once, as
|
||||
// released, for each module from the highest published version over every artifact of the module that the builder's state
|
||||
// versions held, read by the builder's tool builder_versions as a kept call; then versions-filled is said once, and the
|
||||
// builder reserves nothing before it (§369).
|
||||
// released, for each module from the highest version over every artifact of the module that the builder's state versions
|
||||
// gave a number, numbered or published (A-350), read by the builder's tool builder_versions as a kept call; then
|
||||
// versions-filled is said once, and the builder reserves nothing before it (§369).
|
||||
const (
|
||||
// BuilderVersionsCall is the tool the manifest names in its invokes (until that tool goes).
|
||||
BuilderVersionsCall = "mesh-delivery-builder.builder_versions"
|
||||
@@ -39,6 +39,11 @@ type BuilderVersion struct {
|
||||
At time.Time `json:"at"`
|
||||
}
|
||||
|
||||
// givenANumber says whether the builder's state versions gave the version its number: numbered, or numbered and then
|
||||
// published (A-350: the builder numbers fresh versions it has not published, so a fill from published alone would number
|
||||
// again below what the builder already said).
|
||||
func givenANumber(state string) bool { return state == "numbered" || state == "published" }
|
||||
|
||||
// BuilderVersionsAnswer is what builder_versions answers for a name.
|
||||
type BuilderVersionsAnswer struct {
|
||||
Name string `json:"name"`
|
||||
@@ -90,10 +95,10 @@ func (ix *Indexer) FillVersions(ctx context.Context, ask VersionsAsker) error {
|
||||
name string
|
||||
ref string
|
||||
}
|
||||
best := map[string][]found1{} // by module: each artifact's highest published version
|
||||
best := map[string][]found1{} // by module: each artifact's highest numbered or published version (A-350)
|
||||
var unanswered error
|
||||
for _, e := range entries {
|
||||
var top string // the module's highest published version
|
||||
var top string // the module's highest version the builder gave a number, numbered or published (A-350)
|
||||
per := []found1{}
|
||||
for _, a := range e.Artifacts {
|
||||
name := versionNameOf(e.Module, a)
|
||||
@@ -106,7 +111,7 @@ func (ix *Indexer) FillVersions(ctx context.Context, ask VersionsAsker) error {
|
||||
continue
|
||||
}
|
||||
for _, v := range ans.Versions {
|
||||
if _, ok := versionParts(v.Version); !ok || v.State != "published" {
|
||||
if _, ok := versionParts(v.Version); !ok || !givenANumber(v.State) {
|
||||
continue
|
||||
}
|
||||
per = append(per, found1{v: v, name: name, ref: a.Ref})
|
||||
|
||||
@@ -66,7 +66,7 @@ func (ix *Indexer) filledEdges(ctx context.Context, entry meshcatalog.CatalogEnt
|
||||
}
|
||||
var best *BuilderVersion
|
||||
for i, v := range ans.Versions {
|
||||
if _, ok := versionParts(v.Version); !ok || v.State != "published" || v.At.After(claimed) {
|
||||
if _, ok := versionParts(v.Version); !ok || !givenANumber(v.State) || v.At.After(claimed) {
|
||||
continue
|
||||
}
|
||||
if best == nil || v.At.After(best.At) {
|
||||
|
||||
@@ -87,10 +87,10 @@ func TestAVersionIsReleasedOnceEveryArtifactIsPublished(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Design 47 G §372: the first fill records, once, each module's highest published version over its artifacts as released
|
||||
// and says versions-filled once; a builder_versions that does not answer holds it and, after five minutes, is the finding
|
||||
// Design 47 G §372, A-350: the first fill records, once, each module's highest version the builder gave a number, numbered or
|
||||
// published, over its artifacts as released and says versions-filled once; a builder_versions that does not answer holds it and, after five minutes, is the finding
|
||||
// call-unanswered; a fill made is not made again.
|
||||
func TestTheFirstFillOfTheVersionsComesFromTheBuildersPublished(t *testing.T) {
|
||||
func TestTheFirstFillOfTheVersionsComesFromTheBuildersNumbers(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
now := time.Date(2026, 11, 1, 3, 0, 0, 0, time.UTC)
|
||||
w := newFindings()
|
||||
@@ -128,7 +128,8 @@ func TestTheFirstFillOfTheVersionsComesFromTheBuildersPublished(t *testing.T) {
|
||||
case "@novox/mesh-sdk":
|
||||
return BuilderVersionsAnswer{Name: name, Versions: []BuilderVersion{pub("0.1.18", "sha256:ts18")}}, nil
|
||||
case "avahi/image":
|
||||
return BuilderVersionsAnswer{Name: name, Versions: []BuilderVersion{pub("0.2.3", "sha256:av")}}, nil
|
||||
// published 0.1.0, numbered up to 0.1.14 and never published (A-350): the fill starts above 0.1.14
|
||||
return BuilderVersionsAnswer{Name: name, Versions: []BuilderVersion{pub("0.1.0", "sha256:av"), {Version: "0.1.14", State: "numbered", Revision: "9"}}}, nil
|
||||
}
|
||||
return BuilderVersionsAnswer{Name: name}, nil
|
||||
}
|
||||
@@ -157,6 +158,9 @@ func TestTheFirstFillOfTheVersionsComesFromTheBuildersPublished(t *testing.T) {
|
||||
if len(sdk) != 1 || sdk[0].Version != "0.1.18" || len(sdk[0].Artifacts) != 1 || sdk[0].Artifacts[0].Artifact != "mesh-sdk:ts" || sdk[0].Source != 9 {
|
||||
t.Errorf("mesh-sdk's filled version: %+v (the higher of Go's 0.1.14 and npm's 0.1.18)", sdk)
|
||||
}
|
||||
if avahi, _ := ModuleVersions(ctx, ix.Versions, "avahi"); len(avahi) != 1 || avahi[0].Version != "0.1.14" || len(avahi[0].Artifacts) != 1 || avahi[0].Artifacts[0].Digest != "" {
|
||||
t.Errorf("avahi's filled version: %+v (numbered 0.1.14 above published 0.1.0, so the first G build of 0.1 is 0.1.15, with no digest where the builder kept none, A-351)", avahi)
|
||||
}
|
||||
if fresh, _ := ModuleVersions(ctx, ix.Versions, "fresh"); len(fresh) != 0 {
|
||||
t.Errorf("a module with none published is filled: %+v", fresh)
|
||||
}
|
||||
@@ -462,7 +466,8 @@ func TestTheFirstFillGivesTheNewestVersionsTheirFilledEdges(t *testing.T) {
|
||||
}
|
||||
switch name {
|
||||
case "x/lib":
|
||||
return BuilderVersionsAnswer{Versions: []BuilderVersion{pub("0.1.1", "sha256:l1", t0), pub("0.1.2", "sha256:l2", t0.Add(2*time.Hour))}}, nil
|
||||
// 0.1.1 numbered and not published still counts (A-350)
|
||||
return BuilderVersionsAnswer{Versions: []BuilderVersion{{Version: "0.1.1", State: "numbered", Digest: "sha256:l1", Revision: "9", At: t0}, pub("0.1.2", "sha256:l2", t0.Add(2*time.Hour))}}, nil
|
||||
case "app/program":
|
||||
return BuilderVersionsAnswer{Versions: []BuilderVersion{pub("0.3.1", "sha256:a1", t0.Add(time.Hour))}}, nil
|
||||
}
|
||||
@@ -482,7 +487,7 @@ func TestTheFirstFillGivesTheNewestVersionsTheirFilledEdges(t *testing.T) {
|
||||
switch e.Kind {
|
||||
case 1:
|
||||
if e.Version != "0.1.1" || e.Digest != "sha256:l1" || !e.Stale {
|
||||
t.Errorf("kind 1 is the version published before the build was claimed: %+v", e)
|
||||
t.Errorf("kind 1 is the version numbered or published before the build was claimed: %+v", e)
|
||||
}
|
||||
case 4:
|
||||
if e.Version != "0.9.1" || e.Digest != "sha256:prov/program" {
|
||||
|
||||
Reference in New Issue
Block a user