Skip to content

Commit

Permalink
implement reference links to issues and PRs
Browse files Browse the repository at this point in the history
  • Loading branch information
rhysd committed Oct 4, 2024
1 parent 06ba3e6 commit abcb059
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 22 deletions.
68 changes: 46 additions & 22 deletions reflink.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,46 @@ func (l *Reflinker) linkGitHubRefs(t *ast.Text) {

var reGitHubCommitPath = regexp.MustCompile(`^/([^/]+/[^/]+)/commit/([[:xdigit:]]{7,})`)

func (l *Reflinker) linkGitHubURL(n *ast.AutoLink, src []byte) {
func (l *Reflinker) linkCommitURL(m [][]byte, url []byte, start, end int) {
slug, hash := m[1], m[2]
if len(hash) > 10 {
hash = hash[:10]
}

var replaced string
if bytes.HasPrefix(url, []byte(l.repo)) {
replaced = fmt.Sprintf("[`%s`](%s)", hash, url)
} else {
replaced = fmt.Sprintf("[`%s@%s`](%s)", slug, hash, url)
}

l.links = append(l.links, refLink{
start: start,
end: end,
text: replaced,
})
}

var reGitHubIssuePath = regexp.MustCompile(`^/([^/]+/[^/]+)/(?:pull|issues)/(\d+)`)

func (l *Reflinker) linkIssueURL(m [][]byte, url []byte, start, end int) {
slug, num := m[1], m[2]

var replaced string
if bytes.HasPrefix(url, []byte(l.repo)) {
replaced = fmt.Sprintf("[#%s](%s)", num, url)
} else {
replaced = fmt.Sprintf("[%s#%s](%s)", slug, num, url)
}

l.links = append(l.links, refLink{
start: start,
end: end,
text: replaced,
})
}

func (l *Reflinker) linkURL(n *ast.AutoLink, src []byte) {
start := 0
if p := n.PreviousSibling(); p != nil {
t := p.(*ast.Text)
Expand Down Expand Up @@ -249,28 +288,13 @@ func (l *Reflinker) linkGitHubURL(n *ast.AutoLink, src []byte) {
return
}

m := reGitHubCommitPath.FindSubmatch(url[len(home):])
if m == nil {
return
}
path := url[len(home):]

slug, hash := m[1], m[2]
if len(hash) > 10 {
hash = hash[:10]
if m := reGitHubCommitPath.FindSubmatch(path); m != nil {
l.linkCommitURL(m, url, start, end)
} else if m := reGitHubIssuePath.FindSubmatch(path); m != nil {
l.linkIssueURL(m, url, start, end)
}

var replaced string
if bytes.HasPrefix(url, []byte(l.repo)) {
replaced = fmt.Sprintf("[`%s`](%s)", hash, url)
} else {
replaced = fmt.Sprintf("[`%s@%s`](%s)", slug, hash, url)
}

l.links = append(l.links, refLink{
start: start,
end: end,
text: replaced,
})
}

// BuildLinkedText builds a markdown text linking all references.
Expand Down Expand Up @@ -311,7 +335,7 @@ func LinkRefs(input string, repoURL string) string {
case *ast.CodeSpan, *ast.Link:
return ast.WalkSkipChildren, nil
case *ast.AutoLink:
l.linkGitHubURL(n, src)
l.linkURL(n, src)
return ast.WalkSkipChildren, nil
case *ast.Text:
l.linkGitHubRefs(n)
Expand Down
20 changes: 20 additions & 0 deletions reflink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,26 @@ func TestLinkRefs(t *testing.T) {
want: "https://github.com/foo/bar/commit/1d457ba853aa10f9a6c925a1b73d5aed38066ffe",
repoURL: "https://github.company.com/u/r",
},
{
what: "issue URL inside the repo",
input: "the issue is https://github.com/u/r/issues/123!",
want: "the issue is [#123](https://github.com/u/r/issues/123)!",
},
{
what: "PR URL inside the repo",
input: "the PR is https://github.com/u/r/pull/123!",
want: "the PR is [#123](https://github.com/u/r/pull/123)!",
},
{
what: "issue URL outside the repo",
input: "the issue is https://github.com/foo/bar/issues/123!",
want: "the issue is [foo/bar#123](https://github.com/foo/bar/issues/123)!",
},
{
what: "PR URL outside the repo",
input: "the PR is https://github.com/foo/bar/pull/123!",
want: "the PR is [foo/bar#123](https://github.com/foo/bar/pull/123)!",
},
}

for _, tc := range tests {
Expand Down

0 comments on commit abcb059

Please sign in to comment.