Skip to content

Commit 21b6d17

Browse files
committed
internal/source: add support for dmitri.shuralyov.com/... packages
Add support for a set of packages that defer to another website to display their source code. To be able to produce expected URLs, we need to add two more URL template variables: • {importPath} - Package import path ("example.com/myrepo/mypkg"). • {base} - Base name of file containing the identifier, including file extension ("file.go"). Also add a new optional Repo URL template for overriding the home page of the repository, which is something that was possible with the original go-source meta tag. Document the existing URL template variables, so that it's easier to understand how to use them. For golang/go#40477. Change-Id: I70b857155f69c5c3ed41e78daccb90153a927290 Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/246239 Run-TryBot: Dmitri Shuralyov <[email protected]> TryBot-Result: kokoro <[email protected]> Reviewed-by: Jonathan Amsterdam <[email protected]>
1 parent ea96ad2 commit 21b6d17

File tree

3 files changed

+1421
-1067
lines changed

3 files changed

+1421
-1067
lines changed

internal/source/source.go

+52-15
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,18 @@ type Info struct {
4949
templates urlTemplates // for building URLs
5050
}
5151

52+
// RepoURL returns a URL for the home page of the repository.
5253
func (i *Info) RepoURL() string {
5354
if i == nil {
5455
return ""
5556
}
56-
return i.repoURL
57+
if i.templates.Repo == "" {
58+
// The default repo template is just "{repo}".
59+
return i.repoURL
60+
}
61+
return expand(i.templates.Repo, map[string]string{
62+
"repo": i.repoURL,
63+
})
5764
}
5865

5966
// ModuleURL returns a URL for the home page of the module.
@@ -67,9 +74,10 @@ func (i *Info) DirectoryURL(dir string) string {
6774
return ""
6875
}
6976
return strings.TrimSuffix(expand(i.templates.Directory, map[string]string{
70-
"repo": i.repoURL,
71-
"commit": i.commit,
72-
"dir": path.Join(i.moduleDir, dir),
77+
"repo": i.repoURL,
78+
"importPath": path.Join(strings.TrimPrefix(i.repoURL, "https://"), dir),
79+
"commit": i.commit,
80+
"dir": path.Join(i.moduleDir, dir),
7381
}), "/")
7482
}
7583

@@ -78,10 +86,13 @@ func (i *Info) FileURL(pathname string) string {
7886
if i == nil {
7987
return ""
8088
}
89+
dir, base := path.Split(pathname)
8190
return expand(i.templates.File, map[string]string{
82-
"repo": i.repoURL,
83-
"commit": i.commit,
84-
"file": path.Join(i.moduleDir, pathname),
91+
"repo": i.repoURL,
92+
"importPath": path.Join(strings.TrimPrefix(i.repoURL, "https://"), dir),
93+
"commit": i.commit,
94+
"file": path.Join(i.moduleDir, pathname),
95+
"base": base,
8596
})
8697
}
8798

@@ -90,11 +101,14 @@ func (i *Info) LineURL(pathname string, line int) string {
90101
if i == nil {
91102
return ""
92103
}
104+
dir, base := path.Split(pathname)
93105
return expand(i.templates.Line, map[string]string{
94-
"repo": i.repoURL,
95-
"commit": i.commit,
96-
"file": path.Join(i.moduleDir, pathname),
97-
"line": strconv.Itoa(line),
106+
"repo": i.repoURL,
107+
"importPath": path.Join(strings.TrimPrefix(i.repoURL, "https://"), dir),
108+
"commit": i.commit,
109+
"file": path.Join(i.moduleDir, pathname),
110+
"base": base,
111+
"line": strconv.Itoa(line),
98112
})
99113
}
100114

