func parseMeta()

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
}