mirror of
https://github.com/golang/go
synced 2024-11-21 23:24:41 -07:00
cmd/go: go get scheme detection
Fixes #2895. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/5651055
This commit is contained in:
parent
222e2ee4d5
commit
dcf5ca706b
@ -27,6 +27,9 @@ type vcsCmd struct {
|
|||||||
tagLookupCmd []tagCmd // commands to lookup tags before running tagSyncCmd
|
tagLookupCmd []tagCmd // commands to lookup tags before running tagSyncCmd
|
||||||
tagSyncCmd string // command to sync to specific tag
|
tagSyncCmd string // command to sync to specific tag
|
||||||
tagSyncDefault string // command to sync to default tag
|
tagSyncDefault string // command to sync to default tag
|
||||||
|
|
||||||
|
scheme []string
|
||||||
|
pingCmd string
|
||||||
}
|
}
|
||||||
|
|
||||||
// A tagCmd describes a command to list available tags
|
// A tagCmd describes a command to list available tags
|
||||||
@ -74,6 +77,9 @@ var vcsHg = &vcsCmd{
|
|||||||
},
|
},
|
||||||
tagSyncCmd: "update -r {tag}",
|
tagSyncCmd: "update -r {tag}",
|
||||||
tagSyncDefault: "update default",
|
tagSyncDefault: "update default",
|
||||||
|
|
||||||
|
scheme: []string{"https", "http"},
|
||||||
|
pingCmd: "identify {scheme}://{repo}",
|
||||||
}
|
}
|
||||||
|
|
||||||
// vcsGit describes how to use Git.
|
// vcsGit describes how to use Git.
|
||||||
@ -94,6 +100,9 @@ var vcsGit = &vcsCmd{
|
|||||||
},
|
},
|
||||||
tagSyncCmd: "checkout {tag}",
|
tagSyncCmd: "checkout {tag}",
|
||||||
tagSyncDefault: "checkout origin/master",
|
tagSyncDefault: "checkout origin/master",
|
||||||
|
|
||||||
|
scheme: []string{"git", "https", "http"},
|
||||||
|
pingCmd: "ls-remote {scheme}://{repo}",
|
||||||
}
|
}
|
||||||
|
|
||||||
// vcsBzr describes how to use Bazaar.
|
// vcsBzr describes how to use Bazaar.
|
||||||
@ -110,6 +119,9 @@ var vcsBzr = &vcsCmd{
|
|||||||
tagCmd: []tagCmd{{"tags", `^(\S+)`}},
|
tagCmd: []tagCmd{{"tags", `^(\S+)`}},
|
||||||
tagSyncCmd: "update -r {tag}",
|
tagSyncCmd: "update -r {tag}",
|
||||||
tagSyncDefault: "update -r revno:-1",
|
tagSyncDefault: "update -r revno:-1",
|
||||||
|
|
||||||
|
scheme: []string{"https", "http", "bzr"},
|
||||||
|
pingCmd: "info {scheme}://{repo}",
|
||||||
}
|
}
|
||||||
|
|
||||||
// vcsSvn describes how to use Subversion.
|
// vcsSvn describes how to use Subversion.
|
||||||
@ -122,6 +134,9 @@ var vcsSvn = &vcsCmd{
|
|||||||
|
|
||||||
// There is no tag command in subversion.
|
// There is no tag command in subversion.
|
||||||
// The branch information is all in the path names.
|
// The branch information is all in the path names.
|
||||||
|
|
||||||
|
scheme: []string{"https", "http", "svn"},
|
||||||
|
pingCmd: "info {scheme}://{repo}",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *vcsCmd) String() string {
|
func (v *vcsCmd) String() string {
|
||||||
@ -136,17 +151,23 @@ func (v *vcsCmd) String() string {
|
|||||||
// command's combined stdout+stderr to standard error.
|
// command's combined stdout+stderr to standard error.
|
||||||
// Otherwise run discards the command's output.
|
// Otherwise run discards the command's output.
|
||||||
func (v *vcsCmd) run(dir string, cmd string, keyval ...string) error {
|
func (v *vcsCmd) run(dir string, cmd string, keyval ...string) error {
|
||||||
_, err := v.run1(dir, cmd, keyval)
|
_, err := v.run1(dir, cmd, keyval, true)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// runVerboseOnly is like run but only generates error output to standard error in verbose mode.
|
||||||
|
func (v *vcsCmd) runVerboseOnly(dir string, cmd string, keyval ...string) error {
|
||||||
|
_, err := v.run1(dir, cmd, keyval, false)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// runOutput is like run but returns the output of the command.
|
// runOutput is like run but returns the output of the command.
|
||||||
func (v *vcsCmd) runOutput(dir string, cmd string, keyval ...string) ([]byte, error) {
|
func (v *vcsCmd) runOutput(dir string, cmd string, keyval ...string) ([]byte, error) {
|
||||||
return v.run1(dir, cmd, keyval)
|
return v.run1(dir, cmd, keyval, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// run1 is the generalized implementation of run and runOutput.
|
// run1 is the generalized implementation of run and runOutput.
|
||||||
func (v *vcsCmd) run1(dir string, cmdline string, keyval []string) ([]byte, error) {
|
func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) ([]byte, error) {
|
||||||
m := make(map[string]string)
|
m := make(map[string]string)
|
||||||
for i := 0; i < len(keyval); i += 2 {
|
for i := 0; i < len(keyval); i += 2 {
|
||||||
m[keyval[i]] = keyval[i+1]
|
m[keyval[i]] = keyval[i+1]
|
||||||
@ -168,13 +189,20 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string) ([]byte, erro
|
|||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
out := buf.Bytes()
|
out := buf.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.cmd, strings.Join(args, " "))
|
if verbose || buildV {
|
||||||
os.Stderr.Write(out)
|
fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.cmd, strings.Join(args, " "))
|
||||||
|
os.Stderr.Write(out)
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ping pings to determine scheme to use.
|
||||||
|
func (v *vcsCmd) ping(scheme, repo string) error {
|
||||||
|
return v.runVerboseOnly(".", v.pingCmd, "scheme", scheme, "repo", repo)
|
||||||
|
}
|
||||||
|
|
||||||
// create creates a new copy of repo in dir.
|
// create creates a new copy of repo in dir.
|
||||||
// The parent of dir must exist; dir must not.
|
// The parent of dir must exist; dir must not.
|
||||||
func (v *vcsCmd) create(dir, repo string) error {
|
func (v *vcsCmd) create(dir, repo string) error {
|
||||||
@ -236,6 +264,7 @@ type vcsPath struct {
|
|||||||
repo string // repository to use (expand with match of re)
|
repo string // repository to use (expand with match of re)
|
||||||
vcs string // version control system to use (expand with match of re)
|
vcs string // version control system to use (expand with match of re)
|
||||||
check func(match map[string]string) error // additional checks
|
check func(match map[string]string) error // additional checks
|
||||||
|
ping bool // ping for scheme to use to download repo
|
||||||
|
|
||||||
regexp *regexp.Regexp // cached compiled form of re
|
regexp *regexp.Regexp // cached compiled form of re
|
||||||
}
|
}
|
||||||
@ -283,6 +312,14 @@ func vcsForImportPath(importPath string) (vcs *vcsCmd, repo, root string, err er
|
|||||||
if vcs == nil {
|
if vcs == nil {
|
||||||
return nil, "", "", fmt.Errorf("unknown version control system %q", match["vcs"])
|
return nil, "", "", fmt.Errorf("unknown version control system %q", match["vcs"])
|
||||||
}
|
}
|
||||||
|
if srv.ping {
|
||||||
|
for _, scheme := range vcs.scheme {
|
||||||
|
if vcs.ping(scheme, match["repo"]) == nil {
|
||||||
|
match["repo"] = scheme + "://" + match["repo"]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return vcs, match["repo"], match["root"], nil
|
return vcs, match["repo"], match["root"], nil
|
||||||
}
|
}
|
||||||
return nil, "", "", fmt.Errorf("unrecognized import path %q", importPath)
|
return nil, "", "", fmt.Errorf("unrecognized import path %q", importPath)
|
||||||
@ -340,7 +377,8 @@ var vcsPaths = []*vcsPath{
|
|||||||
|
|
||||||
// General syntax for any server.
|
// General syntax for any server.
|
||||||
{
|
{
|
||||||
re: `^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/]*?)\.(?P<vcs>bzr|git|hg|svn))(/[A-Za-z0-9_.\-]+)*$`,
|
re: `^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/]*?)\.(?P<vcs>bzr|git|hg|svn))(/[A-Za-z0-9_.\-]+)*$`,
|
||||||
|
ping: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user