mirror of
https://github.com/golang/go
synced 2024-11-19 02:04:42 -07:00
cmd/go: split out cmd/go/internal/work
This is one CL in a long sequence of changes to break up the go command from one package into a plausible group of packages. This sequence is concerned only with moving code, not changing or cleaning up code. There will still be more cleanup after this sequence. The entire sequence will be submitted together: it is not a goal for the tree to build at every step. For #18653. Change-Id: Icdd181098f9f0e81f68bf201e6867cdd8f820300 Reviewed-on: https://go-review.googlesource.com/36197 Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
eb93b20c2e
commit
3c667ef421
@ -1,44 +0,0 @@
|
||||
// Copyright 2016 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 main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRemoveDevNull(t *testing.T) {
|
||||
fi, err := os.Lstat(os.DevNull)
|
||||
if err != nil {
|
||||
t.Skip(err)
|
||||
}
|
||||
if fi.Mode().IsRegular() {
|
||||
t.Errorf("Lstat(%s).Mode().IsRegular() = true; expected false", os.DevNull)
|
||||
}
|
||||
mayberemovefile(os.DevNull)
|
||||
_, err = os.Lstat(os.DevNull)
|
||||
if err != nil {
|
||||
t.Errorf("mayberemovefile(%s) did remove it; oops", os.DevNull)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitPkgConfigOutput(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
in []byte
|
||||
want []string
|
||||
}{
|
||||
{[]byte(`-r:foo -L/usr/white\ space/lib -lfoo\ bar -lbar\ baz`), []string{"-r:foo", "-L/usr/white space/lib", "-lfoo bar", "-lbar baz"}},
|
||||
{[]byte(`-lextra\ fun\ arg\\`), []string{`-lextra fun arg\`}},
|
||||
{[]byte(`broken flag\`), []string{"broken", "flag"}},
|
||||
{[]byte("\textra whitespace\r\n"), []string{"extra", "whitespace"}},
|
||||
{[]byte(" \r\n "), nil},
|
||||
} {
|
||||
got := splitPkgConfigOutput(test.in)
|
||||
if !reflect.DeepEqual(got, test.want) {
|
||||
t.Errorf("splitPkgConfigOutput(%v) = %v; want %v", test.in, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
@ -5,14 +5,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
"cmd/go/internal/work"
|
||||
)
|
||||
|
||||
var cmdClean = &base.Command{
|
||||
@ -74,7 +76,7 @@ func init() {
|
||||
// mentioned explicitly in the docs but they
|
||||
// are part of the build flags.
|
||||
|
||||
addBuildFlags(cmdClean)
|
||||
work.AddBuildFlags(cmdClean)
|
||||
}
|
||||
|
||||
func runClean(cmd *base.Command, args []string) {
|
||||
@ -124,8 +126,8 @@ func clean(p *load.Package) {
|
||||
return
|
||||
}
|
||||
|
||||
var b builder
|
||||
b.print = fmt.Print
|
||||
var b work.Builder
|
||||
b.Print = fmt.Print
|
||||
|
||||
packageFile := map[string]bool{}
|
||||
if p.Name != "main" {
|
||||
@ -176,7 +178,7 @@ func clean(p *load.Package) {
|
||||
}
|
||||
|
||||
if cfg.BuildN || cfg.BuildX {
|
||||
b.showcmd(p.Dir, "rm -f %s", strings.Join(allRemove, " "))
|
||||
b.Showcmd(p.Dir, "rm -f %s", strings.Join(allRemove, " "))
|
||||
}
|
||||
|
||||
toRemove := map[string]bool{}
|
||||
@ -189,7 +191,7 @@ func clean(p *load.Package) {
|
||||
// TODO: Remove once Makefiles are forgotten.
|
||||
if cleanDir[name] {
|
||||
if cfg.BuildN || cfg.BuildX {
|
||||
b.showcmd(p.Dir, "rm -r %s", name)
|
||||
b.Showcmd(p.Dir, "rm -r %s", name)
|
||||
if cfg.BuildN {
|
||||
continue
|
||||
}
|
||||
@ -212,7 +214,7 @@ func clean(p *load.Package) {
|
||||
|
||||
if cleanI && p.Internal.Target != "" {
|
||||
if cfg.BuildN || cfg.BuildX {
|
||||
b.showcmd("", "rm -f %s", p.Internal.Target)
|
||||
b.Showcmd("", "rm -f %s", p.Internal.Target)
|
||||
}
|
||||
if !cfg.BuildN {
|
||||
removeFile(p.Internal.Target)
|
||||
|
@ -5,13 +5,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
"cmd/go/internal/work"
|
||||
)
|
||||
|
||||
var cmdEnv = &base.Command{
|
||||
@ -29,8 +31,8 @@ each named variable on its own line.
|
||||
}
|
||||
|
||||
func mkEnv() []cfg.EnvVar {
|
||||
var b builder
|
||||
b.init()
|
||||
var b work.Builder
|
||||
b.Init()
|
||||
|
||||
env := []cfg.EnvVar{
|
||||
{"GOARCH", cfg.Goarch},
|
||||
@ -48,10 +50,10 @@ func mkEnv() []cfg.EnvVar {
|
||||
{"TERM", "dumb"},
|
||||
}
|
||||
|
||||
if gccgoBin != "" {
|
||||
env = append(env, cfg.EnvVar{"GCCGO", gccgoBin})
|
||||
if work.GccgoBin != "" {
|
||||
env = append(env, cfg.EnvVar{"GCCGO", work.GccgoBin})
|
||||
} else {
|
||||
env = append(env, cfg.EnvVar{"GCCGO", gccgoName})
|
||||
env = append(env, cfg.EnvVar{"GCCGO", work.GccgoName})
|
||||
}
|
||||
|
||||
switch cfg.Goarch {
|
||||
@ -61,10 +63,10 @@ func mkEnv() []cfg.EnvVar {
|
||||
env = append(env, cfg.EnvVar{"GO386", os.Getenv("GO386")})
|
||||
}
|
||||
|
||||
cmd := b.gccCmd(".")
|
||||
cmd := b.GccCmd(".")
|
||||
env = append(env, cfg.EnvVar{"CC", cmd[0]})
|
||||
env = append(env, cfg.EnvVar{"GOGCCFLAGS", strings.Join(cmd[3:], " ")})
|
||||
cmd = b.gxxCmd(".")
|
||||
cmd = b.GxxCmd(".")
|
||||
env = append(env, cfg.EnvVar{"CXX", cmd[0]})
|
||||
|
||||
if cfg.BuildContext.CgoEnabled {
|
||||
@ -87,11 +89,11 @@ func findEnv(env []cfg.EnvVar, name string) string {
|
||||
|
||||
// extraEnvVars returns environment variables that should not leak into child processes.
|
||||
func extraEnvVars() []cfg.EnvVar {
|
||||
var b builder
|
||||
b.init()
|
||||
cppflags, cflags, cxxflags, fflags, ldflags := b.cflags(&load.Package{})
|
||||
var b work.Builder
|
||||
b.Init()
|
||||
cppflags, cflags, cxxflags, fflags, ldflags := b.CFlags(&load.Package{})
|
||||
return []cfg.EnvVar{
|
||||
{"PKG_CONFIG", b.pkgconfigCmd()},
|
||||
{"PKG_CONFIG", b.PkgconfigCmd()},
|
||||
{"CGO_CFLAGS", strings.Join(cflags, " ")},
|
||||
{"CGO_CPPFLAGS", strings.Join(cppflags, " ")},
|
||||
{"CGO_CXXFLAGS", strings.Join(cxxflags, " ")},
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
"cmd/go/internal/work"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@ -134,7 +135,7 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
addBuildFlags(cmdGenerate)
|
||||
work.AddBuildFlags(cmdGenerate)
|
||||
cmdGenerate.Flag.StringVar(&generateRunFlag, "run", "", "")
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
"cmd/go/internal/str"
|
||||
"cmd/go/internal/work"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"os"
|
||||
@ -83,7 +84,7 @@ var getFix = cmdGet.Flag.Bool("fix", false, "")
|
||||
var getInsecure = cmdGet.Flag.Bool("insecure", false, "")
|
||||
|
||||
func init() {
|
||||
addBuildFlags(cmdGet)
|
||||
work.AddBuildFlags(cmdGet)
|
||||
cmdGet.Run = runGet // break init loop
|
||||
}
|
||||
|
||||
@ -157,7 +158,7 @@ func runGet(cmd *base.Command, args []string) {
|
||||
return
|
||||
}
|
||||
|
||||
installPackages(args, true)
|
||||
work.InstallPackages(args, true)
|
||||
}
|
||||
|
||||
// downloadPaths prepares the list of paths to pass to download.
|
||||
|
37
src/cmd/go/internal/base/env.go
Normal file
37
src/cmd/go/internal/base/env.go
Normal file
@ -0,0 +1,37 @@
|
||||
// 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 "strings"
|
||||
|
||||
// envForDir returns a copy of the environment
|
||||
// suitable for running in the given directory.
|
||||
// The environment is the current process's environment
|
||||
// but with an updated $PWD, so that an os.Getwd in the
|
||||
// child will be faster.
|
||||
func EnvForDir(dir string, base []string) []string {
|
||||
// Internally we only use rooted paths, so dir is rooted.
|
||||
// Even if dir is not rooted, no harm done.
|
||||
return MergeEnvLists([]string{"PWD=" + dir}, base)
|
||||
}
|
||||
|
||||
// MergeEnvLists merges the two environment lists such that
|
||||
// variables with the same name in "in" replace those in "out".
|
||||
// This always returns a newly allocated slice.
|
||||
func MergeEnvLists(in, out []string) []string {
|
||||
out = append([]string(nil), out...)
|
||||
NextVar:
|
||||
for _, inkv := range in {
|
||||
k := strings.SplitAfterN(inkv, "=", 2)[0]
|
||||
for i, outkv := range out {
|
||||
if strings.HasPrefix(outkv, k) {
|
||||
out[i] = inkv
|
||||
continue NextVar
|
||||
}
|
||||
}
|
||||
out = append(out, inkv)
|
||||
}
|
||||
return out
|
||||
}
|
33
src/cmd/go/internal/base/flag.go
Normal file
33
src/cmd/go/internal/base/flag.go
Normal file
@ -0,0 +1,33 @@
|
||||
// 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 (
|
||||
"cmd/go/internal/str"
|
||||
"flag"
|
||||
)
|
||||
|
||||
// A StringsFlag is a command-line flag that interprets its argument
|
||||
// as a space-separated list of possibly-quoted strings.
|
||||
type StringsFlag []string
|
||||
|
||||
func (v *StringsFlag) Set(s string) error {
|
||||
var err error
|
||||
*v, err = str.SplitQuotedFields(s)
|
||||
if *v == nil {
|
||||
*v = []string{}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (v *StringsFlag) String() string {
|
||||
return "<StringsFlag>"
|
||||
}
|
||||
|
||||
// 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, "")
|
||||
}
|
@ -7,6 +7,7 @@ package base
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var Cwd, _ = os.Getwd()
|
||||
@ -34,3 +35,10 @@ func RelPaths(paths []string) []string {
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// IsTestFile reports whether the source file is a set of tests and should therefore
|
||||
// be excluded from coverage analysis.
|
||||
func IsTestFile(file string) bool {
|
||||
// We don't cover tests, only the code they test.
|
||||
return strings.HasSuffix(file, "_test.go")
|
||||
}
|
||||
|
@ -95,3 +95,47 @@ func Contains(x []string, s string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isSpaceByte(c byte) bool {
|
||||
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
|
||||
}
|
||||
|
||||
// SplitQuotedFields splits s into a list of fields,
|
||||
// allowing single or double quotes around elements.
|
||||
// There is no unescaping or other processing within
|
||||
// quoted fields.
|
||||
func SplitQuotedFields(s string) ([]string, error) {
|
||||
// Split fields allowing '' or "" around elements.
|
||||
// Quotes further inside the string do not count.
|
||||
var f []string
|
||||
for len(s) > 0 {
|
||||
for len(s) > 0 && isSpaceByte(s[0]) {
|
||||
s = s[1:]
|
||||
}
|
||||
if len(s) == 0 {
|
||||
break
|
||||
}
|
||||
// Accepted quoted string. No unescaping inside.
|
||||
if s[0] == '"' || s[0] == '\'' {
|
||||
quote := s[0]
|
||||
s = s[1:]
|
||||
i := 0
|
||||
for i < len(s) && s[i] != quote {
|
||||
i++
|
||||
}
|
||||
if i >= len(s) {
|
||||
return nil, fmt.Errorf("unterminated %c string", quote)
|
||||
}
|
||||
f = append(f, s[:i])
|
||||
s = s[i+1:]
|
||||
continue
|
||||
}
|
||||
i := 0
|
||||
for i < len(s) && !isSpaceByte(s[i]) {
|
||||
i++
|
||||
}
|
||||
f = append(f, s[:i])
|
||||
s = s[i:]
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
167
src/cmd/go/internal/work/build_test.go
Normal file
167
src/cmd/go/internal/work/build_test.go
Normal file
@ -0,0 +1,167 @@
|
||||
// Copyright 2016 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 work
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
)
|
||||
|
||||
func TestRemoveDevNull(t *testing.T) {
|
||||
fi, err := os.Lstat(os.DevNull)
|
||||
if err != nil {
|
||||
t.Skip(err)
|
||||
}
|
||||
if fi.Mode().IsRegular() {
|
||||
t.Errorf("Lstat(%s).Mode().IsRegular() = true; expected false", os.DevNull)
|
||||
}
|
||||
mayberemovefile(os.DevNull)
|
||||
_, err = os.Lstat(os.DevNull)
|
||||
if err != nil {
|
||||
t.Errorf("mayberemovefile(%s) did remove it; oops", os.DevNull)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitPkgConfigOutput(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
in []byte
|
||||
want []string
|
||||
}{
|
||||
{[]byte(`-r:foo -L/usr/white\ space/lib -lfoo\ bar -lbar\ baz`), []string{"-r:foo", "-L/usr/white space/lib", "-lfoo bar", "-lbar baz"}},
|
||||
{[]byte(`-lextra\ fun\ arg\\`), []string{`-lextra fun arg\`}},
|
||||
{[]byte(`broken flag\`), []string{"broken", "flag"}},
|
||||
{[]byte("\textra whitespace\r\n"), []string{"extra", "whitespace"}},
|
||||
{[]byte(" \r\n "), nil},
|
||||
} {
|
||||
got := splitPkgConfigOutput(test.in)
|
||||
if !reflect.DeepEqual(got, test.want) {
|
||||
t.Errorf("splitPkgConfigOutput(%v) = %v; want %v", test.in, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSharedLibName(t *testing.T) {
|
||||
// TODO(avdva) - make these values platform-specific
|
||||
prefix := "lib"
|
||||
suffix := ".so"
|
||||
testData := []struct {
|
||||
args []string
|
||||
pkgs []*load.Package
|
||||
expected string
|
||||
expectErr bool
|
||||
rootedAt string
|
||||
}{
|
||||
{
|
||||
args: []string{"std"},
|
||||
pkgs: []*load.Package{},
|
||||
expected: "std",
|
||||
},
|
||||
{
|
||||
args: []string{"std", "cmd"},
|
||||
pkgs: []*load.Package{},
|
||||
expected: "std,cmd",
|
||||
},
|
||||
{
|
||||
args: []string{},
|
||||
pkgs: []*load.Package{pkgImportPath("gopkg.in/somelib")},
|
||||
expected: "gopkg.in-somelib",
|
||||
},
|
||||
{
|
||||
args: []string{"./..."},
|
||||
pkgs: []*load.Package{pkgImportPath("somelib")},
|
||||
expected: "somelib",
|
||||
rootedAt: "somelib",
|
||||
},
|
||||
{
|
||||
args: []string{"../somelib", "../somelib"},
|
||||
pkgs: []*load.Package{pkgImportPath("somelib")},
|
||||
expected: "somelib",
|
||||
},
|
||||
{
|
||||
args: []string{"../lib1", "../lib2"},
|
||||
pkgs: []*load.Package{pkgImportPath("gopkg.in/lib1"), pkgImportPath("gopkg.in/lib2")},
|
||||
expected: "gopkg.in-lib1,gopkg.in-lib2",
|
||||
},
|
||||
{
|
||||
args: []string{"./..."},
|
||||
pkgs: []*load.Package{
|
||||
pkgImportPath("gopkg.in/dir/lib1"),
|
||||
pkgImportPath("gopkg.in/lib2"),
|
||||
pkgImportPath("gopkg.in/lib3"),
|
||||
},
|
||||
expected: "gopkg.in",
|
||||
rootedAt: "gopkg.in",
|
||||
},
|
||||
{
|
||||
args: []string{"std", "../lib2"},
|
||||
pkgs: []*load.Package{},
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
args: []string{"all", "./"},
|
||||
pkgs: []*load.Package{},
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
args: []string{"cmd", "fmt"},
|
||||
pkgs: []*load.Package{},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
for _, data := range testData {
|
||||
func() {
|
||||
if data.rootedAt != "" {
|
||||
tmpGopath, err := ioutil.TempDir("", "gopath")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
oldGopath := cfg.BuildContext.GOPATH
|
||||
defer func() {
|
||||
cfg.BuildContext.GOPATH = oldGopath
|
||||
os.Chdir(base.Cwd)
|
||||
err := os.RemoveAll(tmpGopath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}()
|
||||
root := filepath.Join(tmpGopath, "src", data.rootedAt)
|
||||
err = os.MkdirAll(root, 0755)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cfg.BuildContext.GOPATH = tmpGopath
|
||||
os.Chdir(root)
|
||||
}
|
||||
computed, err := libname(data.args, data.pkgs)
|
||||
if err != nil {
|
||||
if !data.expectErr {
|
||||
t.Errorf("libname returned an error %q, expected a name", err.Error())
|
||||
}
|
||||
} else if data.expectErr {
|
||||
t.Errorf("libname returned %q, expected an error", computed)
|
||||
} else {
|
||||
expected := prefix + data.expected + suffix
|
||||
if expected != computed {
|
||||
t.Errorf("libname returned %q, expected %q", computed, expected)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func pkgImportPath(pkgpath string) *load.Package {
|
||||
return &load.Package{
|
||||
PackagePublic: load.PackagePublic{
|
||||
ImportPath: pkgpath,
|
||||
},
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import (
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
"cmd/go/internal/work"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
@ -140,7 +141,7 @@ For more about specifying packages, see 'go help packages'.
|
||||
|
||||
func init() {
|
||||
cmdList.Run = runList // break init cycle
|
||||
addBuildFlags(cmdList)
|
||||
work.AddBuildFlags(cmdList)
|
||||
}
|
||||
|
||||
var listE = cmdList.Flag.Bool("e", false, "")
|
||||
@ -149,7 +150,7 @@ var listJson = cmdList.Flag.Bool("json", false, "")
|
||||
var nl = []byte{'\n'}
|
||||
|
||||
func runList(cmd *base.Command, args []string) {
|
||||
buildModeInit()
|
||||
work.BuildModeInit()
|
||||
out := newTrackingWriter(os.Stdout)
|
||||
defer out.w.Flush()
|
||||
|
||||
|
@ -16,11 +16,12 @@ import (
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/help"
|
||||
"cmd/go/internal/work"
|
||||
)
|
||||
|
||||
func init() {
|
||||
base.Commands = []*base.Command{
|
||||
cmdBuild,
|
||||
work.CmdBuild,
|
||||
cmdClean,
|
||||
cmdDoc,
|
||||
cmdEnv,
|
||||
@ -29,7 +30,7 @@ func init() {
|
||||
cmdFmt,
|
||||
cmdGenerate,
|
||||
cmdGet,
|
||||
cmdInstall,
|
||||
work.CmdInstall,
|
||||
cmdList,
|
||||
cmdRun,
|
||||
cmdTest,
|
||||
|
@ -5,13 +5,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
"cmd/go/internal/str"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
@ -95,112 +90,3 @@ func pkgImportPath(path string) *load.Package {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestSharedLibName(t *testing.T) {
|
||||
// TODO(avdva) - make these values platform-specific
|
||||
prefix := "lib"
|
||||
suffix := ".so"
|
||||
testData := []struct {
|
||||
args []string
|
||||
pkgs []*load.Package
|
||||
expected string
|
||||
expectErr bool
|
||||
rootedAt string
|
||||
}{
|
||||
{
|
||||
args: []string{"std"},
|
||||
pkgs: []*load.Package{},
|
||||
expected: "std",
|
||||
},
|
||||
{
|
||||
args: []string{"std", "cmd"},
|
||||
pkgs: []*load.Package{},
|
||||
expected: "std,cmd",
|
||||
},
|
||||
{
|
||||
args: []string{},
|
||||
pkgs: []*load.Package{pkgImportPath("gopkg.in/somelib")},
|
||||
expected: "gopkg.in-somelib",
|
||||
},
|
||||
{
|
||||
args: []string{"./..."},
|
||||
pkgs: []*load.Package{pkgImportPath("somelib")},
|
||||
expected: "somelib",
|
||||
rootedAt: "somelib",
|
||||
},
|
||||
{
|
||||
args: []string{"../somelib", "../somelib"},
|
||||
pkgs: []*load.Package{pkgImportPath("somelib")},
|
||||
expected: "somelib",
|
||||
},
|
||||
{
|
||||
args: []string{"../lib1", "../lib2"},
|
||||
pkgs: []*load.Package{pkgImportPath("gopkg.in/lib1"), pkgImportPath("gopkg.in/lib2")},
|
||||
expected: "gopkg.in-lib1,gopkg.in-lib2",
|
||||
},
|
||||
{
|
||||
args: []string{"./..."},
|
||||
pkgs: []*load.Package{
|
||||
pkgImportPath("gopkg.in/dir/lib1"),
|
||||
pkgImportPath("gopkg.in/lib2"),
|
||||
pkgImportPath("gopkg.in/lib3"),
|
||||
},
|
||||
expected: "gopkg.in",
|
||||
rootedAt: "gopkg.in",
|
||||
},
|
||||
{
|
||||
args: []string{"std", "../lib2"},
|
||||
pkgs: []*load.Package{},
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
args: []string{"all", "./"},
|
||||
pkgs: []*load.Package{},
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
args: []string{"cmd", "fmt"},
|
||||
pkgs: []*load.Package{},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
for _, data := range testData {
|
||||
func() {
|
||||
if data.rootedAt != "" {
|
||||
tmpGopath, err := ioutil.TempDir("", "gopath")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
oldGopath := cfg.BuildContext.GOPATH
|
||||
defer func() {
|
||||
cfg.BuildContext.GOPATH = oldGopath
|
||||
os.Chdir(base.Cwd)
|
||||
err := os.RemoveAll(tmpGopath)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}()
|
||||
root := filepath.Join(tmpGopath, "src", data.rootedAt)
|
||||
err = os.MkdirAll(root, 0755)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cfg.BuildContext.GOPATH = tmpGopath
|
||||
os.Chdir(root)
|
||||
}
|
||||
computed, err := libname(data.args, data.pkgs)
|
||||
if err != nil {
|
||||
if !data.expectErr {
|
||||
t.Errorf("libname returned an error %q, expected a name", err.Error())
|
||||
}
|
||||
} else if data.expectErr {
|
||||
t.Errorf("libname returned %q, expected an error", computed)
|
||||
} else {
|
||||
expected := prefix + data.expected + suffix
|
||||
if expected != computed {
|
||||
t.Errorf("libname returned %q, expected %q", computed, expected)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
@ -5,15 +5,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
"cmd/go/internal/str"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
"cmd/go/internal/str"
|
||||
"cmd/go/internal/work"
|
||||
)
|
||||
|
||||
var execCmd []string // -exec flag, for run and test
|
||||
@ -59,8 +61,8 @@ See also: go build.
|
||||
func init() {
|
||||
cmdRun.Run = runRun // break init loop
|
||||
|
||||
addBuildFlags(cmdRun)
|
||||
cmdRun.Flag.Var((*stringsFlag)(&execCmd), "exec", "")
|
||||
work.AddBuildFlags(cmdRun)
|
||||
cmdRun.Flag.Var((*base.StringsFlag)(&execCmd), "exec", "")
|
||||
}
|
||||
|
||||
func printStderr(args ...interface{}) (int, error) {
|
||||
@ -68,11 +70,11 @@ func printStderr(args ...interface{}) (int, error) {
|
||||
}
|
||||
|
||||
func runRun(cmd *base.Command, args []string) {
|
||||
instrumentInit()
|
||||
buildModeInit()
|
||||
var b builder
|
||||
b.init()
|
||||
b.print = printStderr
|
||||
work.InstrumentInit()
|
||||
work.BuildModeInit()
|
||||
var b work.Builder
|
||||
b.Init()
|
||||
b.Print = printStderr
|
||||
i := 0
|
||||
for i < len(args) && strings.HasSuffix(args[i], ".go") {
|
||||
i++
|
||||
@ -126,17 +128,17 @@ func runRun(cmd *base.Command, args []string) {
|
||||
base.Fatalf("go run: no suitable source files%s", hint)
|
||||
}
|
||||
p.Internal.ExeName = src[:len(src)-len(".go")] // name temporary executable for first go file
|
||||
a1 := b.action(modeBuild, modeBuild, p)
|
||||
a := &action{f: (*builder).runProgram, args: cmdArgs, deps: []*action{a1}}
|
||||
b.do(a)
|
||||
a1 := b.Action(work.ModeBuild, work.ModeBuild, p)
|
||||
a := &work.Action{Func: buildRunProgram, Args: cmdArgs, Deps: []*work.Action{a1}}
|
||||
b.Do(a)
|
||||
}
|
||||
|
||||
// runProgram is the action for running a binary that has already
|
||||
// buildRunProgram is the action for running a binary that has already
|
||||
// been compiled. We ignore exit status.
|
||||
func (b *builder) runProgram(a *action) error {
|
||||
cmdline := str.StringList(findExecCmd(), a.deps[0].target, a.args)
|
||||
func buildRunProgram(b *work.Builder, a *work.Action) error {
|
||||
cmdline := str.StringList(findExecCmd(), a.Deps[0].Target, a.Args)
|
||||
if cfg.BuildN || cfg.BuildX {
|
||||
b.showcmd("", "%s", strings.Join(cmdline, " "))
|
||||
b.Showcmd("", "%s", strings.Join(cmdline, " "))
|
||||
if cfg.BuildN {
|
||||
return nil
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
"cmd/go/internal/str"
|
||||
"cmd/go/internal/work"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
@ -409,8 +410,8 @@ func runTest(cmd *base.Command, args []string) {
|
||||
|
||||
findExecCmd() // initialize cached result
|
||||
|
||||
instrumentInit()
|
||||
buildModeInit()
|
||||
work.InstrumentInit()
|
||||
work.BuildModeInit()
|
||||
pkgs := load.PackagesForBuild(pkgArgs)
|
||||
if len(pkgs) == 0 {
|
||||
base.Fatalf("no packages to test")
|
||||
@ -454,8 +455,8 @@ func runTest(cmd *base.Command, args []string) {
|
||||
testC = true
|
||||
}
|
||||
|
||||
var b builder
|
||||
b.init()
|
||||
var b work.Builder
|
||||
b.Init()
|
||||
|
||||
if cfg.BuildI {
|
||||
cfg.BuildV = testV
|
||||
@ -497,18 +498,18 @@ func runTest(cmd *base.Command, args []string) {
|
||||
}
|
||||
sort.Strings(all)
|
||||
|
||||
a := &action{}
|
||||
a := &work.Action{}
|
||||
for _, p := range load.PackagesForBuild(all) {
|
||||
a.deps = append(a.deps, b.action(modeInstall, modeInstall, p))
|
||||
a.Deps = append(a.Deps, b.Action(work.ModeInstall, work.ModeInstall, p))
|
||||
}
|
||||
b.do(a)
|
||||
if !testC || a.failed {
|
||||
b.Do(a)
|
||||
if !testC || a.Failed {
|
||||
return
|
||||
}
|
||||
b.init()
|
||||
b.Init()
|
||||
}
|
||||
|
||||
var builds, runs, prints []*action
|
||||
var builds, runs, prints []*work.Action
|
||||
|
||||
if testCoverPaths != nil {
|
||||
// Load packages that were asked about for coverage.
|
||||
@ -570,13 +571,13 @@ func runTest(cmd *base.Command, args []string) {
|
||||
}
|
||||
|
||||
// Ultimately the goal is to print the output.
|
||||
root := &action{deps: prints}
|
||||
root := &work.Action{Deps: prints}
|
||||
|
||||
// Force the printing of results to happen in order,
|
||||
// one at a time.
|
||||
for i, a := range prints {
|
||||
if i > 0 {
|
||||
a.deps = append(a.deps, prints[i-1])
|
||||
a.Deps = append(a.Deps, prints[i-1])
|
||||
}
|
||||
}
|
||||
|
||||
@ -586,9 +587,9 @@ func runTest(cmd *base.Command, args []string) {
|
||||
// Later runs must wait for the previous run's print.
|
||||
for i, run := range runs {
|
||||
if i == 0 {
|
||||
run.deps = append(run.deps, builds...)
|
||||
run.Deps = append(run.Deps, builds...)
|
||||
} else {
|
||||
run.deps = append(run.deps, prints[i-1])
|
||||
run.Deps = append(run.Deps, prints[i-1])
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -600,26 +601,26 @@ func runTest(cmd *base.Command, args []string) {
|
||||
okBuild[p] = true
|
||||
}
|
||||
warned := false
|
||||
for _, a := range actionList(root) {
|
||||
if a.p == nil || okBuild[a.p] {
|
||||
for _, a := range work.ActionList(root) {
|
||||
if a.Package == nil || okBuild[a.Package] {
|
||||
continue
|
||||
}
|
||||
okBuild[a.p] = true // warn at most once
|
||||
okBuild[a.Package] = true // warn at most once
|
||||
|
||||
// Don't warn about packages being rebuilt because of
|
||||
// things like coverage analysis.
|
||||
for _, p1 := range a.p.Internal.Imports {
|
||||
for _, p1 := range a.Package.Internal.Imports {
|
||||
if p1.Internal.Fake {
|
||||
a.p.Internal.Fake = true
|
||||
a.Package.Internal.Fake = true
|
||||
}
|
||||
}
|
||||
|
||||
if a.f != nil && !okBuild[a.p] && !a.p.Internal.Fake && !a.p.Internal.Local {
|
||||
if a.Func != nil && !okBuild[a.Package] && !a.Package.Internal.Fake && !a.Package.Internal.Local {
|
||||
if !warned {
|
||||
fmt.Fprintf(os.Stderr, "warning: building out-of-date packages:\n")
|
||||
warned = true
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "\t%s\n", a.p.ImportPath)
|
||||
fmt.Fprintf(os.Stderr, "\t%s\n", a.Package.ImportPath)
|
||||
}
|
||||
}
|
||||
if warned {
|
||||
@ -637,7 +638,7 @@ func runTest(cmd *base.Command, args []string) {
|
||||
fmt.Fprintf(os.Stderr, "installing these packages with 'go test %s-i%s' will speed future tests.\n\n", extraOpts, args)
|
||||
}
|
||||
|
||||
b.do(root)
|
||||
b.Do(root)
|
||||
}
|
||||
|
||||
var windowsBadWords = []string{
|
||||
@ -647,11 +648,11 @@ var windowsBadWords = []string{
|
||||
"update",
|
||||
}
|
||||
|
||||
func builderTest(b *builder, p *load.Package) (buildAction, runAction, printAction *action, err error) {
|
||||
func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) {
|
||||
if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
|
||||
build := b.action(modeBuild, modeBuild, p)
|
||||
run := &action{p: p, deps: []*action{build}}
|
||||
print := &action{f: builderNoTest, p: p, deps: []*action{run}}
|
||||
build := b.Action(work.ModeBuild, work.ModeBuild, p)
|
||||
run := &work.Action{Package: p, Deps: []*work.Action{build}}
|
||||
print := &work.Action{Func: builderNoTest, Package: p, Deps: []*work.Action{run}}
|
||||
return build, run, print, nil
|
||||
}
|
||||
|
||||
@ -736,12 +737,12 @@ func builderTest(b *builder, p *load.Package) (buildAction, runAction, printActi
|
||||
// $WORK/unicode/utf8/_test/unicode/utf8.a.
|
||||
// We write the external test package archive to
|
||||
// $WORK/unicode/utf8/_test/unicode/utf8_test.a.
|
||||
testDir := filepath.Join(b.work, filepath.FromSlash(p.ImportPath+"/_test"))
|
||||
ptestObj := buildToolchain.pkgpath(testDir, p)
|
||||
testDir := filepath.Join(b.WorkDir, filepath.FromSlash(p.ImportPath+"/_test"))
|
||||
ptestObj := work.BuildToolchain.Pkgpath(testDir, p)
|
||||
|
||||
// Create the directory for the .a files.
|
||||
ptestDir, _ := filepath.Split(ptestObj)
|
||||
if err := b.mkdir(ptestDir); err != nil {
|
||||
if err := b.Mkdir(ptestDir); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
@ -898,7 +899,7 @@ func builderTest(b *builder, p *load.Package) (buildAction, runAction, printActi
|
||||
if cfg.BuildContext.GOOS == "darwin" {
|
||||
if cfg.BuildContext.GOARCH == "arm" || cfg.BuildContext.GOARCH == "arm64" {
|
||||
t.IsIOS = true
|
||||
t.NeedCgo = true
|
||||
t.NeedOS = true
|
||||
}
|
||||
}
|
||||
if t.TestMain == nil {
|
||||
@ -922,24 +923,24 @@ func builderTest(b *builder, p *load.Package) (buildAction, runAction, printActi
|
||||
load.ComputeStale(pmain)
|
||||
|
||||
if ptest != p {
|
||||
a := b.action(modeBuild, modeBuild, ptest)
|
||||
a.objdir = testDir + string(filepath.Separator) + "_obj_test" + string(filepath.Separator)
|
||||
a.objpkg = ptestObj
|
||||
a.target = ptestObj
|
||||
a.link = false
|
||||
a := b.Action(work.ModeBuild, work.ModeBuild, ptest)
|
||||
a.Objdir = testDir + string(filepath.Separator) + "_obj_test" + string(filepath.Separator)
|
||||
a.Objpkg = ptestObj
|
||||
a.Target = ptestObj
|
||||
a.Link = false
|
||||
}
|
||||
|
||||
if pxtest != nil {
|
||||
a := b.action(modeBuild, modeBuild, pxtest)
|
||||
a.objdir = testDir + string(filepath.Separator) + "_obj_xtest" + string(filepath.Separator)
|
||||
a.objpkg = buildToolchain.pkgpath(testDir, pxtest)
|
||||
a.target = a.objpkg
|
||||
a := b.Action(work.ModeBuild, work.ModeBuild, pxtest)
|
||||
a.Objdir = testDir + string(filepath.Separator) + "_obj_xtest" + string(filepath.Separator)
|
||||
a.Objpkg = work.BuildToolchain.Pkgpath(testDir, pxtest)
|
||||
a.Target = a.Objpkg
|
||||
}
|
||||
|
||||
a := b.action(modeBuild, modeBuild, pmain)
|
||||
a.objdir = testDir + string(filepath.Separator)
|
||||
a.objpkg = filepath.Join(testDir, "main.a")
|
||||
a.target = filepath.Join(testDir, testBinary) + cfg.ExeSuffix
|
||||
a := b.Action(work.ModeBuild, work.ModeBuild, pmain)
|
||||
a.Objdir = testDir + string(filepath.Separator)
|
||||
a.Objpkg = filepath.Join(testDir, "main.a")
|
||||
a.Target = filepath.Join(testDir, testBinary) + cfg.ExeSuffix
|
||||
if cfg.Goos == "windows" {
|
||||
// There are many reserved words on Windows that,
|
||||
// if used in the name of an executable, cause Windows
|
||||
@ -965,7 +966,7 @@ func builderTest(b *builder, p *load.Package) (buildAction, runAction, printActi
|
||||
// we could just do this always on Windows.
|
||||
for _, bad := range windowsBadWords {
|
||||
if strings.Contains(testBinary, bad) {
|
||||
a.target = filepath.Join(testDir, "test.test") + cfg.ExeSuffix
|
||||
a.Target = filepath.Join(testDir, "test.test") + cfg.ExeSuffix
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -981,33 +982,33 @@ func builderTest(b *builder, p *load.Package) (buildAction, runAction, printActi
|
||||
target = filepath.Join(base.Cwd, target)
|
||||
}
|
||||
}
|
||||
buildAction = &action{
|
||||
f: (*builder).install,
|
||||
deps: []*action{buildAction},
|
||||
p: pmain,
|
||||
target: target,
|
||||
buildAction = &work.Action{
|
||||
Func: work.BuildInstallFunc,
|
||||
Deps: []*work.Action{buildAction},
|
||||
Package: pmain,
|
||||
Target: target,
|
||||
}
|
||||
runAction = buildAction // make sure runAction != nil even if not running test
|
||||
}
|
||||
if testC {
|
||||
printAction = &action{p: p, deps: []*action{runAction}} // nop
|
||||
printAction = &work.Action{Package: p, Deps: []*work.Action{runAction}} // nop
|
||||
} else {
|
||||
// run test
|
||||
runAction = &action{
|
||||
f: builderRunTest,
|
||||
deps: []*action{buildAction},
|
||||
p: p,
|
||||
ignoreFail: true,
|
||||
runAction = &work.Action{
|
||||
Func: builderRunTest,
|
||||
Deps: []*work.Action{buildAction},
|
||||
Package: p,
|
||||
IgnoreFail: true,
|
||||
}
|
||||
cleanAction := &action{
|
||||
f: builderCleanTest,
|
||||
deps: []*action{runAction},
|
||||
p: p,
|
||||
cleanAction := &work.Action{
|
||||
Func: builderCleanTest,
|
||||
Deps: []*work.Action{runAction},
|
||||
Package: p,
|
||||
}
|
||||
printAction = &action{
|
||||
f: builderPrintTest,
|
||||
deps: []*action{cleanAction},
|
||||
p: p,
|
||||
printAction = &work.Action{
|
||||
Func: builderPrintTest,
|
||||
Deps: []*work.Action{cleanAction},
|
||||
Package: p,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1060,7 +1061,7 @@ func recompileForTest(pmain, preal, ptest *load.Package, testDir string) {
|
||||
}
|
||||
}
|
||||
|
||||
// Update p.deps and p.Internal.Imports to use at test copies.
|
||||
// Update p.Deps and p.Internal.Imports to use at test copies.
|
||||
for i, dep := range p.Internal.Deps {
|
||||
if p1 := testCopy[dep]; p1 != nil && p1 != dep {
|
||||
split()
|
||||
@ -1105,27 +1106,27 @@ func declareCoverVars(importPath string, files ...string) map[string]*load.Cover
|
||||
var noTestsToRun = []byte("\ntesting: warning: no tests to run\n")
|
||||
|
||||
// builderRunTest is the action for running a test binary.
|
||||
func builderRunTest(b *builder, a *action) error {
|
||||
args := str.StringList(findExecCmd(), a.deps[0].target, testArgs)
|
||||
a.testOutput = new(bytes.Buffer)
|
||||
func builderRunTest(b *work.Builder, a *work.Action) error {
|
||||
args := str.StringList(findExecCmd(), a.Deps[0].Target, testArgs)
|
||||
a.TestOutput = new(bytes.Buffer)
|
||||
|
||||
if cfg.BuildN || cfg.BuildX {
|
||||
b.showcmd("", "%s", strings.Join(args, " "))
|
||||
b.Showcmd("", "%s", strings.Join(args, " "))
|
||||
if cfg.BuildN {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if a.failed {
|
||||
if a.Failed {
|
||||
// We were unable to build the binary.
|
||||
a.failed = false
|
||||
fmt.Fprintf(a.testOutput, "FAIL\t%s [build failed]\n", a.p.ImportPath)
|
||||
a.Failed = false
|
||||
fmt.Fprintf(a.TestOutput, "FAIL\t%s [build failed]\n", a.Package.ImportPath)
|
||||
base.SetExitStatus(1)
|
||||
return nil
|
||||
}
|
||||
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
cmd.Dir = a.p.Dir
|
||||
cmd.Dir = a.Package.Dir
|
||||
cmd.Env = envForDir(cmd.Dir, cfg.OrigEnv)
|
||||
var buf bytes.Buffer
|
||||
if testStreamOutput {
|
||||
@ -1138,7 +1139,7 @@ func builderRunTest(b *builder, a *action) error {
|
||||
|
||||
// If there are any local SWIG dependencies, we want to load
|
||||
// the shared library from the build directory.
|
||||
if a.p.UsesSwig() {
|
||||
if a.Package.UsesSwig() {
|
||||
env := cmd.Env
|
||||
found := false
|
||||
prefix := "LD_LIBRARY_PATH="
|
||||
@ -1196,23 +1197,23 @@ func builderRunTest(b *builder, a *action) error {
|
||||
if err == nil {
|
||||
norun := ""
|
||||
if testShowPass {
|
||||
a.testOutput.Write(out)
|
||||
a.TestOutput.Write(out)
|
||||
}
|
||||
if bytes.HasPrefix(out, noTestsToRun[1:]) || bytes.Contains(out, noTestsToRun) {
|
||||
norun = " [no tests to run]"
|
||||
}
|
||||
fmt.Fprintf(a.testOutput, "ok \t%s\t%s%s%s\n", a.p.ImportPath, t, coveragePercentage(out), norun)
|
||||
fmt.Fprintf(a.TestOutput, "ok \t%s\t%s%s%s\n", a.Package.ImportPath, t, coveragePercentage(out), norun)
|
||||
return nil
|
||||
}
|
||||
|
||||
base.SetExitStatus(1)
|
||||
if len(out) > 0 {
|
||||
a.testOutput.Write(out)
|
||||
a.TestOutput.Write(out)
|
||||
// assume printing the test binary's exit status is superfluous
|
||||
} else {
|
||||
fmt.Fprintf(a.testOutput, "%s\n", err)
|
||||
fmt.Fprintf(a.TestOutput, "%s\n", err)
|
||||
}
|
||||
fmt.Fprintf(a.testOutput, "FAIL\t%s\t%s\n", a.p.ImportPath, t)
|
||||
fmt.Fprintf(a.TestOutput, "FAIL\t%s\t%s\n", a.Package.ImportPath, t)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1237,28 +1238,28 @@ func coveragePercentage(out []byte) string {
|
||||
}
|
||||
|
||||
// builderCleanTest is the action for cleaning up after a test.
|
||||
func builderCleanTest(b *builder, a *action) error {
|
||||
func builderCleanTest(b *work.Builder, a *work.Action) error {
|
||||
if cfg.BuildWork {
|
||||
return nil
|
||||
}
|
||||
run := a.deps[0]
|
||||
testDir := filepath.Join(b.work, filepath.FromSlash(run.p.ImportPath+"/_test"))
|
||||
run := a.Deps[0]
|
||||
testDir := filepath.Join(b.WorkDir, filepath.FromSlash(run.Package.ImportPath+"/_test"))
|
||||
os.RemoveAll(testDir)
|
||||
return nil
|
||||
}
|
||||
|
||||
// builderPrintTest is the action for printing a test result.
|
||||
func builderPrintTest(b *builder, a *action) error {
|
||||
clean := a.deps[0]
|
||||
run := clean.deps[0]
|
||||
os.Stdout.Write(run.testOutput.Bytes())
|
||||
run.testOutput = nil
|
||||
func builderPrintTest(b *work.Builder, a *work.Action) error {
|
||||
clean := a.Deps[0]
|
||||
run := clean.Deps[0]
|
||||
os.Stdout.Write(run.TestOutput.Bytes())
|
||||
run.TestOutput = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// builderNoTest is the action for testing a package with no test files.
|
||||
func builderNoTest(b *builder, a *action) error {
|
||||
fmt.Printf("? \t%s\t[no test files]\n", a.p.ImportPath)
|
||||
func builderNoTest(b *work.Builder, a *work.Action) error {
|
||||
fmt.Printf("? \t%s\t[no test files]\n", a.Package.ImportPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -5,13 +5,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/str"
|
||||
"cmd/go/internal/work"
|
||||
)
|
||||
|
||||
// The flag handling part of go test is large and distracting.
|
||||
@ -66,7 +69,7 @@ var testFlagDefn = []*testFlagSpec{
|
||||
// add build flags to testFlagDefn
|
||||
func init() {
|
||||
var cmd base.Command
|
||||
addBuildFlags(&cmd)
|
||||
work.AddBuildFlags(&cmd)
|
||||
cmd.Flag.VisitAll(func(f *flag.Flag) {
|
||||
if f.Name == "v" {
|
||||
// test overrides the build -v flag
|
||||
@ -144,7 +147,7 @@ func testFlags(args []string) (packageNames, passToTest []string) {
|
||||
testO = value
|
||||
testNeedBinary = true
|
||||
case "exec":
|
||||
execCmd, err = splitQuotedFields(value)
|
||||
execCmd, err = str.SplitQuotedFields(value)
|
||||
if err != nil {
|
||||
base.Fatalf("invalid flag argument for -%s: %v", f.name, err)
|
||||
}
|
||||
|
@ -11,10 +11,11 @@ import (
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/load"
|
||||
"cmd/go/internal/str"
|
||||
"cmd/go/internal/work"
|
||||
)
|
||||
|
||||
func init() {
|
||||
addBuildFlags(cmdVet)
|
||||
work.AddBuildFlags(cmdVet)
|
||||
}
|
||||
|
||||
var cmdVet = &base.Command{
|
||||
|
Loading…
Reference in New Issue
Block a user