Commit a444da03 authored by Tamir Duberstein's avatar Tamir Duberstein Committed by Russ Cox

cmd/go: fetch git submodules in `go get`

Change createCmd, downloadCmd, tagSyncCmd, tagSyncDefault to allow
multiple commands.

When using the vendoring experiment, fetch git submodules in `go get`,
and update them in `go get -u`.

This is a reincarnation of https://codereview.appspot.com/142180043.

For #7764.

Change-Id: I8248efb851130620ef762a765ab8716af430572a
Reviewed-on: https://go-review.googlesource.com/9815Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
parent ebfc5be5
...@@ -26,13 +26,13 @@ type vcsCmd struct { ...@@ -26,13 +26,13 @@ type vcsCmd struct {
name string name string
cmd string // name of binary to invoke command cmd string // name of binary to invoke command
createCmd string // command to download a fresh copy of a repository createCmd []string // commands to download a fresh copy of a repository
downloadCmd string // command to download updates into an existing repository downloadCmd []string // commands to download updates into an existing repository
tagCmd []tagCmd // commands to list tags tagCmd []tagCmd // commands to list tags
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 // commands to sync to specific tag
tagSyncDefault string // command to sync to default tag tagSyncDefault []string // commands to sync to default tag
scheme []string scheme []string
pingCmd string pingCmd string
...@@ -88,8 +88,8 @@ var vcsHg = &vcsCmd{ ...@@ -88,8 +88,8 @@ var vcsHg = &vcsCmd{
name: "Mercurial", name: "Mercurial",
cmd: "hg", cmd: "hg",
createCmd: "clone -U {repo} {dir}", createCmd: []string{"clone -U {repo} {dir}"},
downloadCmd: "pull", downloadCmd: []string{"pull"},
// We allow both tag and branch names as 'tags' // We allow both tag and branch names as 'tags'
// for selecting a version. This lets people have // for selecting a version. This lets people have
...@@ -100,8 +100,8 @@ var vcsHg = &vcsCmd{ ...@@ -100,8 +100,8 @@ var vcsHg = &vcsCmd{
{"tags", `^(\S+)`}, {"tags", `^(\S+)`},
{"branches", `^(\S+)`}, {"branches", `^(\S+)`},
}, },
tagSyncCmd: "update -r {tag}", tagSyncCmd: []string{"update -r {tag}"},
tagSyncDefault: "update default", tagSyncDefault: []string{"update default"},
scheme: []string{"https", "http", "ssh"}, scheme: []string{"https", "http", "ssh"},
pingCmd: "identify {scheme}://{repo}", pingCmd: "identify {scheme}://{repo}",
...@@ -121,8 +121,8 @@ var vcsGit = &vcsCmd{ ...@@ -121,8 +121,8 @@ var vcsGit = &vcsCmd{
name: "Git", name: "Git",
cmd: "git", cmd: "git",
createCmd: "clone {repo} {dir}", createCmd: []string{"clone {repo} {dir}", "--git-dir={dir}/.git submodule update --init --recursive"},
downloadCmd: "pull --ff-only", downloadCmd: []string{"pull --ff-only", "submodule update --init --recursive"},
tagCmd: []tagCmd{ tagCmd: []tagCmd{
// tags/xxx matches a git tag named xxx // tags/xxx matches a git tag named xxx
...@@ -132,12 +132,12 @@ var vcsGit = &vcsCmd{ ...@@ -132,12 +132,12 @@ var vcsGit = &vcsCmd{
tagLookupCmd: []tagCmd{ tagLookupCmd: []tagCmd{
{"show-ref tags/{tag} origin/{tag}", `((?:tags|origin)/\S+)$`}, {"show-ref tags/{tag} origin/{tag}", `((?:tags|origin)/\S+)$`},
}, },
tagSyncCmd: "checkout {tag}", tagSyncCmd: []string{"checkout {tag}", "submodule update --init --recursive"},
// both createCmd and downloadCmd update the working dir. // both createCmd and downloadCmd update the working dir.
// No need to do more here. We used to 'checkout master' // No need to do more here. We used to 'checkout master'
// but that doesn't work if the default branch is not named master. // but that doesn't work if the default branch is not named master.
// See golang.org/issue/9032. // See golang.org/issue/9032.
tagSyncDefault: "", tagSyncDefault: []string{"checkout master", "submodule update --init --recursive"},
scheme: []string{"git", "https", "http", "git+ssh"}, scheme: []string{"git", "https", "http", "git+ssh"},
pingCmd: "ls-remote {scheme}://{repo}", pingCmd: "ls-remote {scheme}://{repo}",
...@@ -178,15 +178,15 @@ var vcsBzr = &vcsCmd{ ...@@ -178,15 +178,15 @@ var vcsBzr = &vcsCmd{
name: "Bazaar", name: "Bazaar",
cmd: "bzr", cmd: "bzr",
createCmd: "branch {repo} {dir}", createCmd: []string{"branch {repo} {dir}"},
// Without --overwrite bzr will not pull tags that changed. // Without --overwrite bzr will not pull tags that changed.
// Replace by --overwrite-tags after http://pad.lv/681792 goes in. // Replace by --overwrite-tags after http://pad.lv/681792 goes in.
downloadCmd: "pull --overwrite", downloadCmd: []string{"pull --overwrite"},
tagCmd: []tagCmd{{"tags", `^(\S+)`}}, tagCmd: []tagCmd{{"tags", `^(\S+)`}},
tagSyncCmd: "update -r {tag}", tagSyncCmd: []string{"update -r {tag}"},
tagSyncDefault: "update -r revno:-1", tagSyncDefault: []string{"update -r revno:-1"},
scheme: []string{"https", "http", "bzr", "bzr+ssh"}, scheme: []string{"https", "http", "bzr", "bzr+ssh"},
pingCmd: "info {scheme}://{repo}", pingCmd: "info {scheme}://{repo}",
...@@ -240,8 +240,8 @@ var vcsSvn = &vcsCmd{ ...@@ -240,8 +240,8 @@ var vcsSvn = &vcsCmd{
name: "Subversion", name: "Subversion",
cmd: "svn", cmd: "svn",
createCmd: "checkout {repo} {dir}", createCmd: []string{"checkout {repo} {dir}"},
downloadCmd: "update", downloadCmd: []string{"update"},
// 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.
...@@ -352,7 +352,15 @@ func (v *vcsCmd) ping(scheme, repo string) error { ...@@ -352,7 +352,15 @@ func (v *vcsCmd) ping(scheme, repo string) error {
// 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 {
return v.run(".", v.createCmd, "dir", dir, "repo", repo) for _, cmd := range v.createCmd {
if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
continue
}
if err := v.run(".", cmd, "dir", dir, "repo", repo); err != nil {
return err
}
}
return nil
} }
// download downloads any new changes for the repo in dir. // download downloads any new changes for the repo in dir.
...@@ -360,7 +368,15 @@ func (v *vcsCmd) download(dir string) error { ...@@ -360,7 +368,15 @@ func (v *vcsCmd) download(dir string) error {
if err := v.fixDetachedHead(dir); err != nil { if err := v.fixDetachedHead(dir); err != nil {
return err return err
} }
return v.run(dir, v.downloadCmd) for _, cmd := range v.downloadCmd {
if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
continue
}
if err := v.run(dir, cmd); err != nil {
return err
}
}
return nil
} }
// fixDetachedHead switches a Git repository in dir from a detached head to the master branch. // fixDetachedHead switches a Git repository in dir from a detached head to the master branch.
...@@ -406,7 +422,7 @@ func (v *vcsCmd) tags(dir string) ([]string, error) { ...@@ -406,7 +422,7 @@ func (v *vcsCmd) tags(dir string) ([]string, error) {
// tagSync syncs the repo in dir to the named tag, // tagSync syncs the repo in dir to the named tag,
// which either is a tag returned by tags or is v.tagDefault. // which either is a tag returned by tags or is v.tagDefault.
func (v *vcsCmd) tagSync(dir, tag string) error { func (v *vcsCmd) tagSync(dir, tag string) error {
if v.tagSyncCmd == "" { if v.tagSyncCmd == nil {
return nil return nil
} }
if tag != "" { if tag != "" {
...@@ -423,10 +439,28 @@ func (v *vcsCmd) tagSync(dir, tag string) error { ...@@ -423,10 +439,28 @@ func (v *vcsCmd) tagSync(dir, tag string) error {
} }
} }
} }
if tag == "" && v.tagSyncDefault != "" {
return v.run(dir, v.tagSyncDefault) if tag == "" && v.tagSyncDefault != nil {
for _, cmd := range v.tagSyncDefault {
if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
continue
}
if err := v.run(dir, cmd); err != nil {
return err
}
}
return nil
}
for _, cmd := range v.tagSyncCmd {
if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
continue
}
if err := v.run(dir, cmd, "tag", tag); err != nil {
return err
}
} }
return v.run(dir, v.tagSyncCmd, "tag", tag) return nil
} }
// A vcsPath describes how to convert an import path into a // A vcsPath describes how to convert an import path into a
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment