package opensuse import ( "context" "fmt" "strings" "sync" "time" "tangled.org/odd.computer/isomorph/internal/fetch" ) // giturls.good on rb.zq1.de is the output of Bernhard Wiedemann's findvcs script over every // Factory spec: "/.spec = " per line. It was derived from the same spec // URL/Source fields we parse (and parts of it date from 2022), so it corroborates rather than // proves an upstream. Loaded once per process per base URL; failures are non-fatal. var giturlsCache = struct { mu sync.Mutex m map[string]*giturlsEntry }{m: map[string]*giturlsEntry{}} type giturlsEntry struct { once sync.Once urls map[string][]string err error } // ParseGitURLs parses the giturls(.good) format into package -> URLs. Lines with "= unknown", // "debug:" lines and findvcs "FIXME" placeholders are skipped. func ParseGitURLs(text string) map[string][]string { out := map[string][]string{} for _, line := range strings.Split(text, "\n") { line = strings.TrimSpace(line) if line == "" || strings.HasPrefix(line, "debug:") || strings.HasPrefix(line, "#") { continue } key, val, ok := strings.Cut(line, " = ") if !ok { continue } val = strings.TrimSpace(val) if val == "" || val == "unknown" || strings.Contains(val, "FIXME") || strings.ContainsAny(val, " \t") { continue } pkg := strings.TrimSpace(key) if i := strings.Index(pkg, "/"); i >= 0 { pkg = pkg[:i] } if pkg == "" { continue } out[pkg] = appendUnique(out[pkg], val) } return out } // loadGitURLs fetches and parses giturls.good (7-day TTL) once per process. func (r *Resolver) loadGitURLs(ctx context.Context) (map[string][]string, error) { giturlsCache.mu.Lock() e, ok := giturlsCache.m[r.ZQ1Base] if !ok { e = &giturlsEntry{} giturlsCache.m[r.ZQ1Base] = e } giturlsCache.mu.Unlock() e.once.Do(func() { u := strings.TrimSuffix(r.ZQ1Base, "/") + "/giturls.good" b, err := r.c.Get(ctx, u, fetch.WithTTL(7*24*time.Hour)) if err != nil { e.err = fmt.Errorf("giturls: %w", err) return } e.urls = ParseGitURLs(string(b)) }) return e.urls, e.err } func appendUnique(s []string, v string) []string { if v == "" { return s } for _, x := range s { if x == v { return s } } return append(s, v) }