diff --git a/go/catalogue/config.go b/go/catalogue/config.go index 9341b4b..14f0508 100644 --- a/go/catalogue/config.go +++ b/go/catalogue/config.go @@ -114,6 +114,7 @@ type configDeclaration struct { Default any `json:"default,omitempty"` Required bool `json:"required,omitempty"` Runtime bool `json:"runtime,omitempty"` + RenamedFrom string `json:"renamed-from,omitempty"` } // MarshalJSON writes a settings declaration exactly as before, and a config declaration without the settings @@ -125,7 +126,7 @@ func (d SettingDeclaration) MarshalJSON() ([]byte, error) { } return json.Marshal(configDeclaration{Type: d.Type, Description: d.Description, Enum: d.Enum, Minimum: d.Minimum, Maximum: d.Maximum, Pattern: d.Pattern, Trusted: d.Trusted, Predefined: d.Predefined, - Default: d.Default, Required: d.Required, Runtime: d.Runtime}) + Default: d.Default, Required: d.Required, Runtime: d.Runtime, RenamedFrom: d.RenamedFrom}) } // validationProblems is what is wrong with a declaration's validation, and its default against it. diff --git a/go/catalogue/config_test.go b/go/catalogue/config_test.go index 338c72a..cc482dc 100644 --- a/go/catalogue/config_test.go +++ b/go/catalogue/config_test.go @@ -132,6 +132,32 @@ func TestAConfigManifestIsWrittenBackInItsOwnForm(t *testing.T) { if !bytes.Equal(raw, twice) { t.Fatalf("read again it is written\n%s\nwhere it was\n%s", twice, raw) } + + // The registry milestone's words round-trip the same (design 32): a config value's old name, an artifact's series + // and contracts marker, the series a module accepts of a package; absent, a series is 0.1. + declared := []byte(`{"module":"c","version":"1","config":{"font":{"type":"string","renamed-from":"font-name"}}, + "packages":{"mesh-sdk":"0.2"}, + "build":{"artifacts":[{"name":"go","kind":"package","language":"go","paths":["go"],"series":"0.2", + "generated-from":"seats"},{"name":"lib","kind":"package","language":"typescript"}]}}`) + m, err = decodeForTest(declared) + if err != nil { + t.Fatal(err) + } + if m.Settings["font"].RenamedFrom != "font-name" || m.AcceptedSeries("mesh-sdk") != "0.2" || + m.AcceptedSeries("mesh-contracts") != DefaultSeries || m.Build.Artifacts[0].SeriesOf() != "0.2" || + m.Build.Artifacts[0].GeneratedFrom != "seats" || m.Build.Artifacts[1].SeriesOf() != "0.1" { + t.Fatalf("read %+v", m) + } + raw, _ = json.Marshal(m) + for _, said := range []string{`"renamed-from":"font-name"`, `"packages":{"mesh-sdk":"0.2"}`, `"series":"0.2"`, + `"generated-from":"seats"`} { + if !strings.Contains(string(raw), said) { + t.Errorf("written back without %s: %s", said, raw) + } + } + if strings.Count(string(raw), `"series"`) != 1 { + t.Errorf("a series nobody said is written: %s", raw) + } } // A module in the settings form is written back byte for byte as before. diff --git a/go/catalogue/manifest.go b/go/catalogue/manifest.go index 485e190..5aecd73 100644 --- a/go/catalogue/manifest.go +++ b/go/catalogue/manifest.go @@ -469,6 +469,11 @@ type Manifest struct { // this is for the rest — `zsh` provides `shell`, `xorg` provides `display-server`. Provides []Offer `json:"provides,omitempty"` + // Packages are the series of each mesh package this module accepts, by the package's name (novox/hq ADR 0606, + // design 32): its fingerprint takes the newest version of that series, and a publish of another series moves it + // not. A package it uses and does not name is accepted in DefaultSeries (AcceptedSeries). + Packages map[string]string `json:"packages,omitempty"` + // Requires are names that must be provided by something assigned to the same node. Requires []string `json:"requires,omitempty"` // OptionalRequires is which of Requires the module can run without (novox/hq ADR 0330): filled @@ -1224,6 +1229,38 @@ type Artifact struct { // paths and constants composed with ${dir:…} and ${port:…} exactly as a container's environment // is, never a secret's content. The node's runtime hands it to this bundle and to no other. Env map[string]string `json:"env,omitempty"` + + // Series is the series this artifact's versions are numbered in, `.` (novox/hq ADR 0606, design 32): + // the builder numbers `.`, so a change of series is a change a user accepts by its own `packages`. + // Said on a package, an image, a bundle or an archive; the judge refuses it on any other kind. Absent is + // DefaultSeries (SeriesOf). + Series string `json:"series,omitempty"` + + // GeneratedFrom marks a package of a contracts module (novox/hq ADR 0608 §5, design 26 *Contracts modules*): the + // directory, relative to the module's, of the seat definitions every file of the package is generated from. A + // module carrying it holds contracts only and claims no seat, which the judge refuses naming the seat; the build + // modules' test step regenerates the package and fails on a file out of step. + GeneratedFrom string `json:"generated-from,omitempty"` +} + +// AcceptedSeries is the series of the package of that name this module accepts: the one Packages names, or +// DefaultSeries. +func (m Manifest) AcceptedSeries(name string) string { + if s := m.Packages[name]; s != "" { + return s + } + return DefaultSeries +} + +// DefaultSeries is the series of an artifact or an accepted package that names none (design 32). +const DefaultSeries = "0.1" + +// SeriesOf is the series the artifact's versions are numbered in: its own, or DefaultSeries. +func (a Artifact) SeriesOf() string { + if a.Series == "" { + return DefaultSeries + } + return a.Series } // Kinds an artifact may be. diff --git a/go/catalogue/setting_defaults.go b/go/catalogue/setting_defaults.go index 05f9c46..5180cd8 100644 --- a/go/catalogue/setting_defaults.go +++ b/go/catalogue/setting_defaults.go @@ -31,6 +31,11 @@ type SettingDeclaration struct { Required bool `json:"required,omitempty"` // Runtime is a value the module's code reads at runtime rather than one placed in a file (ADR 0348 §5). Runtime bool `json:"runtime,omitempty"` + // RenamedFrom is the value's old name, a config value of this module's own (novox/hq ADR 0609 §4, design 32 *A + // config value renamed*): on the merge mesh-config moves the value held under it to this name, and answers both + // names until every node-engine reports a build reading the new one. The config form only: the judge refuses it + // under `settings`, on a secret, and where it changes the value's trust. + RenamedFrom string `json:"renamed-from,omitempty"` } // KindPreference is the kind of a setting that may have a default.