in internal/source/meta-tags.go [61:152]
func parseMeta(importPath string, r io.Reader) (sm *sourceMeta, err error) {
errorMessage := "go-import and go-source meta tags not found"
// gddo uses an xml parser, and this code is adapted from it.
d := xml.NewDecoder(r)
d.Strict = false
metaScan:
for {
t, tokenErr := d.Token()
if tokenErr != nil {
break metaScan
}
switch t := t.(type) {
case xml.EndElement:
if strings.EqualFold(t.Name.Local, "head") {
break metaScan
}
case xml.StartElement:
if strings.EqualFold(t.Name.Local, "body") {
break metaScan
}
if !strings.EqualFold(t.Name.Local, "meta") {
continue metaScan
}
nameAttr := attrValue(t.Attr, "name")
if nameAttr != "go-import" && nameAttr != "go-source" {
continue metaScan
}
fields := strings.Fields(attrValue(t.Attr, "content"))
if len(fields) < 1 {
continue metaScan
}
repoRootPrefix := fields[0]
if !strings.HasPrefix(importPath, repoRootPrefix) ||
!(len(importPath) == len(repoRootPrefix) || importPath[len(repoRootPrefix)] == '/') {
// Ignore if root is not a prefix of the path. This allows a
// site to use a single error page for multiple repositories.
continue metaScan
}
switch nameAttr {
case "go-import":
if len(fields) != 3 {
errorMessage = "go-import meta tag content attribute does not have three fields"
continue metaScan
}
if fields[1] == "mod" {
// We can't make source links from a "mod" vcs type, so skip it.
continue
}
if sm != nil {
sm = nil
errorMessage = "more than one go-import meta tag found"
break metaScan
}
sm = &sourceMeta{
repoRootPrefix: repoRootPrefix,
repoURL: fields[2],
}
// Keep going in the hope of finding a go-source tag.
case "go-source":
if len(fields) != 4 {
errorMessage = "go-source meta tag content attribute does not have four fields"
continue metaScan
}
if sm != nil && sm.repoRootPrefix != repoRootPrefix {
errorMessage = fmt.Sprintf("import path prefixes %q for go-import and %q for go-source disagree", sm.repoRootPrefix, repoRootPrefix)
sm = nil
break metaScan
}
// If go-source repo is "_", then default to the go-import repo.
repoURL := fields[1]
if repoURL == "_" {
if sm == nil {
errorMessage = `go-source repo is "_", but no previous go-import tag`
break metaScan
}
repoURL = sm.repoURL
}
sm = &sourceMeta{
repoRootPrefix: repoRootPrefix,
repoURL: repoURL,
dirTemplate: fields[2],
fileTemplate: fields[3],
}
break metaScan
}
}
}
if sm == nil {
return nil, fmt.Errorf("%s: %w", errorMessage, derrors.NotFound)
}
return sm, nil
}