Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2010 The Go Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style | |
3 // license that can be found in the LICENSE file. | |
4 | |
5 // Download remote packages. | |
6 | |
7 package main | |
8 | |
9 import ( | |
10 "http" | |
11 "os" | |
12 "regexp" | |
13 "strings" | |
14 ) | |
15 | |
16 const dashboardURL = "http://godashboard.appspot.com/package" | |
17 | |
18 // maybeReportToDashboard reports path to dashboard unless | |
19 // -dashboard=false is on command line. It ignores errors. | |
20 func maybeReportToDashboard(path string) { | |
21 // if -dashboard=false was on command line, do nothing | |
22 if !*reportToDashboard { | |
23 return | |
24 } | |
25 | |
26 // otherwise lob url to dashboard | |
27 r, _ := http.Post(dashboardURL, "application/x-www-form-urlencoded", str ings.NewReader("path="+path)) | |
28 if r != nil && r.Body != nil { | |
29 r.Body.Close() | |
30 } | |
31 } | |
32 | |
33 var googlecode = regexp.MustCompile(`^([a-z0-9\-]+\.googlecode\.com/(svn|hg))(/[ a-z0-9A-Z_.\-/]*)?$`) | |
34 var github = regexp.MustCompile(`^(github\.com/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+ \.git)(/[a-z0-9A-Z_.\-/]*)?$`) | |
35 var bitbucket = regexp.MustCompile(`^(bitbucket\.org/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z _.\-]+)(/[a-z0-9A-Z_.\-/]*)?$`) | |
36 | |
37 // download checks out or updates pkg from the remote server. | |
38 func download(pkg string) (string, os.Error) { | |
39 if strings.Index(pkg, "..") >= 0 { | |
40 return "", os.ErrorString("invalid path (contains ..)") | |
41 } | |
42 if m := bitbucket.MatchStrings(pkg); m != nil { | |
43 if err := vcsCheckout(&hg, root+m[1], "http://"+m[1], m[1]); err != nil { | |
44 return "", err | |
45 } | |
46 return root + pkg, nil | |
47 } | |
48 if m := googlecode.MatchStrings(pkg); m != nil { | |
49 var v *vcs | |
50 switch m[2] { | |
51 case "hg": | |
52 v = &hg | |
53 case "svn": | |
54 v = &svn | |
55 default: | |
56 // regexp only allows hg, svn to get through | |
57 panic("missing case in download") | |
r
2010/03/03 04:21:55
put pkg in the message
| |
58 } | |
59 if err := vcsCheckout(v, root+m[1], "http://"+m[1], m[1]); err ! = nil { | |
60 return "", err | |
61 } | |
62 return root + pkg, nil | |
63 } | |
64 if m := github.MatchStrings(pkg); m != nil { | |
65 if err := vcsCheckout(&git, root+m[1], "http://"+m[1], m[1]); er r != nil { | |
66 return "", err | |
67 } | |
68 return root + pkg, nil | |
69 } | |
70 return "", os.ErrorString("unknown repository: " + pkg) | |
71 } | |
72 | |
73 type vcs struct { | |
r
2010/03/03 04:21:55
if you want patches you should put comments on the
| |
74 cmd string | |
75 metadir string | |
76 clone string | |
77 update string | |
78 pull string | |
79 log string | |
80 logLimitFlag string | |
81 logReleaseFlag string | |
82 } | |
83 | |
84 var hg = vcs{ | |
85 cmd: "hg", | |
86 metadir: ".hg", | |
87 clone: "clone", | |
88 update: "update", | |
89 pull: "pull", | |
90 log: "log", | |
91 logLimitFlag: "-l1", | |
92 logReleaseFlag: "-rrelease", | |
93 } | |
94 | |
95 var git = vcs{ | |
96 cmd: "git", | |
97 metadir: ".git", | |
98 clone: "clone", | |
99 update: "checkout", | |
100 pull: "fetch", | |
101 log: "log", | |
102 logLimitFlag: "-n1", | |
103 logReleaseFlag: "release", | |
104 } | |
105 | |
106 var svn = vcs{ | |
107 cmd: "svn", | |
108 metadir: ".svn", | |
109 clone: "checkout", | |
110 update: "update", | |
111 pull: "", | |
112 log: "log", | |
113 logLimitFlag: "-l1", | |
114 logReleaseFlag: "release", | |
115 } | |
116 | |
117 // vcsCheckout checks out repo into dst using vcs. | |
118 // It tries to check out (or update, if the dst already | |
119 // exists and -u was specified on the command line) | |
120 // the repository at tag/branch "release". If there is no | |
121 // such tag or branch, it falls back to the repository tip. | |
122 func vcsCheckout(vcs *vcs, dst, repo, dashpath string) os.Error { | |
123 dir, err := os.Stat(dst + "/" + vcs.metadir) | |
124 if err == nil && !dir.IsDirectory() { | |
125 return os.ErrorString("not a directory: " + dst) | |
126 } | |
127 if err != nil { | |
128 if err := os.MkdirAll(dst, 0777); err != nil { | |
129 return err | |
130 } | |
131 if err := run("/", nil, vcs.cmd, vcs.clone, repo, dst); err != n il { | |
132 return err | |
133 } | |
134 quietRun(dst, nil, vcs.cmd, vcs.update, "release") | |
135 | |
136 // success on first installation - report | |
137 maybeReportToDashboard(dashpath) | |
138 } else if *update { | |
139 if vcs.pull != "" { | |
140 if err := run(dst, nil, vcs.cmd, vcs.pull); err != nil { | |
141 return err | |
142 } | |
143 } | |
144 // check for release with hg log -l 1 -r release | |
145 // if success, hg update release | |
146 // else hg update | |
147 if err := quietRun(dst, nil, vcs.cmd, vcs.log, vcs.logLimitFlag, vcs.logReleaseFlag); err == nil { | |
148 if err := run(dst, nil, vcs.cmd, vcs.update, "release"); err != nil { | |
149 return err | |
150 } | |
151 } else { | |
152 if err := run(dst, nil, vcs.cmd, vcs.update); err != nil { | |
153 return err | |
154 } | |
155 } | |
156 } | |
157 return nil | |
158 } | |
OLD | NEW |