70 lines
1.9 KiB
Go
70 lines
1.9 KiB
Go
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
|
|
}
|