summaryrefslogtreecommitdiff
path: root/src/cmd/goinstall/download.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/goinstall/download.go')
-rw-r--r--src/cmd/goinstall/download.go306
1 files changed, 0 insertions, 306 deletions
diff --git a/src/cmd/goinstall/download.go b/src/cmd/goinstall/download.go
deleted file mode 100644
index da892a69d..000000000
--- a/src/cmd/goinstall/download.go
+++ /dev/null
@@ -1,306 +0,0 @@
-// Copyright 2010 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.
-
-// Download remote packages.
-
-package main
-
-import (
- "exec"
- "fmt"
- "http"
- "os"
- "path/filepath"
- "regexp"
- "strings"
-)
-
-const dashboardURL = "http://godashboard.appspot.com/package"
-
-// maybeReportToDashboard reports path to dashboard unless
-// -dashboard=false is on command line. It ignores errors.
-func maybeReportToDashboard(path string) {
- // if -dashboard=false was on command line, do nothing
- if !*reportToDashboard {
- return
- }
-
- // otherwise lob url to dashboard
- r, _ := http.Post(dashboardURL, "application/x-www-form-urlencoded", strings.NewReader("path="+path))
- if r != nil && r.Body != nil {
- r.Body.Close()
- }
-}
-
-// a vcs represents a version control system
-// like Mercurial, Git, or Subversion.
-type vcs struct {
- name string
- cmd string
- metadir string
- checkout string
- clone string
- update string
- updateReleaseFlag string
- pull string
- pullForceFlag string
- log string
- logLimitFlag string
- logReleaseFlag string
- check string
- protocols []string
- suffix string
- defaultHosts []host
-}
-
-type host struct {
- pattern *regexp.Regexp
- protocol string
- suffix string
-}
-
-var hg = vcs{
- name: "Mercurial",
- cmd: "hg",
- metadir: ".hg",
- checkout: "checkout",
- clone: "clone",
- update: "update",
- updateReleaseFlag: "release",
- pull: "pull",
- log: "log",
- logLimitFlag: "-l1",
- logReleaseFlag: "-rrelease",
- check: "identify",
- protocols: []string{"https", "http"},
- suffix: ".hg",
- defaultHosts: []host{
- {regexp.MustCompile(`^([a-z0-9\-]+\.googlecode\.com/hg)(/[a-z0-9A-Z_.\-/]*)?$`), "https", ""},
- {regexp.MustCompile(`^(bitbucket\.org/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(/[a-z0-9A-Z_.\-/]*)?$`), "http", ""},
- },
-}
-
-var git = vcs{
- name: "Git",
- cmd: "git",
- metadir: ".git",
- checkout: "checkout",
- clone: "clone",
- update: "pull",
- updateReleaseFlag: "release",
- pull: "fetch",
- log: "show-ref",
- logLimitFlag: "",
- logReleaseFlag: "release",
- check: "ls-remote",
- protocols: []string{"git", "https", "http"},
- suffix: ".git",
- defaultHosts: []host{
- {regexp.MustCompile(`^(github\.com/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(/[a-z0-9A-Z_.\-/]*)?$`), "http", ".git"},
- },
-}
-
-var svn = vcs{
- name: "Subversion",
- cmd: "svn",
- metadir: ".svn",
- checkout: "checkout",
- clone: "checkout",
- update: "update",
- updateReleaseFlag: "release",
- log: "log",
- logLimitFlag: "-l1",
- logReleaseFlag: "release",
- check: "info",
- protocols: []string{"https", "http", "svn"},
- suffix: ".svn",
- defaultHosts: []host{
- {regexp.MustCompile(`^([a-z0-9\-]+\.googlecode\.com/svn)(/[a-z0-9A-Z_.\-/]*)?$`), "https", ""},
- },
-}
-
-var bzr = vcs{
- name: "Bazaar",
- cmd: "bzr",
- metadir: ".bzr",
- checkout: "update",
- clone: "branch",
- update: "update",
- updateReleaseFlag: "-rrelease",
- pull: "pull",
- pullForceFlag: "--overwrite",
- log: "log",
- logLimitFlag: "-l1",
- logReleaseFlag: "-rrelease",
- check: "info",
- protocols: []string{"https", "http", "bzr"},
- suffix: ".bzr",
- defaultHosts: []host{
- {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_.\-/]+)?$`), "https", ""},
- },
-}
-
-var vcsList = []*vcs{&git, &hg, &bzr, &svn}
-
-type vcsMatch struct {
- *vcs
- prefix, repo string
-}
-
-// findHostedRepo checks whether pkg is located at one of
-// the supported code hosting sites and, if so, returns a match.
-func findHostedRepo(pkg string) (*vcsMatch, os.Error) {
- for _, v := range vcsList {
- for _, host := range v.defaultHosts {
- if hm := host.pattern.FindStringSubmatch(pkg); hm != nil {
- if host.suffix != "" && strings.HasSuffix(hm[1], host.suffix) {
- return nil, os.NewError("repository " + pkg + " should not have " + v.suffix + " suffix")
- }
- repo := host.protocol + "://" + hm[1] + host.suffix
- return &vcsMatch{v, hm[1], repo}, nil
- }
- }
- }
- return nil, nil
-}
-
-// findAnyRepo looks for a vcs suffix in pkg (.git, etc) and returns a match.
-func findAnyRepo(pkg string) (*vcsMatch, os.Error) {
- for _, v := range vcsList {
- i := strings.Index(pkg+"/", v.suffix+"/")
- if i < 0 {
- continue
- }
- if !strings.Contains(pkg[:i], "/") {
- continue // don't match vcs suffix in the host name
- }
- if m := v.find(pkg[:i]); m != nil {
- return m, nil
- }
- return nil, fmt.Errorf("couldn't find %s repository", v.name)
- }
- return nil, nil
-}
-
-func (v *vcs) find(pkg string) *vcsMatch {
- for _, proto := range v.protocols {
- for _, suffix := range []string{"", v.suffix} {
- repo := proto + "://" + pkg + suffix
- out, err := exec.Command(v.cmd, v.check, repo).CombinedOutput()
- if err == nil {
- printf("find %s: found %s\n", pkg, repo)
- return &vcsMatch{v, pkg + v.suffix, repo}
- }
- printf("find %s: %s %s %s: %v\n%s\n", pkg, v.cmd, v.check, repo, err, out)
- }
- }
- return nil
-}
-
-// isRemote returns true if the first part of the package name looks like a
-// hostname - i.e. contains at least one '.' and the last part is at least 2
-// characters.
-func isRemote(pkg string) bool {
- parts := strings.SplitN(pkg, "/", 2)
- if len(parts) != 2 {
- return false
- }
- parts = strings.Split(parts[0], ".")
- if len(parts) < 2 || len(parts[len(parts)-1]) < 2 {
- return false
- }
- return true
-}
-
-// download checks out or updates pkg from the remote server.
-func download(pkg, srcDir string) (dashReport bool, err os.Error) {
- if strings.Contains(pkg, "..") {
- err = os.NewError("invalid path (contains ..)")
- return
- }
- m, err := findHostedRepo(pkg)
- if err != nil {
- return
- }
- if m != nil {
- dashReport = true // only report public code hosting sites
- } else {
- m, err = findAnyRepo(pkg)
- if err != nil {
- return
- }
- }
- if m == nil {
- err = os.NewError("cannot download: " + pkg)
- return
- }
- installed, err := m.checkoutRepo(srcDir, m.prefix, m.repo)
- if err != nil {
- return
- }
- if !installed {
- dashReport = false
- }
- return
-}
-
-// Try to detect if a "release" tag exists. If it does, update
-// to the tagged version, otherwise just update the current branch.
-// NOTE(_nil): svn will always fail because it is trying to get
-// the revision history of a file named "release" instead of
-// looking for a commit with a release tag
-func (v *vcs) updateRepo(dst string) os.Error {
- if err := quietRun(dst, nil, v.cmd, v.log, v.logLimitFlag, v.logReleaseFlag); err == nil {
- if err := run(dst, nil, v.cmd, v.checkout, v.updateReleaseFlag); err != nil {
- return err
- }
- } else if err := run(dst, nil, v.cmd, v.update); err != nil {
- return err
- }
- return nil
-}
-
-// checkoutRepo checks out repo into dst using vcs.
-// It tries to check out (or update, if the dst already
-// exists and -u was specified on the command line)
-// the repository at tag/branch "release". If there is no
-// such tag or branch, it falls back to the repository tip.
-func (vcs *vcs) checkoutRepo(srcDir, pkgprefix, repo string) (installed bool, err os.Error) {
- dst := filepath.Join(srcDir, filepath.FromSlash(pkgprefix))
- dir, err := os.Stat(filepath.Join(dst, vcs.metadir))
- if err == nil && !dir.IsDirectory() {
- err = os.NewError("not a directory: " + dst)
- return
- }
- if err != nil {
- parent, _ := filepath.Split(dst)
- if err = os.MkdirAll(parent, 0777); err != nil {
- return
- }
- if err = run(string(filepath.Separator), nil, vcs.cmd, vcs.clone, repo, dst); err != nil {
- return
- }
- if err = vcs.updateRepo(dst); err != nil {
- return
- }
- installed = true
- } 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 vcs.pullForceFlag != "" {
- if err = run(dst, nil, vcs.cmd, vcs.pull, vcs.pullForceFlag); err != nil {
- return
- }
- } else if err = run(dst, nil, vcs.cmd, vcs.pull); err != nil {
- return
- }
- }
- // Update to release or latest revision
- if err = vcs.updateRepo(dst); err != nil {
- return
- }
- }
- return
-}