Artifact b104477c3b4c0976cb638038236098f29776cc07c54d960e958838e5d5e89654:
- File
internal/merge/resolve.go
— part of check-in
[22b3a0f06d]
at
2026-10-13 04:51:36
on branch main
— test(conformance): cover artifact K, delta-lookup and delta-size requirements (#388)
* test(conformance): cover artifact K, delta-lookup and delta-size requirements
Single-name lookup in a delta manifest now follows artifact-format-01 8.4 (manifest.LookupFile), Marshal writes the K ticket ID lowercase (4.7.9), and new cases cover 3.1 size limits, 3.4 checksum mismatches and date-only timestamps. AF-6.3-5 and AF-7.1-2 stay uncovered with a reason in their rows.
* test(conformance): cover artifact K, delta-lookup and delta-size requirements (review fixes) (user: [email protected], size: 2192) [annotate] [blame] [check-ins using]
package merge import ( "bufio" "path/filepath" "strings" "github.com/danmestas/go-libfossil/internal/content" libfossil "github.com/danmestas/go-libfossil/internal/fsltype" "github.com/danmestas/go-libfossil/internal/manifest" "github.com/danmestas/go-libfossil/internal/repo" ) // PatternRule maps a glob pattern to a strategy name. type PatternRule struct { Glob string Strategy string } // Resolver picks the merge strategy for a given filename. type Resolver struct { patterns []PatternRule fallback string } // LoadResolver reads the .libfossil-merge file from the repo at the given // version, plus the merge-strategy config key as fallback. func LoadResolver(r *repo.Repo, tipRid libfossil.FslID) *Resolver { if r == nil { panic("merge.LoadResolver: r must not be nil") } res := &Resolver{fallback: "three-way"} var cfgDefault string if r.DB().QueryRow("SELECT value FROM config WHERE name='merge-strategy'").Scan(&cfgDefault) == nil && cfgDefault != "" { res.fallback = cfgDefault } if tipRid > 0 { f, found, err := manifest.LookupFile(r, tipRid, ".libfossil-merge") if err == nil && found { if rid, ok := content.AvailableByUUID(r.DB(), f.UUID); ok { // Bare Expand: one config file (.libfossil-merge) at one // version, read once. No revision walk to cache. if data, err := content.Expand(r.DB(), rid); err == nil { res.patterns = parseMergeFile(data) } } } } return res } // Resolve returns the strategy name for a filename. func (res *Resolver) Resolve(filename string) string { for _, p := range res.patterns { matched, matchErr := filepath.Match(p.Glob, filepath.Base(filename)) if matchErr != nil { continue } if matched { return p.Strategy } } return res.fallback } func parseMergeFile(data []byte) []PatternRule { var rules []PatternRule scanner := bufio.NewScanner(strings.NewReader(string(data))) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if line == "" || strings.HasPrefix(line, "#") { continue } parts := strings.Fields(line) if len(parts) >= 2 { rules = append(rules, PatternRule{Glob: parts[0], Strategy: parts[1]}) } } return rules }