blob: e74128b63bbda963474ffe6a4522ce6fb0c2c48d [file] [log] [blame]
// Copyright 2013 The Go Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd.
package main
import (
"net/url"
"path"
"regexp"
"strings"
)
func importPathFromGoogleBrowse(m []string) string {
project := m[1]
dir := m[2]
if dir == "" {
dir = "/"
} else if dir[len(dir)-1] == '/' {
dir = dir[:len(dir)-1]
}
subrepo := ""
if len(m[3]) > 0 {
v, _ := url.ParseQuery(m[3][1:])
subrepo = v.Get("repo")
if len(subrepo) > 0 {
subrepo = "." + subrepo
}
}
if strings.HasPrefix(m[4], "#hg%2F") {
d, _ := url.QueryUnescape(m[4][len("#hg%2f"):])
if i := strings.IndexRune(d, '%'); i >= 0 {
d = d[:i]
}
dir = dir + "/" + d
}
return "code.google.com/p/" + project + subrepo + dir
}
var browsePatterns = []struct {
pat *regexp.Regexp
fn func([]string) string
}{
{
// GitHub tree browser.
regexp.MustCompile(`^https?://(github\.com/[^/]+/[^/]+)(?:/tree/[^/]+(/.*))?$`),
func(m []string) string { return m[1] + m[2] },
},
{
// GitHub file browser.
regexp.MustCompile(`^https?://(github\.com/[^/]+/[^/]+)/blob/[^/]+/(.*)$`),
func(m []string) string {
d := path.Dir(m[2])
if d == "." {
return m[1]
}
return m[1] + "/" + d
},
},
{
// GitHub issues, pulls, etc.
regexp.MustCompile(`^https?://(github\.com/[^/]+/[^/]+)(.*)$`),
func(m []string) string { return m[1] },
},
{
// Bitbucket source borwser.
regexp.MustCompile(`^https?://(bitbucket\.org/[^/]+/[^/]+)(?:/src/[^/]+(/[^?]+)?)?`),
func(m []string) string { return m[1] + m[2] },
},
{
// Google Project Hosting source browser.
regexp.MustCompile(`^http:/+code\.google\.com/p/([^/]+)/source/browse(/[^?#]*)?(\?[^#]*)?(#.*)?$`),
importPathFromGoogleBrowse,
},
{
// Launchpad source browser.
regexp.MustCompile(`^https?:/+bazaar\.(launchpad\.net/.*)/files$`),
func(m []string) string { return m[1] },
},
{
regexp.MustCompile(`^https?://(.+)$`),
func(m []string) string { return strings.Trim(m[1], "/") },
},
}
// isBrowserURL returns importPath and true if URL looks like a URL for a VCS
// source browser.
func isBrowseURL(s string) (importPath string, ok bool) {
for _, c := range browsePatterns {
if m := c.pat.FindStringSubmatch(s); m != nil {
return c.fn(m), true
}
}
return "", false
}