75 lines
2.7 KiB
Go
75 lines
2.7 KiB
Go
package index
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
)
|
|
|
|
// The reasons a module has no fingerprint (ADR 0437 §5; issue 1209's decision).
|
|
const (
|
|
// NoneNarrow is for a module whose image compiles a Go program from a context: the context is the hash of the build
|
|
// source the builder handed it, not a git tree.
|
|
NoneNarrow = "an artifact compiles a Go program from a build source that git trees do not pin: no fingerprint before release 4"
|
|
// NoneContext is for a context that is a repository's root tree.
|
|
NoneContext = "an artifact reads the root tree of a repository the indexer does not know the tree of before release 4"
|
|
// NoneNoBuild is for a module no successful trunk build recorded the inputs of.
|
|
NoneNoBuild = "no successful trunk build recorded its inputs"
|
|
)
|
|
|
|
// fingerprintOf is the module's fingerprint at the merge, or none and why: its directory's tree from the merged
|
|
// message and the bases, contexts and toolchains its newest successful trunk build recorded.
|
|
func fingerprintOf(k Known, trees map[string]string) (fp, none string) {
|
|
if k.Trunk == nil {
|
|
return "", NoneNoBuild
|
|
}
|
|
in := *k.Trunk.SourceInputs
|
|
artifacts := make([]string, 0, len(in.Contexts))
|
|
for a := range in.Contexts {
|
|
artifacts = append(artifacts, a)
|
|
}
|
|
sort.Strings(artifacts)
|
|
for _, a := range artifacts {
|
|
if strings.HasPrefix(in.Contexts[a], "narrow:") {
|
|
return "", NoneNarrow
|
|
}
|
|
}
|
|
if len(artifacts) > 0 {
|
|
return "", NoneContext
|
|
}
|
|
in.Tree = trees[k.Path] // the directory "" is the repository's root
|
|
return delivery.SourceFingerprint(in)
|
|
}
|
|
|
|
// applyMerged writes, for each module built from the merged repository, its fingerprint at the merge commit (or none and
|
|
// why). A module of another repository is not written. A value the module already holds is not written again.
|
|
func (ix *Indexer) applyMerged(ctx context.Context, f delivery.Forge) error {
|
|
for _, k := range ix.Builds.Modules(f.Repository) {
|
|
key, err := delivery.ModulesKey(k.Module)
|
|
if err != nil {
|
|
ix.logf("%s: the module %q has no usable key, skipped: %v", f.Repository, k.Module, err)
|
|
continue
|
|
}
|
|
fp, none := fingerprintOf(k, f.Trees)
|
|
next := delivery.Module{Repository: f.Repository, Commit: f.Merge, FP: fp, None: none}
|
|
err = write(ctx, ix.Modules, key, func(value []byte, found bool) ([]byte, bool, error) {
|
|
if found {
|
|
if cur, err := delivery.DecodeModule(value); err == nil && delivery.SameModule(cur, withV(next)) {
|
|
return nil, false, nil
|
|
}
|
|
}
|
|
data, err := delivery.EncodeModule(next)
|
|
return data, false, err
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("modules.%s: %w", key, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func withV(m delivery.Module) delivery.Module { m.V = delivery.Version; return m }
|