1
0
mirror of https://github.com/golang/go synced 2024-10-02 22:31:22 -06:00

goinstall: support for Bazaar+Launchpad

With these changes, goinstall is now able to use branches
maintained with Bazaar located in Launchpad.

Project aliases such as /project and /project/series are
supported in addition to specific user or team branches
such as /~user/project/branch.  Temporary branches under
the +junk special project are also supported.

As a curious side effect, since Launchpad is able to import
code from other locations, they can be indirectly
accessible too if desired.

R=rsc
CC=golang-dev
https://golang.org/cl/1699050
This commit is contained in:
Gustavo Niemeyer 2010-06-30 23:33:49 -07:00 committed by Russ Cox
parent 88744a9733
commit ae33032893
3 changed files with 88 additions and 43 deletions

View File

@ -42,6 +42,15 @@ if necessary. The recognized code hosting sites are:
import "project.googlecode.com/svn/trunk"
import "project.googlecode.com/svn/trunk/sub/directory"
Launchpad
import "launchpad.net/project
import "launchpad.net/project/series
import "launchpad.net/project/series/sub/directory
import "launchpad.net/~user/project/branch
import "launchpad.net/~user/project/branch/sub/directory
If the destination directory (e.g., $GOROOT/src/pkg/bitbucket.org/user/project)
already exists and contains an appropriate checkout, goinstall will not

View File

@ -34,6 +34,7 @@ func maybeReportToDashboard(path string) {
var googlecode = regexp.MustCompile(`^([a-z0-9\-]+\.googlecode\.com/(svn|hg))(/[a-z0-9A-Z_.\-/]*)?$`)
var github = regexp.MustCompile(`^(github\.com/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(/[a-z0-9A-Z_.\-/]*)?$`)
var bitbucket = regexp.MustCompile(`^(bitbucket\.org/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(/[a-z0-9A-Z_.\-/]*)?$`)
var launchpad = regexp.MustCompile(`^(launchpad\.net/([a-z0-9A-Z_.\-]+(/[a-z0-9A-Z_.\-]+)?|~[a-z0-9A-Z_.\-]+/(\+junk|[a-z0-9A-Z_.\-]+)/[a-z0-9A-Z_.\-]+))(/[a-z0-9A-Z_.\-/]+)?$`)
// download checks out or updates pkg from the remote server.
func download(pkg string) (string, os.Error) {
@ -71,53 +72,78 @@ func download(pkg string) (string, os.Error) {
}
return root + pkg, nil
}
if m := launchpad.MatchStrings(pkg); m != nil {
// Either lp.net/<project>[/<series>[/<path>]]
// or lp.net/~<user or team>/<project>/<branch>[/<path>]
if err := vcsCheckout(&bzr, root+m[1], "https://"+m[1], m[1]); err != nil {
return "", err
}
return root + pkg, nil
}
return "", os.ErrorString("unknown repository: " + pkg)
}
// a vcs represents a version control system
// like Mercurial, Git, or Subversion.
type vcs struct {
cmd string
metadir string
clone string
update string
pull string
log string
logLimitFlag string
logReleaseFlag string
cmd string
metadir string
clone string
update string
updateReleaseFlag string
pull string
pullForceFlag string
log string
logLimitFlag string
logReleaseFlag string
}
var hg = vcs{
cmd: "hg",
metadir: ".hg",
clone: "clone",
update: "update",
pull: "pull",
log: "log",
logLimitFlag: "-l1",
logReleaseFlag: "-rrelease",
cmd: "hg",
metadir: ".hg",
clone: "clone",
update: "update",
updateReleaseFlag: "release",
pull: "pull",
log: "log",
logLimitFlag: "-l1",
logReleaseFlag: "-rrelease",
}
var git = vcs{
cmd: "git",
metadir: ".git",
clone: "clone",
update: "pull",
pull: "fetch",
log: "log",
logLimitFlag: "-n1",
logReleaseFlag: "release",
cmd: "git",
metadir: ".git",
clone: "clone",
update: "pull",
updateReleaseFlag: "release",
pull: "fetch",
log: "log",
logLimitFlag: "-n1",
logReleaseFlag: "release",
}
var svn = vcs{
cmd: "svn",
metadir: ".svn",
clone: "checkout",
update: "update",
pull: "",
log: "log",
logLimitFlag: "-l1",
logReleaseFlag: "release",
cmd: "svn",
metadir: ".svn",
clone: "checkout",
update: "update",
updateReleaseFlag: "release",
log: "log",
logLimitFlag: "-l1",
logReleaseFlag: "release",
}
var bzr = vcs{
cmd: "bzr",
metadir: ".bzr",
clone: "branch",
update: "update",
updateReleaseFlag: "-rrelease",
pull: "pull",
pullForceFlag: "--overwrite",
log: "log",
logLimitFlag: "-l1",
logReleaseFlag: "-rrelease",
}
// vcsCheckout checks out repo into dst using vcs.
@ -138,27 +164,37 @@ func vcsCheckout(vcs *vcs, dst, repo, dashpath string) os.Error {
if err := run("/", nil, vcs.cmd, vcs.clone, repo, dst); err != nil {
return err
}
quietRun(dst, nil, vcs.cmd, vcs.update, "release")
quietRun(dst, nil, vcs.cmd, vcs.update, vcs.updateReleaseFlag)
// success on first installation - report
maybeReportToDashboard(dashpath)
} else if *update {
// Retrieve new revisions from the remote branch, if the VCS
// supports this operation independently (e.g. svn doesn't)
if vcs.pull != "" {
if err := run(dst, nil, vcs.cmd, vcs.pull); err != nil {
if vcs.pullForceFlag != "" {
if err := run(dst, nil, vcs.cmd, vcs.pull, vcs.pullForceFlag); err != nil {
return err
}
} else if err := run(dst, nil, vcs.cmd, vcs.pull); err != nil {
return err
}
}
// check for release with hg log -l 1 -r release
// if success, hg update release
// else hg update
// Try to detect if a "release" tag exists. If it does, update
// to the tagged version. If no tag is found, then update to the
// tip afterwards.
// NOTE(gustavo@niemeyer.net): What is the expected behavior with
// svn here? "svn log -l1 release" doesn't make sense in this
// context and will probably fail.
if err := quietRun(dst, nil, vcs.cmd, vcs.log, vcs.logLimitFlag, vcs.logReleaseFlag); err == nil {
if err := run(dst, nil, vcs.cmd, vcs.update, "release"); err != nil {
return err
}
} else {
if err := run(dst, nil, vcs.cmd, vcs.update); err != nil {
if err := run(dst, nil, vcs.cmd, vcs.update, vcs.updateReleaseFlag); err != nil {
// The VCS supports tagging, has the "release" tag, but
// something else went wrong. Report.
return err
}
} else if err := run(dst, nil, vcs.cmd, vcs.update); err != nil {
return err
}
}
return nil

View File

@ -184,7 +184,7 @@ func quietRun(dir string, stdin []byte, cmd ...string) os.Error {
return genRun(dir, stdin, cmd, true)
}
// genRun implements run and tryRun.
// genRun implements run and quietRun.
func genRun(dir string, stdin []byte, cmd []string, quiet bool) os.Error {
bin, err := exec.LookPath(cmd[0])
if err != nil {