Files
mesh-delivery/modules/mesh-delivery-indexer/internal/index/own.go
T
jschoubben 9f7e082688 List a repository's modules from the merged message's manifests and the indexer's own bucket, not the controller's build records, so a new module gets a value and a key with no build asked (issue 1851, I1 I2 I4, ADR 0501 §6, ADR 0453 §6)
I1: a merge writes each module its manifests name, at its directory. I2: a pull request's changed directory, a
preview's touched module and a source revision's modules come from the modules bucket (a module a pull request adds is
found in the preview by its manifest). I4: the value of today's form (fp, none) is no longer written, since it was
computed from the build records; mesh-sdk keeps it readable until R4g. One commit: the three share applyMerged and its
tests. Pins mesh-sdk feat/r4e-sdk 9cb4d59.
2026-10-22 18:08:48 +02:00

82 lines
2.6 KiB
Go

package index
import (
"context"
"encoding/json"
"fmt"
"path"
"strings"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
// From R4e the indexer lists a repository's modules from what it holds itself (novox/hq ADR 0501 clause 6, issue 1851):
// a merged message's manifests name the modules of the merge, and the modules bucket names the modules it wrote before,
// with their repository and directory. The controller's build records name none of them (ADR 0453 clause 5 keeps only
// the builder's own input from them until R4g, builds.go).
// manifestModule is the module a manifest names itself (its `module`), or "" when it names none or is not JSON. Only the
// name is read here; the manifest is read whole by the catalogue's parser (inputs.go).
func manifestModule(raw string) string {
var m struct {
Module string `json:"module"`
}
if json.Unmarshal([]byte(raw), &m) != nil {
return ""
}
return m.Module
}
// heldModules are the values the modules bucket holds, by key (the module's name). A value that is not a module is left
// out and said.
func (ix *Indexer) heldModules(ctx context.Context) (map[string]delivery.Module, error) {
out := map[string]delivery.Module{}
if ix.Modules == nil {
return out, nil
}
keys, err := ix.Modules.Keys(ctx)
if err != nil {
return nil, fmt.Errorf("listing the modules: %w", err)
}
for _, key := range keys {
value, _, found, err := ix.Modules.Get(ctx, key)
if err != nil {
return nil, fmt.Errorf("modules.%s: %w", key, err)
}
if !found {
continue
}
m, err := delivery.DecodeModule(value)
if err != nil {
ix.logf("modules.%s holds what is not a module, left: %v", key, err)
continue
}
out[key] = m
}
return out, nil
}
// moduleAt is the module whose directory in the repository is dir, as the modules bucket holds it.
func moduleAt(held map[string]delivery.Module, repository, dir string) (string, bool) {
want := pathOf(strings.Trim(dir, "/"))
for name, m := range held {
if m.Path == want && delivery.SameRepository(m.Repository, repository) {
return name, true
}
}
return "", false
}
// moduleOfDir is the module of a changed directory of a pull request: the module its manifest in the message names, else
// the one the modules bucket holds at that directory of the repository, else the directory's last element (the
// catalogue's rule for nearly every manifest).
func moduleOfDir(held map[string]delivery.Module, f delivery.Forge, dir string) string {
if name := manifestModule(f.Manifests[dir]); name != "" {
return name
}
if name, ok := moduleAt(held, f.Repository, dir); ok {
return name
}
return path.Base(strings.Trim(dir, "/"))
}