@@ -521,6 +535,17 @@ var patterns = []struct {
521535
// URLs anyway. See gogs/gogs#6242.
522536
templates: giteaURLTemplates,
523537
},
538+
539+
{
540+
pattern: `^(?P<repo>dmitri\.shuralyov\.com\/.+)$`,
541+
templates: urlTemplates{
542+
Repo: "{repo}/...",
543+
Directory: "https://gotools.org/{importPath}?rev={commit}",
544+
File: "https://gotools.org/{importPath}?rev={commit}#{base}",
545+
Line: "https://gotools.org/{importPath}?rev={commit}#{base}-L{line}",
546+
},
547+
},
548+
524549
// Patterns that match the general go command pattern, where they must have
525550
// a ".git" repo suffix in an import path. If matching a repo URL from a meta tag,
526551
// there is no ".git".
@@ -577,11 +602,23 @@ func giteaTransformCommit(commit string, isHash bool) string {
577602

578603
// urlTemplates describes how to build URLs from bits of source information.
579604
// The fields are exported for JSON encoding.
605+
//
606+
// The template variables are:
607+
//
608+
// • {repo} - Repository URL with "https://" prefix ("https://example.com/myrepo").
609+
// • {importPath} - Package import path ("example.com/myrepo/mypkg").
610+
// • {commit} - Tag name or commit hash corresponding to version ("v0.1.0" or "1234567890ab").
611+
// • {dir} - Path to directory of the package, relative to repo root ("mypkg").
612+
// • {file} - Path to file containing the identifier, relative to repo root ("mypkg/file.go").
613+
// • {base} - Base name of file containing the identifier, including file extension ("file.go").
614+
// • {line} - Line number for the identifier ("41").
615+
//
580616
type urlTemplates struct {
581-
Directory string // URL template for a directory, with {repo}, {commit} and {dir}
582-
File string // URL template for a file, with {repo}, {commit} and {file}
583-
Line string // URL template for a line, with {repo}, {commit}, {file} and {line}
584-
Raw string // URL template for the raw contents of a file, with {repo}, {repoPath}, {commit} and {file}
617+
Repo string `json:",omitempty"` // Optional URL template for the repository home page, with {repo}. If left empty, a default template "{repo}" is used.
618+
Directory string // URL template for a directory, with {repo}, {importPath}, {commit}, {dir}.
619+
File string // URL template for a file, with {repo}, {importPath}, {commit}, {file}, {base}.
620+
Line string // URL template for a line, with {repo}, {importPath}, {commit}, {file}, {base}, {line}.
621+
Raw string // Optional URL template for the raw contents of a file, with {repo}, {commit}, {file}.
585622
}
586623

587624
var (

internal/source/source_test.go

+28-4
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,34 @@ func TestModuleInfo(t *testing.T) {
333333
"https://github.com/gonum/gonum/blob/v0.6.1/doc.go#L1",
334334
"https://github.com/gonum/gonum/raw/v0.6.1/doc.go",
335335
},
336+
{
337+
"custom with gotools at repo root",
338+
"dmitri.shuralyov.com/gpu/mtl", "v0.0.0-20191203043605-d42048ed14fd", "mtl.go",
339+
340+
"https://dmitri.shuralyov.com/gpu/mtl/...",
341+
"https://gotools.org/dmitri.shuralyov.com/gpu/mtl?rev=d42048ed14fd",
342+
"https://gotools.org/dmitri.shuralyov.com/gpu/mtl?rev=d42048ed14fd#mtl.go",
343+
"https://gotools.org/dmitri.shuralyov.com/gpu/mtl?rev=d42048ed14fd#mtl.go-L1",
344+
"",
345+
},
346+
{
347+
"custom with gotools in subdir",
348+
"dmitri.shuralyov.com/gpu/mtl", "v0.0.0-20191203043605-d42048ed14fd", "example/movingtriangle/internal/coreanim/coreanim.go",
349+
350+
"https://dmitri.shuralyov.com/gpu/mtl/...",
351+
"https://gotools.org/dmitri.shuralyov.com/gpu/mtl?rev=d42048ed14fd",
352+
"https://gotools.org/dmitri.shuralyov.com/gpu/mtl/example/movingtriangle/internal/coreanim?rev=d42048ed14fd#coreanim.go",
353+
"https://gotools.org/dmitri.shuralyov.com/gpu/mtl/example/movingtriangle/internal/coreanim?rev=d42048ed14fd#coreanim.go-L1",
354+
"",
355+
},
336356
} {
337357
t.Run(test.desc, func(t *testing.T) {
338358
info, err := ModuleInfo(context.Background(), &Client{client}, test.modulePath, test.version)
339359
if err != nil {
340360
t.Fatal(err)
341361
}
342362

343-
check(t, "repo", info.repoURL, test.wantRepo)
363+
check(t, "repo", info.RepoURL(), test.wantRepo)
344364
check(t, "module", info.ModuleURL(), test.wantModule)
345365
check(t, "file", info.FileURL(test.file), test.wantFile)
346366
check(t, "line", info.LineURL(test.file, 1), test.wantLine)
@@ -837,6 +857,10 @@ func TestJSON(t *testing.T) {
837857
&Info{repoURL: "r", moduleDir: "m", commit: "c", templates: urlTemplates{File: "f"}},
838858
`{"RepoURL":"r","ModuleDir":"m","Commit":"c","Templates":{"Directory":"","File":"f","Line":"","Raw":""}}`,
839859
},
860+
{
861+
&Info{repoURL: "r", moduleDir: "m", commit: "c", templates: urlTemplates{Repo: "r", File: "f"}},
862+
`{"RepoURL":"r","ModuleDir":"m","Commit":"c","Templates":{"Repo":"r","Directory":"","File":"f","Line":"","Raw":""}}`,
863+
},
840864
} {
841865
bytes, err := json.Marshal(&test.in)
842866
if err != nil {
@@ -877,9 +901,9 @@ func TestURLTemplates(t *testing.T) {
877901
}
878902
}
879903

880-
check(p.templates.Directory, "commit", "dir")
881-
check(p.templates.File, "commit", "file")
882-
check(p.templates.Line, "commit", "file", "line")
904+
check(p.templates.Directory, "commit")
905+
check(p.templates.File, "commit")
906+
check(p.templates.Line, "commit", "line")
883907
check(p.templates.Raw, "commit", "file")
884908
}
885909
}

0 commit comments

Comments
 (0)