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 }