Commit fd1c1b96 authored by Russ Cox's avatar Russ Cox

cmd/go: work toward build script

The commands in the standard tree are now named
by the pseudo-import paths cmd/gofmt etc.
This avoids ambiguity between cmd/go's directory
and go/token's parent directory.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5503050
parent 87201057
......@@ -6,6 +6,8 @@
// to update builtin.c.boot. This is not done automatically
// to avoid depending on having a working compiler binary.
// +build ignore
package PACKAGE
// emitted by compiler, not referred to by go programs
......
......@@ -6,6 +6,8 @@
// to update builtin.c.boot. This is not done automatically
// to avoid depending on having a working compiler binary.
// +build ignore
package PACKAGE
type Pointer uintptr // not really; filled in by compiler
......
This diff is collapsed.
......@@ -14,7 +14,7 @@ var cmdList = &Command{
UsageLine: "list [-f format] [-json] [importpath...]",
Short: "list packages",
Long: `
List lists the packages named by the import paths.
List lists the packages named by the import paths, one per line.
The default output shows the package name and file system location:
......@@ -24,7 +24,7 @@ The default output shows the package name and file system location:
The -f flag specifies an alternate format for the list,
using the syntax of package template. The default output
is equivalent to -f '{{.Name}} {{.Dir}}'. The struct
is equivalent to -f '{{.ImportPath}}'. The struct
being passed to the template is:
type Package struct {
......@@ -57,7 +57,7 @@ func init() {
cmdList.Run = runList // break init cycle
}
var listFmt = cmdList.Flag.String("f", "{{.Name}} {{.Dir}}", "")
var listFmt = cmdList.Flag.String("f", "{{.ImportPath}}", "")
var listJson = cmdList.Flag.Bool("json", false, "")
var nl = []byte{'\n'}
......
......@@ -237,8 +237,38 @@ func run(cmdline ...string) {
// allPackages returns all the packages that can be found
// under the $GOPATH directories and $GOROOT.
func allPackages() []string {
have := make(map[string]bool)
have := map[string]bool{
"builtin": true, // ignore pseudo-package that exists only for documentation
}
var pkgs []string
// Commands
goroot := build.Path[0].Path
cmd := filepath.Join(goroot, "src/cmd") + string(filepath.Separator)
filepath.Walk(cmd, func(path string, fi os.FileInfo, err error) error {
if err != nil || !fi.IsDir() {
return nil
}
name := path[len(cmd):]
// Commands are all in cmd/, not in subdirectories.
if strings.Contains(name, string(filepath.Separator)) {
return filepath.SkipDir
}
_, err = build.ScanDir(path)
if err != nil {
return nil
}
// We use, e.g., cmd/gofmt as the pseudo import path for gofmt.
name = "cmd/" + name
if !have[name] {
have[name] = true
pkgs = append(pkgs, name)
}
return nil
})
for _, t := range build.Path {
src := t.SrcDir() + string(filepath.Separator)
filepath.Walk(src, func(path string, fi os.FileInfo, err error) error {
......@@ -256,21 +286,19 @@ func allPackages() []string {
return nil
}
name := path[len(src):]
if have[name] {
return nil
if !have[name] {
pkgs = append(pkgs, name)
have[name] = true
}
pkgs = append(pkgs, name)
have[name] = true
// Avoid go/build test data.
// TODO: Move it into a testdata directory.
if path == filepath.Join(build.Path[0].SrcDir(), "go/build") {
return filepath.SkipDir
}
return nil
})
// TODO: Commands.
}
return pkgs
}
......@@ -70,13 +70,15 @@ func loadPackage(arg string) (*Package, error) {
// Find basic information about package path.
t, importPath, err := build.FindTree(arg)
dir := ""
// Maybe it is a standard command.
if err != nil && !filepath.IsAbs(arg) && !strings.HasPrefix(arg, ".") {
if err != nil && !filepath.IsAbs(arg) && strings.HasPrefix(arg, "cmd/") {
goroot := build.Path[0]
p := filepath.Join(goroot.Path, "src/cmd", arg)
p := filepath.Join(goroot.Path, "src", arg)
if st, err1 := os.Stat(p); err1 == nil && st.IsDir() {
t = goroot
importPath = "../cmd/" + arg
importPath = arg
dir = p
err = nil
}
}
......@@ -84,7 +86,9 @@ func loadPackage(arg string) (*Package, error) {
return nil, err
}
dir := filepath.Join(t.SrcDir(), filepath.FromSlash(importPath))
if dir == "" {
dir = filepath.Join(t.SrcDir(), filepath.FromSlash(importPath))
}
// Maybe we know the package by its directory.
if p := packageCache[dir]; p != nil {
......@@ -140,6 +144,13 @@ func scanPackage(ctxt *build.Context, t *build.Tree, arg, importPath, dir string
}
sort.Strings(p.gofiles)
// Packages that use cgo import runtime/cgo implicitly,
// except runtime/cgo itself.
if len(info.CgoFiles) > 0 && (!p.Standard || p.ImportPath != "runtime/cgo") {
p.Imports = append(p.Imports, "runtime/cgo")
sort.Strings(p.Imports)
}
// Record package under both import path and full directory name.
packageCache[dir] = p
packageCache[importPath] = p
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment