package issue import ( "regexp" "strings" ) // A reference is a slug, or `#N` on an issue that came from a tracker. var depRefRe = regexp.MustCompile(`#(\d+)|\b([a-z0-9]+(?:-[a-z0-9]+)+)\b`) // DepRef is one dependency reference written in the body prose, carried out // with the section it was found in. // // The section travels with the reference so a caller can name the one the // reader actually has in front of them: a container's children come from // `## Issues`, and pointing at `## Depends on` would name a section that is not // in the file. type DepRef struct { Section string Ref string } // BodyDepRefs returns every reference under one of DepSections, deduplicated // on first sight, in order of first appearance. // // Never from prose elsewhere, or a graph walk would drag in half the backlog. func BodyDepRefs(body string) []DepRef { var out []DepRef seen := map[string]bool{} section := "" for _, line := range splitLines(body) { if strings.HasPrefix(line, "## ") { head := strings.TrimSpace(line) section = "" for _, s := range DepSections { if head == s { section = head break } } continue } if section == "" { continue } for _, tok := range depRefRe.FindAllStringSubmatch(line, -1) { ref := tok[2] if tok[1] != "" { ref = "#" + tok[1] } if !seen[ref] { seen[ref] = true out = append(out, DepRef{Section: section, Ref: ref}) } } } return out }