getSrcBranchURL returns a link to the source on the web and the tag name for the package version, if possible.
(c *Call)
| 132 | // getSrcBranchURL returns a link to the source on the web and the tag name for |
| 133 | // the package version, if possible. |
| 134 | func getSrcBranchURL(c *Call) (template.URL, template.URL) { |
| 135 | tag := "" |
| 136 | if c.Location == Stdlib { |
| 137 | // TODO(maruel): This is not strictly speaking correct. The remote could be |
| 138 | // running a different Go version from the current executable. |
| 139 | ver := runtime.Version() |
| 140 | const devel = "devel +" |
| 141 | if strings.HasPrefix(ver, devel) { |
| 142 | ver = ver[len(devel) : len(devel)+10] |
| 143 | } |
| 144 | tag = url.QueryEscape(ver) |
| 145 | /* #nosec G203 */ |
| 146 | return template.URL(fmt.Sprintf("https://github.com/golang/go/blob/%s/src/%s#L%d", tag, escape(c.RelSrcPath), c.Line)), template.URL(tag) |
| 147 | } |
| 148 | // TODO(maruel): Leverage Location. |
| 149 | if rel := c.RelSrcPath; rel != "" { |
| 150 | // Check for vendored code first. |
| 151 | if i := strings.Index(rel, "/vendor/"); i != -1 { |
| 152 | rel = rel[i+8:] |
| 153 | } |
| 154 | // Specialized support for github and golang.org. This will cover a fair |
| 155 | // share of the URLs, but it'd be nice to support others too. Please submit |
| 156 | // a PR (including a unit test that I was too lazy to add yet). |
| 157 | switch host, rest := splitHost(rel); host { |
| 158 | case "github.com": |
| 159 | if parts := strings.SplitN(rest, "/", 3); len(parts) == 3 { |
| 160 | p, srcTag, tag := splitTag(parts[1]) |
| 161 | url := fmt.Sprintf("https://github.com/%s/%s/blob/%s/%s#L%d", escape(parts[0]), p, srcTag, escape(parts[2]), c.Line) |
| 162 | /* #nosec G203 */ |
| 163 | return template.URL(url), tag |
| 164 | } |
| 165 | log.Printf("problematic github.com URL: %q", rel) |
| 166 | case "golang.org": |
| 167 | // https://github.com/golang/build/blob/HEAD/repos/repos.go lists all |
| 168 | // the golang.org/x/<foo> packages. |
| 169 | if parts := strings.SplitN(rest, "/", 3); len(parts) == 3 && parts[0] == "x" { |
| 170 | // parts is: "x", <project@version>, <path inside the repo>. |
| 171 | p, srcTag, tag := splitTag(parts[1]) |
| 172 | // The source of truth is are actually go.googlesource.com, but |
| 173 | // github.com has nicer syntax highlighting. |
| 174 | url := fmt.Sprintf("https://github.com/golang/%s/blob/%s/%s#L%d", p, srcTag, escape(parts[2]), c.Line) |
| 175 | /* #nosec G203 */ |
| 176 | return template.URL(url), tag |
| 177 | } |
| 178 | log.Printf("problematic golang.org URL: %q", rel) |
| 179 | default: |
| 180 | // For example gopkg.in. In this case there's no known way to find the |
| 181 | // link to the source files, but we can still try to extract the version |
| 182 | // if fetched from a go module. |
| 183 | // Do a best effort to find a version by searching for a '@'. |
| 184 | if i := strings.IndexByte(rel, '@'); i != -1 { |
| 185 | if j := strings.IndexByte(rel[i:], '/'); j != -1 { |
| 186 | tag = rel[i+1 : i+j] |
| 187 | } |
| 188 | } |
| 189 | } |
| 190 | } |
| 191 |
searching dependent graphs…