package scraper import ( "sort" "strings" "github.com/go-enry/go-license-detector/v4/licensedb/filer" ) // readmeCandidates are the filenames looked for, in priority order, when // retrieving a repository's README. var readmeCandidates = []string{"README.md", "README.rst", "README.txt", "README"} // readmeFor returns the content of the repository's README on the given ref // (default branch), picking from root (the pre-fetched root file listing) the // first candidate found (case-insensitively). An empty string is returned when // no README can be found; the repo is still kept in results either way. func (s *ForgejoScraper) readmeFor(owner, name, ref string, root []filer.File) string { // Collect root file names, lowercased for case-insensitive matching, while // keeping the real name for the GetFile call. type rootFile struct { real string low string } files := make([]rootFile, 0, len(root)) for _, e := range root { if e.IsDir { continue } files = append(files, rootFile{real: e.Name, low: strings.ToLower(e.Name)}) } // Candidate priority wins; ties broken by alphabetical real name for // deterministic picks when a repo has e.g. both README and README.md. sort.SliceStable(files, func(i, j int) bool { pi, pj := readmePriority(files[i].low), readmePriority(files[j].low) if pi != pj { return pi < pj // lower = higher priority } return files[i].real < files[j].real }) var chosen string for i := range files { if readmePriority(files[i].low) >= 0 { chosen = files[i].real break } } if chosen == "" { return "" } data, _, err := s.Client.GetFile(owner, name, ref, chosen) if err != nil { return "" } return string(data) } // readmePriority returns the index of a lowercased filename in // readmeCandidates, or -1 if it is not a readme candidate. func readmePriority(low string) int { for i, c := range readmeCandidates { if low == strings.ToLower(c) { return i } } return -1 }