The checker built from G's heads makes no tag-wanted and waits on no published of a tagged version: tagwanted.go and tags.go go (the verdict sayer stays, in verdictsay.go), with st.tagged, groupVersions, Case.Tagged, TagAsks, the PublishedHeard wiring, the group path's tagged Node package and Go packages, the manifest's two published consumes and the tag-wanted event of asks. Builds: design 47 G §528, §373, §321 Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
116 lines
4.0 KiB
Go
116 lines
4.0 KiB
Go
package check
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
)
|
|
|
|
// declaredPackage is one package a group member declares: the module, its directory in the repository (RootPath for its
|
|
// root, empty when not known), and the artifact's name, paths and language.
|
|
type declaredPackage struct {
|
|
pull Pull
|
|
module, dir string
|
|
name string
|
|
paths []string
|
|
language string
|
|
}
|
|
|
|
// manifestAtHead is a touched module's manifest read from the forge at its member's head (the lead's ruling 4 on A2c's
|
|
// finding 4): with no preview of the merge, a package new in the group is declared only there, never at the trunk. The
|
|
// module's directory is the indexer's when it knows the module, else modules/<module> or the repository's root, the one
|
|
// whose manifest names the module. Found is false when no such file names it.
|
|
func (st *state) manifestAtHead(ctx context.Context, p Pull, module string) (m catalogue.Manifest, dir string, found bool, err error) {
|
|
var dirs []string
|
|
if st.j.Dirs != nil {
|
|
if d, ok := st.j.Dirs.ModuleDir(module); ok {
|
|
dirs = []string{d}
|
|
}
|
|
}
|
|
if dirs == nil {
|
|
dirs = []string{"modules/" + module, meshcatalogclient.RootPath}
|
|
}
|
|
for _, d := range dirs {
|
|
file := "module.json"
|
|
if t := strings.Trim(d, "/"); t != "" && t != meshcatalogclient.RootPath {
|
|
file = t + "/module.json"
|
|
}
|
|
text, err := st.j.Forge.File(ctx, p.Repository, file, p.Head)
|
|
if errors.Is(err, ErrNotFound) {
|
|
continue
|
|
}
|
|
if err != nil {
|
|
return catalogue.Manifest{}, "", false, fmt.Errorf("the manifest of %s at the head of %s cannot be read%s: %w", module, pullKey(p), unheardWords(err), err)
|
|
}
|
|
m, err := catalogue.Decode([]byte(text))
|
|
if err != nil {
|
|
return catalogue.Manifest{}, "", false, fmt.Errorf("the manifest %s of %s at the head of %s is no manifest: %w", file, module, pullKey(p), err)
|
|
}
|
|
if m.Module == module {
|
|
return m, d, true, nil
|
|
}
|
|
}
|
|
return catalogue.Manifest{}, "", false, nil
|
|
}
|
|
|
|
// declaredPackages are the packages the case's members declare, read from each touched module's manifest at the merge
|
|
// preview (the candidate's); with no preview, at the member's head on the forge, so a package new in the group is asked
|
|
// for on the first check too (trunk's manifest when no forge is read): a member that declares none is not asked for.
|
|
func (st *state) declaredPackages(ctx context.Context) ([]declaredPackage, error) {
|
|
if st.j.Read == nil && st.j.Forge == nil {
|
|
return nil, nil
|
|
}
|
|
var trunk map[string]string
|
|
if st.j.Manifests != nil {
|
|
trunk = st.j.Manifests.ManifestDigests()
|
|
}
|
|
var out []declaredPackage
|
|
for _, p := range st.c.Pulls {
|
|
for _, module := range p.Modules {
|
|
var m catalogue.Manifest
|
|
var dir string
|
|
digest := p.Fps[module].Manifest
|
|
switch {
|
|
case digest != "" && st.j.Read != nil:
|
|
var err error
|
|
if m, err = st.j.Read.Manifest(ctx, digest); err != nil {
|
|
return nil, fmt.Errorf("the manifest of %s (%s) cannot be read, so the packages it declares are not known: %w", module, pullKey(p), err)
|
|
}
|
|
case st.j.Forge != nil:
|
|
var found bool
|
|
var err error
|
|
if m, dir, found, err = st.manifestAtHead(ctx, p, module); err != nil {
|
|
return nil, fmt.Errorf("%v, so the packages it declares are not known", err)
|
|
}
|
|
if !found {
|
|
continue
|
|
}
|
|
case trunk[module] != "" && st.j.Read != nil:
|
|
var err error
|
|
if m, err = st.j.Read.Manifest(ctx, trunk[module]); err != nil {
|
|
return nil, fmt.Errorf("the manifest of %s (%s) cannot be read, so the packages it declares are not known: %w", module, pullKey(p), err)
|
|
}
|
|
default:
|
|
continue
|
|
}
|
|
if dir == "" && st.j.Dirs != nil {
|
|
dir, _ = st.j.Dirs.ModuleDir(module)
|
|
}
|
|
if m.Build == nil {
|
|
continue
|
|
}
|
|
for _, a := range m.Build.Artifacts {
|
|
if a.Kind != catalogue.ArtifactPackage {
|
|
continue
|
|
}
|
|
out = append(out, declaredPackage{pull: p, module: module, dir: dir, name: a.Name, paths: a.Paths, language: a.Language})
|
|
}
|
|
}
|
|
}
|
|
return out, nil
|
|
}
|