Preserve upstream policy wording in link examples
This commit is contained in:
@@ -118,8 +118,7 @@ Each entry presents these five fields in order, with blank lines between them:
|
||||
by ` | `, and ending with a period. Label local standard texts by license
|
||||
name, such as `MIT` or `Apache 2.0`. Label upstream files by their actual
|
||||
filenames, such as `COPYRIGHT`, `LICENSE`, `NOTICE`, or `PATENTS`.
|
||||
5. **Source repository link**, rendered as a Markdown link labeled `Source` to
|
||||
the exact commit URL, followed by a period.
|
||||
5. **Source repository link**, rendered exactly as `[Source](COMMIT_URL).`.
|
||||
|
||||
Use the upstream [attribution example](https://gitea.maximumdirect.net/eric/policy/src/commit/a469273adda336625f96b9d769ea27b33999f146/examples/licensing/attribution.md)
|
||||
to create the project’s `docs/oss/attribution.md`.
|
||||
|
||||
@@ -12,6 +12,46 @@ import (
|
||||
)
|
||||
|
||||
var markdownLinkPattern = regexp.MustCompile(`\[[^\]]+\]\(([^)]+)\)`)
|
||||
var markdownBackticks = regexp.MustCompile("`+")
|
||||
|
||||
// documentationLinks excludes literal examples enclosed by matching backtick
|
||||
// runs before applying the existing lightweight link check.
|
||||
func documentationLinks(markdown string) [][]string {
|
||||
runs := markdownBackticks.FindAllStringIndex(markdown, -1)
|
||||
text := []byte(markdown)
|
||||
for i := 0; i < len(runs); i++ {
|
||||
width := runs[i][1] - runs[i][0]
|
||||
for j := i + 1; j < len(runs); j++ {
|
||||
if runs[j][1]-runs[j][0] != width {
|
||||
continue
|
||||
}
|
||||
for k := runs[i][0]; k < runs[j][1]; k++ {
|
||||
text[k] = ' '
|
||||
}
|
||||
i = j
|
||||
break
|
||||
}
|
||||
}
|
||||
return markdownLinkPattern.FindAllStringSubmatch(string(text), -1)
|
||||
}
|
||||
|
||||
func TestDocumentationLinksIgnoreCodeExamples(t *testing.T) {
|
||||
for _, example := range []string{
|
||||
"`[Source](COMMIT_URL).`",
|
||||
"``[Source](COMMIT_URL) with a ` character``",
|
||||
"```markdown\n[Source](COMMIT_URL)\n```",
|
||||
} {
|
||||
t.Run(example, func(t *testing.T) {
|
||||
matches := documentationLinks("[before](before.md) " + example + " [after](after.md)")
|
||||
if len(matches) != 2 || matches[0][1] != "before.md" || matches[1][1] != "after.md" {
|
||||
t.Fatalf("links = %#v, want only the surrounding real links", matches)
|
||||
}
|
||||
})
|
||||
}
|
||||
if matches := documentationLinks("unmatched ` [real](real.md)"); len(matches) != 1 || matches[0][1] != "real.md" {
|
||||
t.Fatalf("unmatched backtick hid a real link: %#v", matches)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDocumentationLinksResolve(t *testing.T) {
|
||||
root := repositoryRoot(t)
|
||||
@@ -163,7 +203,7 @@ func walkDocumentationLinks(t *testing.T, root, directory string) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, match := range markdownLinkPattern.FindAllStringSubmatch(string(data), -1) {
|
||||
for _, match := range documentationLinks(string(data)) {
|
||||
target := strings.TrimSpace(match[1])
|
||||
if !isLocalDocumentationTarget(target) {
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user