Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(6)

Delta Between Two Patch Sets: src/cmd/goinstall/download.go

Issue 5307066: code review 5307066: non-pkg: gofix -r error (Closed)
Left Patch Set: Created 13 years, 4 months ago
Right Patch Set: diff -r 586479483dd6 https://go.googlecode.com/hg/ Created 13 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/cmd/gofmt/gofmt.go ('k') | src/cmd/goinstall/main.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2010 The Go Authors. All rights reserved. 1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // Download remote packages. 5 // Download remote packages.
6 6
7 package main 7 package main
8 8
9 import ( 9 import (
10 "bytes" 10 "bytes"
11 "errors"
11 "exec" 12 "exec"
12 "fmt" 13 "fmt"
13 "http" 14 "http"
14 "json" 15 "json"
15 "os" 16 "os"
16 "path/filepath" 17 "path/filepath"
17 "regexp" 18 "regexp"
18 "runtime" 19 "runtime"
19 "strconv" 20 "strconv"
20 "strings" 21 "strings"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 tagListRe: regexp.MustCompile("([^ ]+)[^\n]+\n"), 114 tagListRe: regexp.MustCompile("([^ ]+)[^\n]+\n"),
114 check: "info", 115 check: "info",
115 protocols: []string{"https", "http", "bzr"}, 116 protocols: []string{"https", "http", "bzr"},
116 suffix: ".bzr", 117 suffix: ".bzr",
117 } 118 }
118 119
119 var vcsList = []*vcs{&git, &hg, &bzr, &svn} 120 var vcsList = []*vcs{&git, &hg, &bzr, &svn}
120 121
121 type host struct { 122 type host struct {
122 pattern *regexp.Regexp 123 pattern *regexp.Regexp
123 » getVcs func(repo, path string) (*vcsMatch, os.Error) 124 » getVcs func(repo, path string) (*vcsMatch, error)
124 } 125 }
125 126
126 var knownHosts = []host{ 127 var knownHosts = []host{
127 { 128 {
128 regexp.MustCompile(`^([a-z0-9\-]+\.googlecode\.com/(svn|git|hg)) (/[a-z0-9A-Z_.\-/]*)?$`), 129 regexp.MustCompile(`^([a-z0-9\-]+\.googlecode\.com/(svn|git|hg)) (/[a-z0-9A-Z_.\-/]*)?$`),
129 googleVcs, 130 googleVcs,
130 }, 131 },
131 { 132 {
132 regexp.MustCompile(`^(github\.com/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\ -]+)(/[a-z0-9A-Z_.\-/]*)?$`), 133 regexp.MustCompile(`^(github\.com/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\ -]+)(/[a-z0-9A-Z_.\-/]*)?$`),
133 githubVcs, 134 githubVcs,
134 }, 135 },
135 { 136 {
136 regexp.MustCompile(`^(bitbucket\.org/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z _.\-]+)(/[a-z0-9A-Z_.\-/]*)?$`), 137 regexp.MustCompile(`^(bitbucket\.org/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z _.\-]+)(/[a-z0-9A-Z_.\-/]*)?$`),
137 bitbucketVcs, 138 bitbucketVcs,
138 }, 139 },
139 { 140 {
140 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_.\-/]+)?$`), 141 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_.\-/]+)?$`),
141 launchpadVcs, 142 launchpadVcs,
142 }, 143 },
143 } 144 }
144 145
145 type vcsMatch struct { 146 type vcsMatch struct {
146 *vcs 147 *vcs
147 prefix, repo string 148 prefix, repo string
148 } 149 }
149 150
150 func googleVcs(repo, path string) (*vcsMatch, os.Error) { 151 func googleVcs(repo, path string) (*vcsMatch, error) {
151 parts := strings.SplitN(repo, "/", 2) 152 parts := strings.SplitN(repo, "/", 2)
152 url := "https://" + repo 153 url := "https://" + repo
153 switch parts[1] { 154 switch parts[1] {
154 case "svn": 155 case "svn":
155 return &vcsMatch{&svn, repo, url}, nil 156 return &vcsMatch{&svn, repo, url}, nil
156 case "git": 157 case "git":
157 return &vcsMatch{&git, repo, url}, nil 158 return &vcsMatch{&git, repo, url}, nil
158 case "hg": 159 case "hg":
159 return &vcsMatch{&hg, repo, url}, nil 160 return &vcsMatch{&hg, repo, url}, nil
160 } 161 }
161 » return nil, os.NewError("unsupported googlecode vcs: " + parts[1]) 162 » return nil, errors.New("unsupported googlecode vcs: " + parts[1])
162 } 163 }
163 164
164 func githubVcs(repo, path string) (*vcsMatch, os.Error) { 165 func githubVcs(repo, path string) (*vcsMatch, error) {
165 if strings.HasSuffix(repo, ".git") { 166 if strings.HasSuffix(repo, ".git") {
166 » » return nil, os.NewError("path must not include .git suffix") 167 » » return nil, errors.New("path must not include .git suffix")
167 } 168 }
168 return &vcsMatch{&git, repo, "http://" + repo + ".git"}, nil 169 return &vcsMatch{&git, repo, "http://" + repo + ".git"}, nil
169 } 170 }
170 171
171 func bitbucketVcs(repo, path string) (*vcsMatch, os.Error) { 172 func bitbucketVcs(repo, path string) (*vcsMatch, error) {
172 const bitbucketApiUrl = "https://api.bitbucket.org/1.0/repositories/" 173 const bitbucketApiUrl = "https://api.bitbucket.org/1.0/repositories/"
173 174
174 if strings.HasSuffix(repo, ".git") { 175 if strings.HasSuffix(repo, ".git") {
175 » » return nil, os.NewError("path must not include .git suffix") 176 » » return nil, errors.New("path must not include .git suffix")
176 } 177 }
177 178
178 parts := strings.SplitN(repo, "/", 2) 179 parts := strings.SplitN(repo, "/", 2)
179 180
180 // Ask the bitbucket API what kind of repository this is. 181 // Ask the bitbucket API what kind of repository this is.
181 r, err := http.Get(bitbucketApiUrl + parts[1]) 182 r, err := http.Get(bitbucketApiUrl + parts[1])
182 if err != nil { 183 if err != nil {
183 return nil, fmt.Errorf("error querying BitBucket API: %v", err) 184 return nil, fmt.Errorf("error querying BitBucket API: %v", err)
184 } 185 }
185 defer r.Body.Close() 186 defer r.Body.Close()
(...skipping 12 matching lines...) Expand all
198 } 199 }
199 200
200 // Now we should be able to construct a vcsMatch structure 201 // Now we should be able to construct a vcsMatch structure
201 switch response.Vcs { 202 switch response.Vcs {
202 case "git": 203 case "git":
203 return &vcsMatch{&git, repo, "http://" + repo + ".git"}, nil 204 return &vcsMatch{&git, repo, "http://" + repo + ".git"}, nil
204 case "hg": 205 case "hg":
205 return &vcsMatch{&hg, repo, "http://" + repo}, nil 206 return &vcsMatch{&hg, repo, "http://" + repo}, nil
206 } 207 }
207 208
208 » return nil, os.NewError("unsupported bitbucket vcs: " + response.Vcs) 209 » return nil, errors.New("unsupported bitbucket vcs: " + response.Vcs)
209 } 210 }
210 211
211 func launchpadVcs(repo, path string) (*vcsMatch, os.Error) { 212 func launchpadVcs(repo, path string) (*vcsMatch, error) {
212 return &vcsMatch{&bzr, repo, "https://" + repo}, nil 213 return &vcsMatch{&bzr, repo, "https://" + repo}, nil
213 } 214 }
214 215
215 // findPublicRepo checks whether pkg is located at one of 216 // findPublicRepo checks whether pkg is located at one of
216 // the supported code hosting sites and, if so, returns a match. 217 // the supported code hosting sites and, if so, returns a match.
217 func findPublicRepo(pkg string) (*vcsMatch, os.Error) { 218 func findPublicRepo(pkg string) (*vcsMatch, error) {
218 for _, host := range knownHosts { 219 for _, host := range knownHosts {
219 if hm := host.pattern.FindStringSubmatch(pkg); hm != nil { 220 if hm := host.pattern.FindStringSubmatch(pkg); hm != nil {
220 return host.getVcs(hm[1], hm[2]) 221 return host.getVcs(hm[1], hm[2])
221 } 222 }
222 } 223 }
223 return nil, nil 224 return nil, nil
224 } 225 }
225 226
226 // findAnyRepo looks for a vcs suffix in pkg (.git, etc) and returns a match. 227 // findAnyRepo looks for a vcs suffix in pkg (.git, etc) and returns a match.
227 func findAnyRepo(pkg string) (*vcsMatch, os.Error) { 228 func findAnyRepo(pkg string) (*vcsMatch, error) {
228 for _, v := range vcsList { 229 for _, v := range vcsList {
229 i := strings.Index(pkg+"/", v.suffix+"/") 230 i := strings.Index(pkg+"/", v.suffix+"/")
230 if i < 0 { 231 if i < 0 {
231 continue 232 continue
232 } 233 }
233 if !strings.Contains(pkg[:i], "/") { 234 if !strings.Contains(pkg[:i], "/") {
234 continue // don't match vcs suffix in the host name 235 continue // don't match vcs suffix in the host name
235 } 236 }
236 if m := v.find(pkg[:i]); m != nil { 237 if m := v.find(pkg[:i]); m != nil {
237 return m, nil 238 return m, nil
(...skipping 27 matching lines...) Expand all
265 return false 266 return false
266 } 267 }
267 parts = strings.Split(parts[0], ".") 268 parts = strings.Split(parts[0], ".")
268 if len(parts) < 2 || len(parts[len(parts)-1]) < 2 { 269 if len(parts) < 2 || len(parts[len(parts)-1]) < 2 {
269 return false 270 return false
270 } 271 }
271 return true 272 return true
272 } 273 }
273 274
274 // download checks out or updates pkg from the remote server. 275 // download checks out or updates pkg from the remote server.
275 func download(pkg, srcDir string) (public bool, err os.Error) { 276 func download(pkg, srcDir string) (public bool, err error) {
276 if strings.Contains(pkg, "..") { 277 if strings.Contains(pkg, "..") {
277 » » err = os.NewError("invalid path (contains ..)") 278 » » err = errors.New("invalid path (contains ..)")
278 return 279 return
279 } 280 }
280 m, err := findPublicRepo(pkg) 281 m, err := findPublicRepo(pkg)
281 if err != nil { 282 if err != nil {
282 return 283 return
283 } 284 }
284 if m != nil { 285 if m != nil {
285 public = true 286 public = true
286 } else { 287 } else {
287 m, err = findAnyRepo(pkg) 288 m, err = findAnyRepo(pkg)
288 if err != nil { 289 if err != nil {
289 return 290 return
290 } 291 }
291 } 292 }
292 if m == nil { 293 if m == nil {
293 » » err = os.NewError("cannot download: " + pkg) 294 » » err = errors.New("cannot download: " + pkg)
294 return 295 return
295 } 296 }
296 err = m.checkoutRepo(srcDir, m.prefix, m.repo) 297 err = m.checkoutRepo(srcDir, m.prefix, m.repo)
297 return 298 return
298 } 299 }
299 300
300 // updateRepo gets a list of tags in the repository and 301 // updateRepo gets a list of tags in the repository and
301 // checks out the tag closest to the current runtime.Version. 302 // checks out the tag closest to the current runtime.Version.
302 // If no matching tag is found, it just updates to tip. 303 // If no matching tag is found, it just updates to tip.
303 func (v *vcs) updateRepo(dst string) os.Error { 304 func (v *vcs) updateRepo(dst string) error {
304 if v.tagList == "" || v.tagListRe == nil { 305 if v.tagList == "" || v.tagListRe == nil {
305 // TODO(adg): fix for svn 306 // TODO(adg): fix for svn
306 return run(dst, nil, v.cmd, v.update) 307 return run(dst, nil, v.cmd, v.update)
307 } 308 }
308 309
309 // Get tag list. 310 // Get tag list.
310 stderr := new(bytes.Buffer) 311 stderr := new(bytes.Buffer)
311 cmd := exec.Command(v.cmd, v.tagList) 312 cmd := exec.Command(v.cmd, v.tagList)
312 cmd.Dir = dst 313 cmd.Dir = dst
313 cmd.Stderr = stderr 314 cmd.Stderr = stderr
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 } 376 }
376 } 377 }
377 return match 378 return match
378 } 379 }
379 380
380 // checkoutRepo checks out repo into dst using vcs. 381 // checkoutRepo checks out repo into dst using vcs.
381 // It tries to check out (or update, if the dst already 382 // It tries to check out (or update, if the dst already
382 // exists and -u was specified on the command line) 383 // exists and -u was specified on the command line)
383 // the repository at tag/branch "release". If there is no 384 // the repository at tag/branch "release". If there is no
384 // such tag or branch, it falls back to the repository tip. 385 // such tag or branch, it falls back to the repository tip.
385 func (vcs *vcs) checkoutRepo(srcDir, pkgprefix, repo string) os.Error { 386 func (vcs *vcs) checkoutRepo(srcDir, pkgprefix, repo string) error {
386 dst := filepath.Join(srcDir, filepath.FromSlash(pkgprefix)) 387 dst := filepath.Join(srcDir, filepath.FromSlash(pkgprefix))
387 dir, err := os.Stat(filepath.Join(dst, vcs.metadir)) 388 dir, err := os.Stat(filepath.Join(dst, vcs.metadir))
388 if err == nil && !dir.IsDirectory() { 389 if err == nil && !dir.IsDirectory() {
389 » » return os.NewError("not a directory: " + dst) 390 » » return errors.New("not a directory: " + dst)
390 } 391 }
391 if err != nil { 392 if err != nil {
392 parent, _ := filepath.Split(dst) 393 parent, _ := filepath.Split(dst)
393 if err = os.MkdirAll(parent, 0777); err != nil { 394 if err = os.MkdirAll(parent, 0777); err != nil {
394 return err 395 return err
395 } 396 }
396 if err = run(string(filepath.Separator), nil, vcs.cmd, vcs.clone , repo, dst); err != nil { 397 if err = run(string(filepath.Separator), nil, vcs.cmd, vcs.clone , repo, dst); err != nil {
397 return err 398 return err
398 } 399 }
399 return vcs.updateRepo(dst) 400 return vcs.updateRepo(dst)
400 } 401 }
401 if *update { 402 if *update {
402 // Retrieve new revisions from the remote branch, if the VCS 403 // Retrieve new revisions from the remote branch, if the VCS
403 // supports this operation independently (e.g. svn doesn't) 404 // supports this operation independently (e.g. svn doesn't)
404 if vcs.pull != "" { 405 if vcs.pull != "" {
405 if vcs.pullForceFlag != "" { 406 if vcs.pullForceFlag != "" {
406 if err = run(dst, nil, vcs.cmd, vcs.pull, vcs.pu llForceFlag); err != nil { 407 if err = run(dst, nil, vcs.cmd, vcs.pull, vcs.pu llForceFlag); err != nil {
407 return err 408 return err
408 } 409 }
409 } else if err = run(dst, nil, vcs.cmd, vcs.pull); err != nil { 410 } else if err = run(dst, nil, vcs.cmd, vcs.pull); err != nil {
410 return err 411 return err
411 } 412 }
412 } 413 }
413 // Update to release or latest revision 414 // Update to release or latest revision
414 return vcs.updateRepo(dst) 415 return vcs.updateRepo(dst)
415 } 416 }
416 return nil 417 return nil
417 } 418 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b