import (
"bytes"
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"fmt"
"io"
"io/ioutil"
"strings"
)
-var cmdBug = &Command{
+var cmdBug = &base.Command{
Run: runBug,
UsageLine: "bug",
Short: "start a bug report",
cmdBug.Flag.BoolVar(&cfg.BuildV, "v", false, "")
}
-func runBug(cmd *Command, args []string) {
+func runBug(cmd *base.Command, args []string) {
var buf bytes.Buffer
buf.WriteString(bugHeader)
inspectGoVersion(&buf)
"time"
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"cmd/go/internal/str"
)
-var cmdBuild = &Command{
+var cmdBuild = &base.Command{
UsageLine: "build [-o output] [-i] [build flags] [packages]",
Short: "compile packages and dependencies",
Long: `
// addBuildFlags adds the flags common to the build, clean, get,
// install, list, run, and test commands.
-func addBuildFlags(cmd *Command) {
+func addBuildFlags(cmd *base.Command) {
cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "")
cmd.Flag.BoolVar(&cfg.BuildN, "n", false, "")
cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "")
cmd.Flag.BoolVar(&cfg.BuildWork, "work", false, "")
}
-func addBuildFlagsNX(cmd *Command) {
- cmd.Flag.BoolVar(&cfg.BuildN, "n", false, "")
- cmd.Flag.BoolVar(&cfg.BuildX, "x", false, "")
-}
-
func isSpaceByte(c byte) bool {
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
}
case "c-archive":
pkgsFilter = func(p []*Package) []*Package {
if len(p) != 1 || p[0].Name != "main" {
- fatalf("-buildmode=c-archive requires exactly one main package")
+ base.Fatalf("-buildmode=c-archive requires exactly one main package")
}
return p
}
codegenArg = "-shared"
case "darwin/amd64", "darwin/386":
default:
- fatalf("-buildmode=c-shared not supported on %s\n", platform)
+ base.Fatalf("-buildmode=c-shared not supported on %s\n", platform)
}
}
ldBuildmode = "c-shared"
ldBuildmode = "exe"
case "pie":
if gccgo {
- fatalf("-buildmode=pie not supported by gccgo")
+ base.Fatalf("-buildmode=pie not supported by gccgo")
} else {
switch platform {
case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
"android/amd64", "android/arm", "android/arm64", "android/386":
codegenArg = "-shared"
default:
- fatalf("-buildmode=pie not supported on %s\n", platform)
+ base.Fatalf("-buildmode=pie not supported on %s\n", platform)
}
}
ldBuildmode = "pie"
switch platform {
case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
default:
- fatalf("-buildmode=shared not supported on %s\n", platform)
+ base.Fatalf("-buildmode=shared not supported on %s\n", platform)
}
codegenArg = "-dynlink"
}
if cfg.BuildO != "" {
- fatalf("-buildmode=shared and -o not supported together")
+ base.Fatalf("-buildmode=shared and -o not supported together")
}
ldBuildmode = "shared"
case "plugin":
case "linux/amd64", "linux/arm", "linux/arm64", "linux/386",
"android/amd64", "android/arm", "android/arm64", "android/386":
default:
- fatalf("-buildmode=plugin not supported on %s\n", platform)
+ base.Fatalf("-buildmode=plugin not supported on %s\n", platform)
}
codegenArg = "-dynlink"
}
cfg.ExeSuffix = ".so"
ldBuildmode = "plugin"
default:
- fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
+ base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
}
if cfg.BuildLinkshared {
if gccgo {
case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
buildAsmflags = append(buildAsmflags, "-D=GOBUILDMODE_shared=1")
default:
- fatalf("-linkshared not supported on %s\n", platform)
+ base.Fatalf("-linkshared not supported on %s\n", platform)
}
codegenArg = "-dynlink"
// TODO(mwhudson): remove -w when that gets fixed in linker.
}
}
-func runBuild(cmd *Command, args []string) {
+func runBuild(cmd *base.Command, args []string) {
instrumentInit()
buildModeInit()
var b builder
if cfg.BuildO != "" {
if len(pkgs) > 1 {
- fatalf("go build: cannot use -o with multiple packages")
+ base.Fatalf("go build: cannot use -o with multiple packages")
} else if len(pkgs) == 0 {
- fatalf("no packages to build")
+ base.Fatalf("no packages to build")
}
p := pkgs[0]
p.target = cfg.BuildO
if cfg.BuildBuildmode == "shared" {
pkgs := pkgsFilter(packages(args))
if libName, err := libname(args, pkgs); err != nil {
- fatalf("%s", err.Error())
+ base.Fatalf("%s", err.Error())
} else {
a = b.libaction(libName, pkgs, modeBuild, depMode)
}
b.do(a)
}
-var cmdInstall = &Command{
+var cmdInstall = &base.Command{
UsageLine: "install [build flags] [packages]",
Short: "compile and install packages and dependencies",
Long: `
return "lib" + libname + ".so", nil
}
-func runInstall(cmd *Command, args []string) {
+func runInstall(cmd *base.Command, args []string) {
installPackages(args, false)
}
func installPackages(args []string, forGet bool) {
if gobin != "" && !filepath.IsAbs(gobin) {
- fatalf("cannot install, GOBIN must be an absolute path")
+ base.Fatalf("cannot install, GOBIN must be an absolute path")
}
instrumentInit()
if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
switch {
case p.gobinSubdir:
- errorf("go install: cannot install cross-compiled binaries when GOBIN is set")
+ base.Errorf("go install: cannot install cross-compiled binaries when GOBIN is set")
case p.cmdline:
- errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
+ base.Errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
case p.ConflictDir != "":
- errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
+ base.Errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
default:
- errorf("go install: no install location for directory %s outside GOPATH\n"+
+ base.Errorf("go install: no install location for directory %s outside GOPATH\n"+
"\tFor more details see: 'go help gopath'", p.Dir)
}
}
}
- exitIfErrors()
+ base.ExitIfErrors()
var b builder
b.init()
var a *action
if cfg.BuildBuildmode == "shared" {
if libName, err := libname(args, pkgs); err != nil {
- fatalf("%s", err.Error())
+ base.Fatalf("%s", err.Error())
} else {
a = b.libaction(libName, pkgs, modeInstall, modeInstall)
}
}
}
b.do(a)
- exitIfErrors()
+ base.ExitIfErrors()
// Success. If this command is 'go install' with no arguments
// and the current directory (the implicit argument) is a command,
} else {
b.work, err = ioutil.TempDir("", "go-build")
if err != nil {
- fatalf("%s", err)
+ base.Fatalf("%s", err)
}
if cfg.BuildX || cfg.BuildWork {
fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work)
}
if !cfg.BuildWork {
workdir := b.work
- atexit(func() { os.RemoveAll(workdir) })
+ base.AtExit(func() { os.RemoveAll(workdir) })
}
}
}
// TODO: Remove this restriction.
for _, f := range gofiles {
if !strings.HasSuffix(f, ".go") {
- fatalf("named files must be .go files")
+ base.Fatalf("named files must be .go files")
}
}
for _, file := range gofiles {
fi, err := os.Stat(file)
if err != nil {
- fatalf("%s", err)
+ base.Fatalf("%s", err)
}
if fi.IsDir() {
- fatalf("%s is a directory, should be a Go file", file)
+ base.Fatalf("%s is a directory, should be a Go file", file)
}
dir1, _ := filepath.Split(file)
if dir1 == "" {
if dir == "" {
dir = dir1
} else if dir != dir1 {
- fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
+ base.Fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
}
dirent = append(dirent, fi)
}
var err error
if dir == "" {
- dir = cwd
+ dir = base.Cwd
}
dir, err = filepath.Abs(dir)
if err != nil {
- fatalf("%s", err)
+ base.Fatalf("%s", err)
}
bp, err := ctxt.ImportDir(dir, 0)
} else {
pkglistbytes, err := readELFNote(shlibpath, "Go\x00\x00", 1)
if err != nil {
- fatalf("readELFNote failed: %v", err)
+ base.Fatalf("readELFNote failed: %v", err)
}
scanner := bufio.NewScanner(bytes.NewBuffer(pkglistbytes))
for scanner.Scan() {
var stk importStack
p1 := loadPackage("cmd/cgo", &stk)
if p1.Error != nil {
- fatalf("load cmd/cgo: %v", p1.Error)
+ base.Fatalf("load cmd/cgo: %v", p1.Error)
}
a.cgo = b.action(depMode, depMode, p1)
a.deps = append(a.deps, a.cgo)
a := &action{}
switch mode {
default:
- fatalf("unrecognized mode %v", mode)
+ base.Fatalf("unrecognized mode %v", mode)
case modeBuild:
a.f = (*builder).linkShared
var stk importStack
p := loadPackage("runtime/cgo", &stk)
if p.Error != nil {
- fatalf("load runtime/cgo: %v", p.Error)
+ base.Fatalf("load runtime/cgo: %v", p.Error)
}
computeStale(p)
// If runtime/cgo is in another shared library, then that's
var stk importStack
p := loadPackage("math", &stk)
if p.Error != nil {
- fatalf("load math: %v", p.Error)
+ base.Fatalf("load math: %v", p.Error)
}
computeStale(p)
// If math is in another shared library, then that's
if libdir == "" {
libdir = plibdir
} else if libdir != plibdir {
- fatalf("multiple roots %s & %s", libdir, plibdir)
+ base.Fatalf("multiple roots %s & %s", libdir, plibdir)
}
}
a.target = filepath.Join(libdir, libname)
if err != nil {
if err == errPrintedOutput {
- setExitStatus(2)
+ base.SetExitStatus(2)
} else if _, ok := err.(*build.NoGoError); ok && len(a.p.TestGoFiles) > 0 && b.testFilesOnlyOK {
// Ignore the "no buildable Go source files" error for a package with only test files.
} else {
- errorf("%s", err)
+ base.Errorf("%s", err)
}
a.failed = true
}
a := b.ready.pop()
b.exec.Unlock()
handle(a)
- case <-interrupted:
- setExitStatus(1)
+ case <-base.Interrupted:
+ base.SetExitStatus(1)
return
}
}
sfiles = nil
}
- cgoExe := tool("cgo")
+ cgoExe := base.Tool("cgo")
if a.cgo != nil && a.cgo.target != "" {
cgoExe = a.cgo.target
}
}
// On Windows, remove lingering ~ file from last attempt.
- if toolIsWindows {
+ if base.ToolIsWindows {
if _, err := os.Stat(dst + "~"); err == nil {
os.Remove(dst + "~")
}
mayberemovefile(dst)
df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
- if err != nil && toolIsWindows {
+ if err != nil && base.ToolIsWindows {
// Windows does not allow deletion of a binary file
// while it is executing. Try to move it out of the way.
// If the move fails, which is likely, we'll try again the
func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
cfg.BuildToolexec,
- tool("cover"),
+ base.Tool("cover"),
"-mode", a.p.coverMode,
"-var", varName,
"-o", dst,
func (b *builder) showOutput(dir, desc, out string) {
prefix := "# " + desc
suffix := "\n" + out
- if reldir := shortPath(dir); reldir != dir {
+ if reldir := base.ShortPath(dir); reldir != dir {
suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
}
b.print(prefix, suffix)
}
-// shortPath returns an absolute or relative name for path, whatever is shorter.
-func shortPath(path string) string {
- if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
- return rel
- }
- return path
-}
-
-// relPaths returns a copy of paths with absolute paths
-// made relative to the current directory if they would be shorter.
-func relPaths(paths []string) []string {
- var out []string
- pwd, _ := os.Getwd()
- for _, p := range paths {
- rel, err := filepath.Rel(pwd, p)
- if err == nil && len(rel) < len(p) {
- p = rel
- }
- out = append(out, p)
- }
- return out
-}
-
// errPrintedOutput is a special error indicating that a command failed
// but that it generated output as well, and that output has already
// been printed, so there's no point showing 'exit status 1' or whatever
type gcToolchain struct{}
func (gcToolchain) compiler() string {
- return tool("compile")
+ return base.Tool("compile")
}
func (gcToolchain) linker() string {
- return tool("link")
+ return base.Tool("link")
}
func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
}
}
- args := []interface{}{cfg.BuildToolexec, tool("compile"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs}
+ args := []interface{}{cfg.BuildToolexec, base.Tool("compile"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs}
if ofile == archive {
args = append(args, "-pack")
}
func (gcToolchain) asm(b *builder, p *Package, obj string, sfiles []string) ([]string, error) {
// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
inc := filepath.Join(goroot, "pkg", "include")
- args := []interface{}{cfg.BuildToolexec, tool("asm"), "-trimpath", b.work, "-I", obj, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, buildAsmflags}
+ args := []interface{}{cfg.BuildToolexec, base.Tool("asm"), "-trimpath", b.work, "-I", obj, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, buildAsmflags}
if p.ImportPath == "runtime" && cfg.Goarch == "386" {
for _, arg := range buildAsmflags {
if arg == "-dynlink" {
func toolVerify(b *builder, p *Package, newTool string, ofile string, args []interface{}) error {
newArgs := make([]interface{}, len(args))
copy(newArgs, args)
- newArgs[1] = tool(newTool)
+ newArgs[1] = base.Tool(newTool)
newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
return err
// Since it used to not work that way, verify.
if !cfg.BuildN {
if _, err := os.Stat(absAfile); err != nil {
- fatalf("os.Stat of archive file failed: %v", err)
+ base.Fatalf("os.Stat of archive file failed: %v", err)
}
}
dir, out = filepath.Split(out)
}
- return b.run(dir, root.p.ImportPath, nil, cfg.BuildToolexec, tool("link"), "-o", out, importArgs, ldflags, mainpkg)
+ return b.run(dir, root.p.ImportPath, nil, cfg.BuildToolexec, base.Tool("link"), "-o", out, importArgs, ldflags, mainpkg)
}
func (gcToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
}
ldflags = append(ldflags, d.p.ImportPath+"="+d.target)
}
- return b.run(".", out, nil, cfg.BuildToolexec, tool("link"), "-o", out, importArgs, ldflags)
+ return b.run(".", out, nil, cfg.BuildToolexec, base.Tool("link"), "-o", out, importArgs, ldflags)
}
func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
ldflags = append(ldflags, "-zdefs", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc")
default:
- fatalf("-buildmode=%s not supported for gccgo", buildmode)
+ base.Fatalf("-buildmode=%s not supported for gccgo", buildmode)
}
switch buildmode {
import (
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"fmt"
"io/ioutil"
"os"
"strings"
)
-var cmdClean = &Command{
+var cmdClean = &base.Command{
UsageLine: "clean [-i] [-r] [-n] [-x] [build flags] [packages]",
Short: "remove object files",
Long: `
addBuildFlags(cmdClean)
}
-func runClean(cmd *Command, args []string) {
+func runClean(cmd *base.Command, args []string) {
for _, pkg := range packagesAndErrors(args) {
clean(pkg)
}
cleaned[p] = true
if p.Dir == "" {
- errorf("can't load package: %v", p.Error)
+ base.Errorf("can't load package: %v", p.Error)
return
}
dirs, err := ioutil.ReadDir(p.Dir)
if err != nil {
- errorf("go clean %s: %v", p.Dir, err)
+ base.Errorf("go clean %s: %v", p.Dir, err)
return
}
}
}
if err := os.RemoveAll(filepath.Join(p.Dir, name)); err != nil {
- errorf("go clean: %v", err)
+ base.Errorf("go clean: %v", err)
}
}
continue
return
}
// Windows does not allow deletion of a binary file while it is executing.
- if toolIsWindows {
+ if base.ToolIsWindows {
// Remove lingering ~ file from last attempt.
if _, err2 := os.Stat(f + "~"); err2 == nil {
os.Remove(f + "~")
return
}
}
- errorf("go clean: %v", err)
+ base.Errorf("go clean: %v", err)
}
package main
-import "cmd/go/internal/cfg"
+import (
+ "cmd/go/internal/cfg"
+ "cmd/go/internal/base"
+)
-var cmdDoc = &Command{
+var cmdDoc = &base.Command{
Run: runDoc,
UsageLine: "doc [-u] [-c] [package|[package.]symbol[.method]]",
CustomFlags: true,
`,
}
-func runDoc(cmd *Command, args []string) {
- run(cfg.BuildToolexec, tool("doc"), args)
+func runDoc(cmd *base.Command, args []string) {
+ base.Run(cfg.BuildToolexec, base.Tool("doc"), args)
}
import (
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"fmt"
"os"
"runtime"
"strings"
)
-var cmdEnv = &Command{
+var cmdEnv = &base.Command{
Run: runEnv,
UsageLine: "env [var ...]",
Short: "print Go environment information",
{"GOPATH", cfg.BuildContext.GOPATH},
{"GORACE", os.Getenv("GORACE")},
{"GOROOT", goroot},
- {"GOTOOLDIR", toolDir},
+ {"GOTOOLDIR", base.ToolDir},
// disable escape codes in clang errors
{"TERM", "dumb"},
}
}
-func runEnv(cmd *Command, args []string) {
+func runEnv(cmd *base.Command, args []string) {
env := cfg.NewEnv
env = append(env, extraEnvVars()...)
if len(args) > 0 {
import (
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"cmd/go/internal/str"
)
-var cmdFix = &Command{
+var cmdFix = &base.Command{
Run: runFix,
UsageLine: "fix [packages]",
Short: "run go tool fix on packages",
`,
}
-func runFix(cmd *Command, args []string) {
+func runFix(cmd *base.Command, args []string) {
for _, pkg := range packages(args) {
// Use pkg.gofiles instead of pkg.Dir so that
// the command only applies to this package,
// not to packages in subdirectories.
- run(str.StringList(cfg.BuildToolexec, tool("fix"), relPaths(pkg.allgofiles)))
+ base.Run(str.StringList(cfg.BuildToolexec, base.Tool("fix"), base.RelPaths(pkg.allgofiles)))
}
}
package main
import (
+ "cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"cmd/go/internal/str"
"os"
"path/filepath"
)
func init() {
- addBuildFlagsNX(cmdFmt)
+ cfg.AddBuildFlagsNX(&cmdFmt.Flag)
}
-var cmdFmt = &Command{
+var cmdFmt = &base.Command{
Run: runFmt,
UsageLine: "fmt [-n] [-x] [packages]",
Short: "run gofmt on package sources",
`,
}
-func runFmt(cmd *Command, args []string) {
+func runFmt(cmd *base.Command, args []string) {
gofmt := gofmtPath()
for _, pkg := range packages(args) {
// Use pkg.gofiles instead of pkg.Dir so that
// the command only applies to this package,
// not to packages in subdirectories.
- run(str.StringList(gofmt, "-l", "-w", relPaths(pkg.allgofiles)))
+ base.Run(str.StringList(gofmt, "-l", "-w", base.RelPaths(pkg.allgofiles)))
}
}
func gofmtPath() string {
gofmt := "gofmt"
- if toolIsWindows {
- gofmt += toolWindowsExtension
+ if base.ToolIsWindows {
+ gofmt += base.ToolWindowsExtension
}
gofmtPath := filepath.Join(gobin, gofmt)
"bufio"
"bytes"
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"fmt"
"io"
"log"
"strings"
)
-var cmdGenerate = &Command{
+var cmdGenerate = &base.Command{
Run: runGenerate,
UsageLine: "generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]",
Short: "generate Go files by processing source",
cmdGenerate.Flag.StringVar(&generateRunFlag, "run", "", "")
}
-func runGenerate(cmd *Command, args []string) {
+func runGenerate(cmd *base.Command, args []string) {
ignoreImports = true
if generateRunFlag != "" {
if e != stop {
panic(e)
}
- setExitStatus(1)
+ base.SetExitStatus(1)
}
}()
g.dir, g.file = filepath.Split(g.path)
g.dir = filepath.Clean(g.dir) // No final separator please.
if cfg.BuildV {
- fmt.Fprintf(os.Stderr, "%s\n", shortPath(g.path))
+ fmt.Fprintf(os.Stderr, "%s\n", base.ShortPath(g.path))
}
// Scan for lines that start "//go:generate".
g.exec(words)
}
if err != nil && err != io.EOF {
- g.errorf("error reading %s: %s", shortPath(g.path), err)
+ g.errorf("error reading %s: %s", base.ShortPath(g.path), err)
}
return true
}
// It then exits the program (with exit status 1) because generation stops
// at the first error.
func (g *Generator) errorf(format string, args ...interface{}) {
- fmt.Fprintf(os.Stderr, "%s:%d: %s\n", shortPath(g.path), g.lineNum,
+ fmt.Fprintf(os.Stderr, "%s:%d: %s\n", base.ShortPath(g.path), g.lineNum,
fmt.Sprintf(format, args...))
panic(stop)
}
import (
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"cmd/go/internal/str"
"fmt"
"go/build"
"strings"
)
-var cmdGet = &Command{
+var cmdGet = &base.Command{
UsageLine: "get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]",
Short: "download and install packages and dependencies",
Long: `
cmdGet.Run = runGet // break init loop
}
-func runGet(cmd *Command, args []string) {
+func runGet(cmd *base.Command, args []string) {
if *getF && !*getU {
- fatalf("go get: cannot use -f flag without -u")
+ base.Fatalf("go get: cannot use -f flag without -u")
}
// Disable any prompting for passwords by Git.
for _, arg := range args {
download(arg, nil, &stk, mode)
}
- exitIfErrors()
+ base.ExitIfErrors()
// Phase 2. Rescan packages and re-evaluate args list.
p := load(arg, mode)
if p.Error != nil && p.Error.hard {
- errorf("%s", p.Error)
+ base.Errorf("%s", p.Error)
return
}
stk.push(arg)
err := downloadPackage(p)
if err != nil {
- errorf("%s", &PackageError{ImportStack: stk.copy(), Err: err.Error()})
+ base.Errorf("%s", &PackageError{ImportStack: stk.copy(), Err: err.Error()})
stk.pop()
return
}
// Do not push here too, or else stk will say arg imports arg.
p := load(arg, mode)
if p.Error != nil {
- errorf("%s", p.Error)
+ base.Errorf("%s", p.Error)
continue
}
pkgs = append(pkgs, p)
// due to wildcard expansion.
for _, p := range pkgs {
if *getFix {
- run(cfg.BuildToolexec, str.StringList(tool("fix"), relPaths(p.allgofiles)))
+ base.Run(cfg.BuildToolexec, str.StringList(base.Tool("fix"), base.RelPaths(p.allgofiles)))
// The imports might have changed, so reload again.
p = reloadPackage(arg, stk)
if p.Error != nil {
- errorf("%s", p.Error)
+ base.Errorf("%s", p.Error)
return
}
}
Err: "must be imported as " + path[j+len("vendor/"):],
}
stk.pop()
- errorf("%s", err)
+ base.Errorf("%s", err)
continue
}
// If this is a test import, apply vendor lookup now.
package main
-var helpC = &Command{
+import "cmd/go/internal/base"
+
+var helpC = &base.Command{
UsageLine: "c",
Short: "calling between Go and C",
Long: `
`,
}
-var helpPackages = &Command{
+var helpPackages = &base.Command{
UsageLine: "packages",
Short: "description of package lists",
Long: `
`,
}
-var helpImportPath = &Command{
+var helpImportPath = &base.Command{
UsageLine: "importpath",
Short: "import path syntax",
Long: `
`,
}
-var helpGopath = &Command{
+var helpGopath = &base.Command{
UsageLine: "gopath",
Short: "GOPATH environment variable",
Long: `
`,
}
-var helpEnvironment = &Command{
+var helpEnvironment = &base.Command{
UsageLine: "environment",
Short: "environment variables",
Long: `
`,
}
-var helpFileType = &Command{
+var helpFileType = &base.Command{
UsageLine: "filetype",
Short: "file types",
Long: `
`,
}
-var helpBuildmode = &Command{
+var helpBuildmode = &base.Command{
UsageLine: "buildmode",
Short: "description of build modes",
Long: `
--- /dev/null
+// Copyright 2017 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.
+
+// Package base defines shared basic pieces of the go command,
+// in particular logging and the Command structure.
+package base
+
+import (
+ "cmd/go/internal/cfg"
+ "cmd/go/internal/str"
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "os/exec"
+ "strings"
+ "sync"
+)
+
+// A Command is an implementation of a go command
+// like go build or go fix.
+type Command struct {
+ // Run runs the command.
+ // The args are the arguments after the command name.
+ Run func(cmd *Command, args []string)
+
+ // UsageLine is the one-line usage message.
+ // The first word in the line is taken to be the command name.
+ UsageLine string
+
+ // Short is the short description shown in the 'go help' output.
+ Short string
+
+ // Long is the long message shown in the 'go help <this-command>' output.
+ Long string
+
+ // Flag is a set of flags specific to this command.
+ Flag flag.FlagSet
+
+ // CustomFlags indicates that the command will do its own
+ // flag parsing.
+ CustomFlags bool
+}
+
+// Name returns the command's name: the first word in the usage line.
+func (c *Command) Name() string {
+ name := c.UsageLine
+ i := strings.Index(name, " ")
+ if i >= 0 {
+ name = name[:i]
+ }
+ return name
+}
+
+func (c *Command) Usage() {
+ fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine)
+ fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(c.Long))
+ os.Exit(2)
+}
+
+// Runnable reports whether the command can be run; otherwise
+// it is a documentation pseudo-command such as importpath.
+func (c *Command) Runnable() bool {
+ return c.Run != nil
+}
+
+var atExitFuncs []func()
+
+func AtExit(f func()) {
+ atExitFuncs = append(atExitFuncs, f)
+}
+
+func Exit() {
+ for _, f := range atExitFuncs {
+ f()
+ }
+ os.Exit(exitStatus)
+}
+
+func Fatalf(format string, args ...interface{}) {
+ Errorf(format, args...)
+ Exit()
+}
+
+func Errorf(format string, args ...interface{}) {
+ log.Printf(format, args...)
+ SetExitStatus(1)
+}
+
+func ExitIfErrors() {
+ if exitStatus != 0 {
+ Exit()
+ }
+}
+
+var exitStatus = 0
+var exitMu sync.Mutex
+
+func SetExitStatus(n int) {
+ exitMu.Lock()
+ if exitStatus < n {
+ exitStatus = n
+ }
+ exitMu.Unlock()
+}
+
+// Run runs the command, with stdout and stderr
+// connected to the go command's own stdout and stderr.
+// If the command fails, Run reports the error using Errorf.
+func Run(cmdargs ...interface{}) {
+ cmdline := str.StringList(cmdargs...)
+ if cfg.BuildN || cfg.BuildX {
+ fmt.Printf("%s\n", strings.Join(cmdline, " "))
+ if cfg.BuildN {
+ return
+ }
+ }
+
+ cmd := exec.Command(cmdline[0], cmdline[1:]...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ if err := cmd.Run(); err != nil {
+ Errorf("%v", err)
+ }
+}
+
+// RunStdin is like run but connects Stdin.
+func RunStdin(cmdline []string) {
+ cmd := exec.Command(cmdline[0], cmdline[1:]...)
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ cmd.Env = cfg.OrigEnv
+ StartSigHandlers()
+ if err := cmd.Run(); err != nil {
+ Errorf("%v", err)
+ }
+}
+
+// Usage is the usage-reporting function, filled in by package main
+// but here for reference by other packages.
+var Usage func()
--- /dev/null
+// Copyright 2017 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.
+
+package base
+
+import (
+ "os"
+ "path/filepath"
+)
+
+var Cwd, _ = os.Getwd()
+
+// ShortPath returns an absolute or relative name for path, whatever is shorter.
+func ShortPath(path string) string {
+ if rel, err := filepath.Rel(Cwd, path); err == nil && len(rel) < len(path) {
+ return rel
+ }
+ return path
+}
+
+// RelPaths returns a copy of paths with absolute paths
+// made relative to the current directory if they would be shorter.
+func RelPaths(paths []string) []string {
+ var out []string
+ // TODO(rsc): Can this use Cwd from above?
+ pwd, _ := os.Getwd()
+ for _, p := range paths {
+ rel, err := filepath.Rel(pwd, p)
+ if err == nil && len(rel) < len(p) {
+ p = rel
+ }
+ out = append(out, p)
+ }
+ return out
+}
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package base
import (
"os"
"sync"
)
-// interrupted is closed, if go process is interrupted.
-var interrupted = make(chan struct{})
+// Interrupted is closed when the go command receives an interrupt signal.
+var Interrupted = make(chan struct{})
// processSignals setups signal handler.
func processSignals() {
signal.Notify(sig, signalsToIgnore...)
go func() {
<-sig
- close(interrupted)
+ close(Interrupted)
}()
}
var onceProcessSignals sync.Once
-// startSigHandlers start signal handlers.
-func startSigHandlers() {
+// StartSigHandlers starts the signal handlers.
+func StartSigHandlers() {
onceProcessSignals.Do(processSignals)
}
// +build plan9 windows
-package main
+package base
import (
"os"
var signalsToIgnore = []os.Signal{os.Interrupt}
-// signalTrace is the signal to send to make a Go program
-// crash with a stack trace.
-var signalTrace os.Signal = nil
+// SignalTrace is the signal to send to make a Go program
+// crash with a stack trace (no such signal in this case).
+var SignalTrace os.Signal = nil
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-package main
+package base
import (
"os"
var signalsToIgnore = []os.Signal{os.Interrupt, syscall.SIGQUIT}
-// signalTrace is the signal to send to make a Go program
+// SignalTrace is the signal to send to make a Go program
// crash with a stack trace.
-var signalTrace os.Signal = syscall.SIGQUIT
+var SignalTrace os.Signal = syscall.SIGQUIT
--- /dev/null
+// Copyright 2017 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.
+
+package base
+
+import (
+ "fmt"
+ "go/build"
+ "os"
+ "path/filepath"
+ "runtime"
+
+ "cmd/go/internal/cfg"
+)
+
+// Configuration for finding tool binaries.
+var (
+ ToolGOOS = runtime.GOOS
+ ToolGOARCH = runtime.GOARCH
+ ToolIsWindows = ToolGOOS == "windows"
+ ToolDir = build.ToolDir
+)
+
+const ToolWindowsExtension = ".exe"
+
+// Tool returns the path to the named tool (for example, "vet").
+// If the tool cannot be found, Tool exits the process.
+func Tool(toolName string) string {
+ toolPath := filepath.Join(ToolDir, toolName)
+ if ToolIsWindows {
+ toolPath += ToolWindowsExtension
+ }
+ if len(cfg.BuildToolexec) > 0 {
+ return toolPath
+ }
+ // Give a nice message if there is no tool with that name.
+ if _, err := os.Stat(toolPath); err != nil {
+ if isInGoToolsRepo(toolName) {
+ fmt.Fprintf(os.Stderr, "go tool: no such tool %q; to install:\n\tgo get golang.org/x/tools/cmd/%s\n", toolName, toolName)
+ } else {
+ fmt.Fprintf(os.Stderr, "go tool: no such tool %q\n", toolName)
+ }
+ SetExitStatus(2)
+ Exit()
+ }
+ return toolPath
+}
+
+// TODO: Delete.
+func isInGoToolsRepo(toolName string) bool {
+ return false
+}
package cfg
import (
+ "flag"
"go/build"
"runtime"
)
ExeSuffix string
Gopath []string
)
+
+// AddBuildFlagsNX adds the -n and -x build flags to the flag set.
+func AddBuildFlagsNX(flags *flag.FlagSet) {
+ flags.BoolVar(&BuildN, "n", false, "")
+ flags.BoolVar(&BuildX, "x", false, "")
+}
import (
"bufio"
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"encoding/json"
"io"
"os"
"text/template"
)
-var cmdList = &Command{
+var cmdList = &base.Command{
UsageLine: "list [-e] [-f format] [-json] [build flags] [packages]",
Short: "list packages",
Long: `
var listJson = cmdList.Flag.Bool("json", false, "")
var nl = []byte{'\n'}
-func runList(cmd *Command, args []string) {
+func runList(cmd *base.Command, args []string) {
buildModeInit()
out := newTrackingWriter(os.Stdout)
defer out.w.Flush()
b, err := json.MarshalIndent(p, "", "\t")
if err != nil {
out.Flush()
- fatalf("%s", err)
+ base.Fatalf("%s", err)
}
out.Write(b)
out.Write(nl)
}
tmpl, err := template.New("main").Funcs(fm).Parse(*listFmt)
if err != nil {
- fatalf("%s", err)
+ base.Fatalf("%s", err)
}
do = func(p *Package) {
if err := tmpl.Execute(out, p); err != nil {
out.Flush()
- fatalf("%s", err)
+ base.Fatalf("%s", err)
}
if out.NeedNL() {
out.Write(nl)
"bufio"
"bytes"
"cmd/go/internal/cfg"
- "cmd/go/internal/str"
+ "cmd/go/internal/base"
"flag"
"fmt"
"go/build"
"io"
"log"
"os"
- "os/exec"
"path"
"path/filepath"
"regexp"
"runtime"
"strings"
- "sync"
"text/template"
"unicode"
"unicode/utf8"
)
-// A Command is an implementation of a go command
-// like go build or go fix.
-type Command struct {
- // Run runs the command.
- // The args are the arguments after the command name.
- Run func(cmd *Command, args []string)
-
- // UsageLine is the one-line usage message.
- // The first word in the line is taken to be the command name.
- UsageLine string
-
- // Short is the short description shown in the 'go help' output.
- Short string
-
- // Long is the long message shown in the 'go help <this-command>' output.
- Long string
-
- // Flag is a set of flags specific to this command.
- Flag flag.FlagSet
-
- // CustomFlags indicates that the command will do its own
- // flag parsing.
- CustomFlags bool
-}
-
-// Name returns the command's name: the first word in the usage line.
-func (c *Command) Name() string {
- name := c.UsageLine
- i := strings.Index(name, " ")
- if i >= 0 {
- name = name[:i]
- }
- return name
-}
-
-func (c *Command) Usage() {
- fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine)
- fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(c.Long))
- os.Exit(2)
-}
-
-// Runnable reports whether the command can be run; otherwise
-// it is a documentation pseudo-command such as importpath.
-func (c *Command) Runnable() bool {
- return c.Run != nil
-}
-
// Commands lists the available commands and help topics.
// The order here is the order in which they are printed by 'go help'.
-var commands []*Command
+var commands []*base.Command
func init() {
- commands = []*Command{
+ commands = []*base.Command{
cmdBuild,
cmdClean,
cmdDoc,
}
}
-var exitStatus = 0
-var exitMu sync.Mutex
-
-func setExitStatus(n int) {
- exitMu.Lock()
- if exitStatus < n {
- exitStatus = n
- }
- exitMu.Unlock()
-}
-
func main() {
_ = go11tag
- flag.Usage = usage
+ flag.Usage = base.Usage
flag.Parse()
log.SetFlags(0)
args := flag.Args()
if len(args) < 1 {
- usage()
+ base.Usage()
}
if args[0] == "help" {
args = cmd.Flag.Args()
}
cmd.Run(cmd, args)
- exit()
+ base.Exit()
return
}
}
fmt.Fprintf(os.Stderr, "go: unknown subcommand %q\nRun 'go help' for usage.\n", args[0])
- setExitStatus(2)
- exit()
+ base.SetExitStatus(2)
+ base.Exit()
}
var usageTemplate = `Go is a tool for managing Go source code.
if strings.Contains(ew.err.Error(), "pipe") {
os.Exit(1)
}
- fatalf("writing output: %v", ew.err)
+ base.Fatalf("writing output: %v", ew.err)
}
if err != nil {
panic(err)
var usage func()
func init() {
- usage = mainUsage
+ base.Usage = mainUsage
}
func mainUsage() {
fmt.Println()
buf := new(bytes.Buffer)
printUsage(buf)
- usage := &Command{Long: buf.String()}
- tmpl(&commentWriter{W: os.Stdout}, documentationTemplate, append([]*Command{usage}, commands...))
+ usage := &base.Command{Long: buf.String()}
+ tmpl(&commentWriter{W: os.Stdout}, documentationTemplate, append([]*base.Command{usage}, commands...))
fmt.Println("package main")
return
}
return out
}
-var atexitFuncs []func()
-
-func atexit(f func()) {
- atexitFuncs = append(atexitFuncs, f)
-}
-
-func exit() {
- for _, f := range atexitFuncs {
- f()
- }
- os.Exit(exitStatus)
-}
-
-func fatalf(format string, args ...interface{}) {
- errorf(format, args...)
- exit()
-}
-
-func errorf(format string, args ...interface{}) {
- log.Printf(format, args...)
- setExitStatus(1)
-}
-
-func exitIfErrors() {
- if exitStatus != 0 {
- exit()
- }
-}
-
-func run(cmdargs ...interface{}) {
- cmdline := str.StringList(cmdargs...)
- if cfg.BuildN || cfg.BuildX {
- fmt.Printf("%s\n", strings.Join(cmdline, " "))
- if cfg.BuildN {
- return
- }
- }
-
- cmd := exec.Command(cmdline[0], cmdline[1:]...)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- if err := cmd.Run(); err != nil {
- errorf("%v", err)
- }
-}
-
// envForDir returns a copy of the environment
// suitable for running in the given directory.
// The environment is the current process's environment
import (
"bytes"
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"cmd/go/internal/str"
"crypto/sha1"
"errors"
func setErrorPos(p *Package, importPos []token.Position) *Package {
if len(importPos) > 0 {
pos := importPos[0]
- pos.Filename = shortPath(pos.Filename)
+ pos.Filename = base.ShortPath(pos.Filename)
p.Error.Pos = pos.String()
}
return p
}
if !hasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator || parent.ImportPath != "command-line-arguments" && !parent.local && filepath.Join(root, parent.ImportPath) != dir {
- fatalf("unexpected directory layout:\n"+
+ base.Fatalf("unexpected directory layout:\n"+
" import path: %s\n"+
" root: %s\n"+
" dir: %s\n"+
// instead of just the first, as err.Error does.
var buf bytes.Buffer
for _, e := range err {
- e.Pos.Filename = shortPath(e.Pos.Filename)
+ e.Pos.Filename = base.ShortPath(e.Pos.Filename)
buf.WriteString("\n")
buf.WriteString(e.Error())
}
}
_, elem := filepath.Split(p.Dir)
full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem
- if cfg.BuildContext.GOOS != toolGOOS || cfg.BuildContext.GOARCH != toolGOARCH {
+ if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH {
// Install cross-compiled binaries to subdirectories of bin.
elem = full
}
}
} else if !os.IsNotExist(err) {
- fatalf("unexpected error reading %s: %v", shlibnamefile, err)
+ base.Fatalf("unexpected error reading %s: %v", shlibnamefile, err)
}
}
}
if p.Standard && p.ImportPath == "runtime/internal/sys" && cfg.BuildContext.Compiler != "gccgo" {
data, err := ioutil.ReadFile(filepath.Join(p.Dir, "zversion.go"))
if err != nil {
- fatalf("go: %s", err)
+ base.Fatalf("go: %s", err)
}
fmt.Fprintf(h, "zversion %q\n", string(data))
}
p.buildID = fmt.Sprintf("%x", h.Sum(nil))
}
-var cwd, _ = os.Getwd()
-
var cmdCache = map[string]*Package{}
// loadPackage is like loadImport but is used for command-line arguments,
// referring to io/ioutil rather than a hypothetical import of
// "./ioutil".
if build.IsLocalImport(arg) {
- bp, _ := cfg.BuildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
+ bp, _ := cfg.BuildContext.ImportDir(filepath.Join(base.Cwd, arg), build.FindOnly)
if bp.ImportPath != "" && bp.ImportPath != "." {
arg = bp.ImportPath
}
}
- return loadImport(arg, cwd, nil, stk, nil, 0)
+ return loadImport(arg, base.Cwd, nil, stk, nil, 0)
}
// packages returns the packages named by the
var pkgs []*Package
for _, pkg := range packagesAndErrors(args) {
if pkg.Error != nil {
- errorf("can't load package: %s", pkg.Error)
+ base.Errorf("can't load package: %s", pkg.Error)
continue
}
pkgs = append(pkgs, pkg)
printed := map[*PackageError]bool{}
for _, pkg := range pkgs {
if pkg.Error != nil {
- errorf("can't load package: %s", pkg.Error)
+ base.Errorf("can't load package: %s", pkg.Error)
}
for _, err := range pkg.DepsErrors {
// Since these are errors in dependencies,
// Only print each once.
if !printed[err] {
printed[err] = true
- errorf("%s", err)
+ base.Errorf("%s", err)
}
}
}
- exitIfErrors()
+ base.ExitIfErrors()
// Check for duplicate loads of the same package.
// That should be impossible, but if it does happen then
for _, pkg := range packageList(pkgs) {
if seen[pkg.ImportPath] && !reported[pkg.ImportPath] {
reported[pkg.ImportPath] = true
- errorf("internal error: duplicate loads of %s", pkg.ImportPath)
+ base.Errorf("internal error: duplicate loads of %s", pkg.ImportPath)
}
seen[pkg.ImportPath] = true
}
- exitIfErrors()
+ base.ExitIfErrors()
return pkgs
}
import (
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"cmd/go/internal/str"
"io/ioutil"
"os"
oldGopath := cfg.BuildContext.GOPATH
defer func() {
cfg.BuildContext.GOPATH = oldGopath
- os.Chdir(cwd)
+ os.Chdir(base.Cwd)
err := os.RemoveAll(tmpGopath)
if err != nil {
t.Error(err)
import (
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"cmd/go/internal/str"
"fmt"
"os"
return execCmd
}
-var cmdRun = &Command{
+var cmdRun = &base.Command{
UsageLine: "run [build flags] [-exec xprog] gofiles... [arguments...]",
Short: "compile and run Go program",
Long: `
return fmt.Fprint(os.Stderr, args...)
}
-func runRun(cmd *Command, args []string) {
+func runRun(cmd *base.Command, args []string) {
instrumentInit()
buildModeInit()
var b builder
}
files, cmdArgs := args[:i], args[i:]
if len(files) == 0 {
- fatalf("go run: no go files listed")
+ base.Fatalf("go run: no go files listed")
}
for _, file := range files {
if strings.HasSuffix(file, "_test.go") {
// goFilesPackage is going to assign this to TestGoFiles.
// Reject since it won't be part of the build.
- fatalf("go run: cannot run *_test.go files (%s)", file)
+ base.Fatalf("go run: cannot run *_test.go files (%s)", file)
}
}
p := goFilesPackage(files)
if p.Error != nil {
- fatalf("%s", p.Error)
+ base.Fatalf("%s", p.Error)
}
p.omitDWARF = true
if len(p.DepsErrors) > 0 {
for _, err := range p.DepsErrors {
if !printed[err] {
printed[err] = true
- errorf("%s", err)
+ base.Errorf("%s", err)
}
}
}
- exitIfErrors()
+ base.ExitIfErrors()
if p.Name != "main" {
- fatalf("go run: cannot run non-main package")
+ base.Fatalf("go run: cannot run non-main package")
}
p.target = "" // must build - not up to date
var src string
if !cfg.BuildContext.CgoEnabled {
hint = " (cgo is disabled)"
}
- fatalf("go run: no suitable source files%s", hint)
+ base.Fatalf("go run: no suitable source files%s", hint)
}
p.exeName = src[:len(src)-len(".go")] // name temporary executable for first go file
a1 := b.action(modeBuild, modeBuild, p)
}
}
- runStdin(cmdline)
+ base.RunStdin(cmdline)
return nil
}
-
-// runStdin is like run, but connects Stdin.
-func runStdin(cmdline []string) {
- cmd := exec.Command(cmdline[0], cmdline[1:]...)
- cmd.Stdin = os.Stdin
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- cmd.Env = cfg.OrigEnv
- startSigHandlers()
- if err := cmd.Run(); err != nil {
- errorf("%v", err)
- }
-}
import (
"bytes"
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"cmd/go/internal/str"
"errors"
"fmt"
const testUsage = "test [build/test flags] [packages] [build/test flags & test binary flags]"
-var cmdTest = &Command{
+var cmdTest = &base.Command{
CustomFlags: true,
UsageLine: testUsage,
Short: "test packages",
flags are also accessible by 'go test'.
`
-var helpTestflag = &Command{
+var helpTestflag = &base.Command{
UsageLine: "testflag",
Short: "description of testing flags",
Long: `
binary, instead of being interpreted as the package list.
`
-var helpTestfunc = &Command{
+var helpTestfunc = &base.Command{
UsageLine: "testfunc",
Short: "description of testing functions",
Long: `
"os": true,
}
-func runTest(cmd *Command, args []string) {
+func runTest(cmd *base.Command, args []string) {
var pkgArgs []string
pkgArgs, testArgs = testFlags(args)
buildModeInit()
pkgs := packagesForBuild(pkgArgs)
if len(pkgs) == 0 {
- fatalf("no packages to test")
+ base.Fatalf("no packages to test")
}
if testC && len(pkgs) != 1 {
- fatalf("cannot use -c flag with multiple packages")
+ base.Fatalf("cannot use -c flag with multiple packages")
}
if testO != "" && len(pkgs) != 1 {
- fatalf("cannot use -o flag with multiple packages")
+ base.Fatalf("cannot use -o flag with multiple packages")
}
if testProfile && len(pkgs) != 1 {
- fatalf("cannot use test profile flag with multiple packages")
+ base.Fatalf("cannot use test profile flag with multiple packages")
}
// If a test timeout was given and is parseable, set our kill timeout
failed := fmt.Sprintf("FAIL\t%s [setup failed]\n", p.ImportPath)
if p.ImportPath != "" {
- errorf("# %s\n%s\n%s", p.ImportPath, str, failed)
+ base.Errorf("# %s\n%s\n%s", p.ImportPath, str, failed)
} else {
- errorf("%s\n%s", str, failed)
+ base.Errorf("%s\n%s", str, failed)
}
continue
}
if testC || testNeedBinary {
// -c or profiling flag: create action to copy binary to ./test.out.
- target := filepath.Join(cwd, testBinary+cfg.ExeSuffix)
+ target := filepath.Join(base.Cwd, testBinary+cfg.ExeSuffix)
if testO != "" {
target = testO
if !filepath.IsAbs(target) {
- target = filepath.Join(cwd, target)
+ target = filepath.Join(base.Cwd, target)
}
}
buildAction = &action{
// We were unable to build the binary.
a.failed = false
fmt.Fprintf(a.testOutput, "FAIL\t%s [build failed]\n", a.p.ImportPath)
- setExitStatus(1)
+ base.SetExitStatus(1)
return nil
}
// running.
if err == nil {
tick := time.NewTimer(testKillTimeout)
- startSigHandlers()
+ base.StartSigHandlers()
done := make(chan error)
go func() {
done <- cmd.Wait()
case err = <-done:
// ok
case <-tick.C:
- if signalTrace != nil {
+ if base.SignalTrace != nil {
// Send a quit signal in the hope that the program will print
// a stack trace and exit. Give it five seconds before resorting
// to Kill.
- cmd.Process.Signal(signalTrace)
+ cmd.Process.Signal(base.SignalTrace)
select {
case err = <-done:
- fmt.Fprintf(&buf, "*** Test killed with %v: ran too long (%v).\n", signalTrace, testKillTimeout)
+ fmt.Fprintf(&buf, "*** Test killed with %v: ran too long (%v).\n", base.SignalTrace, testKillTimeout)
break Outer
case <-time.After(5 * time.Second):
}
return nil
}
- setExitStatus(1)
+ base.SetExitStatus(1)
if len(out) > 0 {
a.testOutput.Write(out)
// assume printing the test binary's exit status is superfluous
import (
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"flag"
"fmt"
"os"
// add build flags to testFlagDefn
func init() {
- var cmd Command
+ var cmd base.Command
addBuildFlags(&cmd)
cmd.Flag.VisitAll(func(f *flag.Flag) {
if f.Name == "v" {
}
if f.flagValue != nil {
if err := f.flagValue.Set(value); err != nil {
- fatalf("invalid flag argument for -%s: %v", f.name, err)
+ base.Fatalf("invalid flag argument for -%s: %v", f.name, err)
}
} else {
// Test-only flags.
case "exec":
execCmd, err = splitQuotedFields(value)
if err != nil {
- fatalf("invalid flag argument for -%s: %v", f.name, err)
+ base.Fatalf("invalid flag argument for -%s: %v", f.name, err)
}
case "bench":
// record that we saw the flag; don't care about the value
case "set", "count", "atomic":
cfg.TestCoverMode = value
default:
- fatalf("invalid flag argument for -covermode: %q", value)
+ base.Fatalf("invalid flag argument for -covermode: %q", value)
}
testCover = true
case "outputdir":
if testProfile && outputDir == "" {
dir, err := os.Getwd()
if err != nil {
- fatalf("error from os.Getwd: %s", err)
+ base.Fatalf("error from os.Getwd: %s", err)
}
passToTest = append(passToTest, "-test.outputdir", dir)
}
}
switch arg {
case "-?", "-h", "-help":
- usage()
+ base.Usage()
}
if arg == "" || arg[0] != '-' {
return
package main
import (
- "cmd/go/internal/cfg"
"fmt"
- "go/build"
"os"
"os/exec"
- "path/filepath"
- "runtime"
"sort"
"strings"
+
+ "cmd/go/internal/cfg"
+ "cmd/go/internal/base"
)
-var cmdTool = &Command{
+var cmdTool = &base.Command{
Run: runTool,
UsageLine: "tool [-n] command [args...]",
Short: "run specified go tool",
`,
}
-var (
- toolGOOS = runtime.GOOS
- toolGOARCH = runtime.GOARCH
- toolIsWindows = toolGOOS == "windows"
- toolDir = build.ToolDir
-
- toolN bool
-)
+var toolN bool
func init() {
cmdTool.Flag.BoolVar(&toolN, "n", false, "")
}
-const toolWindowsExtension = ".exe"
-
-func tool(toolName string) string {
- toolPath := filepath.Join(toolDir, toolName)
- if toolIsWindows {
- toolPath += toolWindowsExtension
- }
- if len(cfg.BuildToolexec) > 0 {
- return toolPath
- }
- // Give a nice message if there is no tool with that name.
- if _, err := os.Stat(toolPath); err != nil {
- if isInGoToolsRepo(toolName) {
- fmt.Fprintf(os.Stderr, "go tool: no such tool %q; to install:\n\tgo get golang.org/x/tools/cmd/%s\n", toolName, toolName)
- } else {
- fmt.Fprintf(os.Stderr, "go tool: no such tool %q\n", toolName)
- }
- setExitStatus(2)
- exit()
- }
- return toolPath
-}
-
-func isInGoToolsRepo(toolName string) bool {
- return false
-}
-
-func runTool(cmd *Command, args []string) {
+func runTool(cmd *base.Command, args []string) {
if len(args) == 0 {
listTools()
return
case 'a' <= c && c <= 'z', '0' <= c && c <= '9', c == '_':
default:
fmt.Fprintf(os.Stderr, "go tool: bad tool name %q\n", toolName)
- setExitStatus(2)
+ base.SetExitStatus(2)
return
}
}
- toolPath := tool(toolName)
+ toolPath := base.Tool(toolName)
if toolPath == "" {
return
}
if e, ok := err.(*exec.ExitError); !ok || !e.Exited() || cfg.BuildX {
fmt.Fprintf(os.Stderr, "go tool %s: %s\n", toolName, err)
}
- setExitStatus(1)
+ base.SetExitStatus(1)
return
}
}
// listTools prints a list of the available tools in the tools directory.
func listTools() {
- f, err := os.Open(toolDir)
+ f, err := os.Open(base.ToolDir)
if err != nil {
fmt.Fprintf(os.Stderr, "go tool: no tool directory: %s\n", err)
- setExitStatus(2)
+ base.SetExitStatus(2)
return
}
defer f.Close()
names, err := f.Readdirnames(-1)
if err != nil {
fmt.Fprintf(os.Stderr, "go tool: can't read directory: %s\n", err)
- setExitStatus(2)
+ base.SetExitStatus(2)
return
}
// Unify presentation by going to lower case.
name = strings.ToLower(name)
// If it's windows, don't show the .exe suffix.
- if toolIsWindows && strings.HasSuffix(name, toolWindowsExtension) {
- name = name[:len(name)-len(toolWindowsExtension)]
+ if base.ToolIsWindows && strings.HasSuffix(name, base.ToolWindowsExtension) {
+ name = name[:len(name)-len(base.ToolWindowsExtension)]
}
fmt.Println(name)
}
package main
import (
+ "cmd/go/internal/base"
"fmt"
"runtime"
)
-var cmdVersion = &Command{
+var cmdVersion = &base.Command{
Run: runVersion,
UsageLine: "version",
Short: "print Go version",
Long: `Version prints the Go version, as reported by runtime.Version.`,
}
-func runVersion(cmd *Command, args []string) {
+func runVersion(cmd *base.Command, args []string) {
if len(args) != 0 {
cmd.Usage()
}
"path/filepath"
"cmd/go/internal/cfg"
+ "cmd/go/internal/base"
"cmd/go/internal/str"
)
addBuildFlags(cmdVet)
}
-var cmdVet = &Command{
+var cmdVet = &base.Command{
Run: runVet,
UsageLine: "vet [-n] [-x] [build flags] [packages]",
Short: "run go tool vet on packages",
`,
}
-func runVet(cmd *Command, args []string) {
+func runVet(cmd *base.Command, args []string) {
for _, p := range packages(args) {
// Vet expects to be given a set of files all from the same package.
// Run once for package p and once for package p_test.
for i := range files {
files[i] = filepath.Join(p.Dir, files[i])
}
- run(cfg.BuildToolexec, tool("vet"), relPaths(files))
+ base.Run(cfg.BuildToolexec, base.Tool("vet"), base.RelPaths(files))
}