LEFT | RIGHT |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 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 package main | 5 package main |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "errors" | 9 "errors" |
10 "fmt" | 10 "fmt" |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 // not to use the package cache. | 154 // not to use the package cache. |
155 func reloadPackage(arg string, stk *importStack) *Package { | 155 func reloadPackage(arg string, stk *importStack) *Package { |
156 p := packageCache[arg] | 156 p := packageCache[arg] |
157 if p != nil { | 157 if p != nil { |
158 delete(packageCache, p.Dir) | 158 delete(packageCache, p.Dir) |
159 delete(packageCache, p.ImportPath) | 159 delete(packageCache, p.ImportPath) |
160 } | 160 } |
161 return loadPackage(arg, stk) | 161 return loadPackage(arg, stk) |
162 } | 162 } |
163 | 163 |
164 // loadImport scans directory named by arg, which must be an import path, | 164 // loadImport scans the directory named by path, which must be an import path, |
165 // but possibly a local import path (an absolute file system path or one beginni
ng | 165 // but possibly a local import path (an absolute file system path or one beginni
ng |
166 // with ./ or ../). A local relative path is interpreted relative to srcDir. | 166 // with ./ or ../). A local relative path is interpreted relative to srcDir. |
167 // It returns a *Package describing the package found in that directory. | 167 // It returns a *Package describing the package found in that directory. |
168 func loadImport(path string, srcDir string, stk *importStack, importPos []token.
Position) *Package { | 168 func loadImport(path string, srcDir string, stk *importStack, importPos []token.
Position) *Package { |
169 stk.push(path) | 169 stk.push(path) |
170 defer stk.pop() | 170 defer stk.pop() |
171 | 171 |
172 // Determine canonical identifier for this package. | 172 // Determine canonical identifier for this package. |
173 // For a local path (./ or ../) the identifier is the full | 173 // For a local path (./ or ../) the identifier is the full |
174 // directory name. Otherwise it is the import path. | 174 // directory name. Otherwise it is the import path. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 if len(p.CgoFiles) > 0 && (!p.Standard || p.ImportPath != "runtime/cgo")
{ | 304 if len(p.CgoFiles) > 0 && (!p.Standard || p.ImportPath != "runtime/cgo")
{ |
305 importPaths = append(importPaths, "runtime/cgo") | 305 importPaths = append(importPaths, "runtime/cgo") |
306 } | 306 } |
307 // Everything depends on runtime, except runtime and unsafe. | 307 // Everything depends on runtime, except runtime and unsafe. |
308 if !p.Standard || (p.ImportPath != "runtime" && p.ImportPath != "unsafe"
) { | 308 if !p.Standard || (p.ImportPath != "runtime" && p.ImportPath != "unsafe"
) { |
309 importPaths = append(importPaths, "runtime") | 309 importPaths = append(importPaths, "runtime") |
310 } | 310 } |
311 | 311 |
312 // Build list of full paths to all Go files in the package, | 312 // Build list of full paths to all Go files in the package, |
313 // for use by commands like go fmt. | 313 // for use by commands like go fmt. |
314 » for _, f := range p.GoFiles { | 314 » p.gofiles = stringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFi
les) |
315 » » p.gofiles = append(p.gofiles, filepath.Join(p.Dir, f)) | 315 » for i := range p.gofiles { |
316 » } | 316 » » p.gofiles[i] = filepath.Join(p.Dir, p.gofiles[i]) |
317 » for _, f := range p.CgoFiles { | |
318 » » p.gofiles = append(p.gofiles, filepath.Join(p.Dir, f)) | |
319 » } | |
320 » for _, f := range p.TestGoFiles { | |
321 » » p.gofiles = append(p.gofiles, filepath.Join(p.Dir, f)) | |
322 » } | |
323 » for _, f := range p.XTestGoFiles { | |
324 » » p.gofiles = append(p.gofiles, filepath.Join(p.Dir, f)) | |
325 } | 317 } |
326 sort.Strings(p.gofiles) | 318 sort.Strings(p.gofiles) |
327 | 319 |
328 // Build list of imported packages and full dependency list. | 320 // Build list of imported packages and full dependency list. |
329 imports := make([]*Package, 0, len(p.Imports)) | 321 imports := make([]*Package, 0, len(p.Imports)) |
330 deps := make(map[string]bool) | 322 deps := make(map[string]bool) |
331 for i, path := range importPaths { | 323 for i, path := range importPaths { |
332 if path == "C" { | 324 if path == "C" { |
333 continue | 325 continue |
334 } | 326 } |
335 p1 := loadImport(path, p.Dir, stk, p.build.ImportPos[path]) | 327 p1 := loadImport(path, p.Dir, stk, p.build.ImportPos[path]) |
336 if p1.local { | 328 if p1.local { |
337 path = p1.Dir | 329 path = p1.Dir |
338 importPaths[i] = path | 330 importPaths[i] = path |
339 } | |
340 if build.IsLocalImport(path) { | |
341 println("LOCAL?", p.Dir, p1, p1.local, p1.Dir, p1.Import
Path, path) | |
342 } | 331 } |
343 deps[path] = true | 332 deps[path] = true |
344 imports = append(imports, p1) | 333 imports = append(imports, p1) |
345 for _, dep := range p1.Deps { | 334 for _, dep := range p1.Deps { |
346 deps[dep] = true | 335 deps[dep] = true |
347 } | 336 } |
348 if p1.Incomplete { | 337 if p1.Incomplete { |
349 p.Incomplete = true | 338 p.Incomplete = true |
350 } | 339 } |
351 } | 340 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 topRoot := map[string]bool{} | 393 topRoot := map[string]bool{} |
405 for _, p := range pkgs { | 394 for _, p := range pkgs { |
406 topRoot[p.Root] = true | 395 topRoot[p.Root] = true |
407 } | 396 } |
408 | 397 |
409 for _, p := range packageList(pkgs) { | 398 for _, p := range packageList(pkgs) { |
410 p.Stale = isStale(p, topRoot) | 399 p.Stale = isStale(p, topRoot) |
411 } | 400 } |
412 } | 401 } |
413 | 402 |
| 403 // isStale reports whether package p needs to be rebuilt. |
414 func isStale(p *Package, topRoot map[string]bool) bool { | 404 func isStale(p *Package, topRoot map[string]bool) bool { |
415 if p.Standard && p.ImportPath == "unsafe" { | 405 if p.Standard && p.ImportPath == "unsafe" { |
416 » » // fake package | 406 » » // fake, builtin package |
417 return false | 407 return false |
418 } | 408 } |
419 if p.Error != nil { | 409 if p.Error != nil { |
420 return true | 410 return true |
421 } | 411 } |
422 | 412 |
423 // A package without Go sources means we only found | 413 // A package without Go sources means we only found |
424 // the installed .a file. Since we don't know how to rebuild | 414 // the installed .a file. Since we don't know how to rebuild |
425 // it, it can't be stale, even if -a is set. This enables binary-only | 415 // it, it can't be stale, even if -a is set. This enables binary-only |
426 // distributions of Go packages, although such binaries are | 416 // distributions of Go packages, although such binaries are |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 // package named on the command-line, assume it is up-to-date | 465 // package named on the command-line, assume it is up-to-date |
476 // no matter what the modification times on the source files indicate. | 466 // no matter what the modification times on the source files indicate. |
477 // This avoids rebuilding $GOROOT packages when people are | 467 // This avoids rebuilding $GOROOT packages when people are |
478 // working outside the Go root, and it effectively makes each tree | 468 // working outside the Go root, and it effectively makes each tree |
479 // listed in $GOPATH a separate compilation world. | 469 // listed in $GOPATH a separate compilation world. |
480 // See issue 3149. | 470 // See issue 3149. |
481 if p.Root != "" && !topRoot[p.Root] { | 471 if p.Root != "" && !topRoot[p.Root] { |
482 return false | 472 return false |
483 } | 473 } |
484 | 474 |
485 » srcss := [][]string{ | 475 » srcs := stringList(p.GoFiles, p.CFiles, p.HFiles, p.SFiles, p.CgoFiles) |
486 » » p.GoFiles, | 476 » for _, src := range srcs { |
487 » » p.CFiles, | 477 » » if olderThan(filepath.Join(p.Dir, src)) { |
488 » » p.HFiles, | 478 » » » return true |
489 » » p.SFiles, | |
490 » » p.CgoFiles, | |
491 » } | |
492 | |
493 » for _, srcs := range srcss { | |
494 » » for _, src := range srcs { | |
495 » » » if olderThan(filepath.Join(p.Dir, src)) { | |
496 » » » » return true | |
497 » » » } | |
498 } | 479 } |
499 } | 480 } |
500 | 481 |
501 return false | 482 return false |
502 } | 483 } |
503 | 484 |
504 var cwd, _ = os.Getwd() | 485 var cwd, _ = os.Getwd() |
505 | 486 |
506 var cmdCache = map[string]*Package{} | 487 var cmdCache = map[string]*Package{} |
507 | 488 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 root = filepath.Clean(root) | 624 root = filepath.Clean(root) |
644 if !strings.HasSuffix(root, sep) { | 625 if !strings.HasSuffix(root, sep) { |
645 root += sep | 626 root += sep |
646 } | 627 } |
647 dir = filepath.Clean(dir) | 628 dir = filepath.Clean(dir) |
648 if !strings.HasPrefix(dir, root) { | 629 if !strings.HasPrefix(dir, root) { |
649 return "", false | 630 return "", false |
650 } | 631 } |
651 return filepath.ToSlash(dir[len(root):]), true | 632 return filepath.ToSlash(dir[len(root):]), true |
652 } | 633 } |
LEFT | RIGHT |