88 lines
4.5 KiB
Go
88 lines
4.5 KiB
Go
package index
|
|
|
|
import (
|
|
"slices"
|
|
"strings"
|
|
|
|
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
|
"git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
|
|
sdkstep "git.novox.be/novox/mesh-delivery/sdk/buildstep"
|
|
|
|
"mesh-delivery-indexer/internal/fingerprint"
|
|
)
|
|
|
|
// form is a module's fingerprint, or why it has none, and the version of each mesh Go module of another repository
|
|
// its build is pinned to.
|
|
type form struct {
|
|
fp, none string
|
|
versions sdkstep.PackageVersions
|
|
}
|
|
|
|
// formOf is the module's fingerprint from its kept inputs (bases already its bases' fingerprints) and toolchains, in the
|
|
// form they call for (novox/hq ADR 0593 §2, §4):
|
|
//
|
|
// - **The import form**, for a module whose last trunk build reported its imports (kept.Imports) when every import is
|
|
// published (the packages state): the content digest of each imported package and the requirements' digest of each
|
|
// mesh Go module holding one. Its versions are each holding module's published commit (another repository's only).
|
|
// - **A change of form never rebuilds by itself** (§4): kept.ImportForm is the import-form fingerprint of the inputs
|
|
// the build that reported the imports was built from. While the import form computes to it, nothing the build was
|
|
// built from changed: the module keeps the fingerprint it holds (prev), in whatever form, and its versions.
|
|
// Otherwise the import form is written, and ImportForm moves with it.
|
|
// - **The version line** otherwise (no import set, or an import none publishes): the version of each mesh Go module of
|
|
// another repository its go.sum names, read as the indexer always read it (fingerprint.HeldVersionsOf), and the
|
|
// content of each mesh Go module of its own repository its go.mod replaces by a directory (fingerprint.VersionLine),
|
|
// so a change of that directory alone moves it (review finding 2). Its versions are the other repositories' alone.
|
|
// - **An accepted series** (DLV-I6): published and pins come from acceptedSeries, so a mesh Go module of another
|
|
// repository whose series the module accepts enters, in either form, by its series' newest published version and the
|
|
// digests of that version's commit.
|
|
//
|
|
// It sets kept.ImportForm when it writes the import form.
|
|
func formOf(module, repository string, kept *meshcatalog.ModulesByModuleValueInputs2, toolchains map[string]meshcatalogclient.Toolchain2, prev meshcatalog.ModulesByModuleValue, held map[string]meshcatalog.ModulesByModuleValue, published map[string]meshcatalog.PackagesByModuleValue, pins sdkstep.PackageVersions, logf func(string, ...any)) form {
|
|
in := inputsFrom(module, *kept, toolchains)
|
|
if len(kept.Imports) > 0 {
|
|
r := fingerprint.Resolve(repository, kept.Imports, published)
|
|
if len(r.Missing) == 0 {
|
|
in.Imports, in.Requires = r.Digests, r.Requires
|
|
fp, none := fingerprint.Of(in)
|
|
switch {
|
|
case fp == "":
|
|
return form{none: none}
|
|
case kept.ImportForm == fp && prev.Fp2 != "":
|
|
return form{fp: prev.Fp2, versions: prev.Packages} // the build that reported the imports stands
|
|
}
|
|
kept.ImportForm = fp
|
|
return form{fp: fp, versions: r.Versions}
|
|
}
|
|
if logf != nil {
|
|
logf("%s: no published package holds %s, so its fingerprint takes the version line", module, strings.Join(r.Missing, ", "))
|
|
}
|
|
}
|
|
others := fingerprint.OtherPackages(kept.Packages, repository)
|
|
versions, unpublished := fingerprint.HeldVersionsOf(others, held)
|
|
for p, v := range pins { // an accepted series' newest published version (acceptedSeries, DLV-I6)
|
|
if slices.Contains(others, p) {
|
|
if versions == nil {
|
|
versions = sdkstep.PackageVersions{}
|
|
}
|
|
versions[p] = v
|
|
unpublished = slices.DeleteFunc(unpublished, func(u string) bool { return u == p })
|
|
}
|
|
}
|
|
if len(unpublished) > 0 && logf != nil {
|
|
logf("%s: no module the indexer holds publishes %s, so its fingerprint takes no version of it", module, strings.Join(unpublished, ", "))
|
|
}
|
|
in.Packages = fingerprint.VersionLine(repository, kept.Packages, versions, published)
|
|
fp, none := fingerprint.Of(in)
|
|
if fp == "" {
|
|
return form{none: none}
|
|
}
|
|
return form{fp: fp, versions: versions}
|
|
}
|
|
|
|
// inputsFrom is the fingerprint's inputs of module m from its kept inputs and the given toolchains, no package of
|
|
// either form yet.
|
|
func inputsFrom(module string, k meshcatalog.ModulesByModuleValueInputs2, toolchains map[string]meshcatalogclient.Toolchain2) fingerprint.Inputs {
|
|
return fingerprint.Inputs{Module: module, Tree: k.Tree, Bases: k.Bases, Builder: k.Builder, Contexts: k.Contexts,
|
|
Locks: k.Locks, Toolchains: toolchains}
|
|
}
|