mirror of
https://github.com/golang/go
synced 2024-10-01 13:18:33 -06: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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/go/internal/base"
|
|
||||||
"cmd/go/internal/cfg"
|
|
||||||
"cmd/go/internal/load"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"cmd/go/internal/base"
|
||||||
|
"cmd/go/internal/cfg"
|
||||||
|
"cmd/go/internal/load"
|
||||||
|
"cmd/go/internal/work"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cmdClean = &base.Command{
|
var cmdClean = &base.Command{
|
||||||
@ -74,7 +76,7 @@ func init() {
|
|||||||
// mentioned explicitly in the docs but they
|
// mentioned explicitly in the docs but they
|
||||||
// are part of the build flags.
|
// are part of the build flags.
|
||||||
|
|
||||||
addBuildFlags(cmdClean)
|
work.AddBuildFlags(cmdClean)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runClean(cmd *base.Command, args []string) {
|
func runClean(cmd *base.Command, args []string) {
|
||||||
@ -124,8 +126,8 @@ func clean(p *load.Package) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var b builder
|
var b work.Builder
|
||||||
b.print = fmt.Print
|
b.Print = fmt.Print
|
||||||
|
|
||||||
packageFile := map[string]bool{}
|
packageFile := map[string]bool{}
|
||||||
if p.Name != "main" {
|
if p.Name != "main" {
|
||||||
@ -176,7 +178,7 @@ func clean(p *load.Package) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cfg.BuildN || cfg.BuildX {
|
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{}
|
toRemove := map[string]bool{}
|
||||||
@ -189,7 +191,7 @@ func clean(p *load.Package) {
|
|||||||
// TODO: Remove once Makefiles are forgotten.
|
// TODO: Remove once Makefiles are forgotten.
|
||||||
if cleanDir[name] {
|
if cleanDir[name] {
|
||||||
if cfg.BuildN || cfg.BuildX {
|
if cfg.BuildN || cfg.BuildX {
|
||||||
b.showcmd(p.Dir, "rm -r %s", name)
|
b.Showcmd(p.Dir, "rm -r %s", name)
|
||||||
if cfg.BuildN {
|
if cfg.BuildN {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -212,7 +214,7 @@ func clean(p *load.Package) {
|
|||||||
|
|
||||||
if cleanI && p.Internal.Target != "" {
|
if cleanI && p.Internal.Target != "" {
|
||||||
if cfg.BuildN || cfg.BuildX {
|
if cfg.BuildN || cfg.BuildX {
|
||||||
b.showcmd("", "rm -f %s", p.Internal.Target)
|
b.Showcmd("", "rm -f %s", p.Internal.Target)
|
||||||
}
|
}
|
||||||
if !cfg.BuildN {
|
if !cfg.BuildN {
|
||||||
removeFile(p.Internal.Target)
|
removeFile(p.Internal.Target)
|
||||||
|
@ -5,13 +5,15 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/go/internal/base"
|
|
||||||
"cmd/go/internal/cfg"
|
|
||||||
"cmd/go/internal/load"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"cmd/go/internal/base"
|
||||||
|
"cmd/go/internal/cfg"
|
||||||
|
"cmd/go/internal/load"
|
||||||
|
"cmd/go/internal/work"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cmdEnv = &base.Command{
|
var cmdEnv = &base.Command{
|
||||||
@ -29,8 +31,8 @@ each named variable on its own line.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func mkEnv() []cfg.EnvVar {
|
func mkEnv() []cfg.EnvVar {
|
||||||
var b builder
|
var b work.Builder
|
||||||
b.init()
|
b.Init()
|
||||||
|
|
||||||
env := []cfg.EnvVar{
|
env := []cfg.EnvVar{
|
||||||
{"GOARCH", cfg.Goarch},
|
{"GOARCH", cfg.Goarch},
|
||||||
@ -48,10 +50,10 @@ func mkEnv() []cfg.EnvVar {
|
|||||||
{"TERM", "dumb"},
|
{"TERM", "dumb"},
|
||||||
}
|
}
|
||||||
|
|
||||||
if gccgoBin != "" {
|
if work.GccgoBin != "" {
|
||||||
env = append(env, cfg.EnvVar{"GCCGO", gccgoBin})
|
env = append(env, cfg.EnvVar{"GCCGO", work.GccgoBin})
|
||||||
} else {
|
} else {
|
||||||
env = append(env, cfg.EnvVar{"GCCGO", gccgoName})
|
env = append(env, cfg.EnvVar{"GCCGO", work.GccgoName})
|
||||||
}
|
}
|
||||||
|
|
||||||
switch cfg.Goarch {
|
switch cfg.Goarch {
|
||||||
@ -61,10 +63,10 @@ func mkEnv() []cfg.EnvVar {
|
|||||||
env = append(env, cfg.EnvVar{"GO386", os.Getenv("GO386")})
|
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{"CC", cmd[0]})
|
||||||
env = append(env, cfg.EnvVar{"GOGCCFLAGS", strings.Join(cmd[3:], " ")})
|
env = append(env, cfg.EnvVar{"GOGCCFLAGS", strings.Join(cmd[3:], " ")})
|
||||||
cmd = b.gxxCmd(".")
|
cmd = b.GxxCmd(".")
|
||||||
env = append(env, cfg.EnvVar{"CXX", cmd[0]})
|
env = append(env, cfg.EnvVar{"CXX", cmd[0]})
|
||||||
|
|
||||||
if cfg.BuildContext.CgoEnabled {
|
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.
|
// extraEnvVars returns environment variables that should not leak into child processes.
|
||||||
func extraEnvVars() []cfg.EnvVar {
|
func extraEnvVars() []cfg.EnvVar {
|
||||||
var b builder
|
var b work.Builder
|
||||||
b.init()
|
b.Init()
|
||||||
cppflags, cflags, cxxflags, fflags, ldflags := b.cflags(&load.Package{})
|
cppflags, cflags, cxxflags, fflags, ldflags := b.CFlags(&load.Package{})
|
||||||
return []cfg.EnvVar{
|
return []cfg.EnvVar{
|
||||||
{"PKG_CONFIG", b.pkgconfigCmd()},
|
{"PKG_CONFIG", b.PkgconfigCmd()},
|
||||||
{"CGO_CFLAGS", strings.Join(cflags, " ")},
|
{"CGO_CFLAGS", strings.Join(cflags, " ")},
|
||||||
{"CGO_CPPFLAGS", strings.Join(cppflags, " ")},
|
{"CGO_CPPFLAGS", strings.Join(cppflags, " ")},
|
||||||
{"CGO_CXXFLAGS", strings.Join(cxxflags, " ")},
|
{"CGO_CXXFLAGS", strings.Join(cxxflags, " ")},
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"cmd/go/internal/base"
|
"cmd/go/internal/base"
|
||||||
"cmd/go/internal/cfg"
|
"cmd/go/internal/cfg"
|
||||||
"cmd/go/internal/load"
|
"cmd/go/internal/load"
|
||||||
|
"cmd/go/internal/work"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
@ -134,7 +135,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
addBuildFlags(cmdGenerate)
|
work.AddBuildFlags(cmdGenerate)
|
||||||
cmdGenerate.Flag.StringVar(&generateRunFlag, "run", "", "")
|
cmdGenerate.Flag.StringVar(&generateRunFlag, "run", "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"cmd/go/internal/cfg"
|
"cmd/go/internal/cfg"
|
||||||
"cmd/go/internal/load"
|
"cmd/go/internal/load"
|
||||||
"cmd/go/internal/str"
|
"cmd/go/internal/str"
|
||||||
|
"cmd/go/internal/work"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/build"
|
"go/build"
|
||||||
"os"
|
"os"
|
||||||
@ -83,7 +84,7 @@ var getFix = cmdGet.Flag.Bool("fix", false, "")
|
|||||||
var getInsecure = cmdGet.Flag.Bool("insecure", false, "")
|
var getInsecure = cmdGet.Flag.Bool("insecure", false, "")
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
addBuildFlags(cmdGet)
|
work.AddBuildFlags(cmdGet)
|
||||||
cmdGet.Run = runGet // break init loop
|
cmdGet.Run = runGet // break init loop
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +158,7 @@ func runGet(cmd *base.Command, args []string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
installPackages(args, true)
|
work.InstallPackages(args, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// downloadPaths prepares the list of paths to pass to download.
|
// 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 (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Cwd, _ = os.Getwd()
|
var Cwd, _ = os.Getwd()
|
||||||
@ -34,3 +35,10 @@ func RelPaths(paths []string) []string {
|
|||||||
}
|
}
|
||||||
return out
|
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
|
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/base"
|
||||||
"cmd/go/internal/cfg"
|
"cmd/go/internal/cfg"
|
||||||
"cmd/go/internal/load"
|
"cmd/go/internal/load"
|
||||||
|
"cmd/go/internal/work"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@ -140,7 +141,7 @@ For more about specifying packages, see 'go help packages'.
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cmdList.Run = runList // break init cycle
|
cmdList.Run = runList // break init cycle
|
||||||
addBuildFlags(cmdList)
|
work.AddBuildFlags(cmdList)
|
||||||
}
|
}
|
||||||
|
|
||||||
var listE = cmdList.Flag.Bool("e", false, "")
|
var listE = cmdList.Flag.Bool("e", false, "")
|
||||||
@ -149,7 +150,7 @@ var listJson = cmdList.Flag.Bool("json", false, "")
|
|||||||
var nl = []byte{'\n'}
|
var nl = []byte{'\n'}
|
||||||
|
|
||||||
func runList(cmd *base.Command, args []string) {
|
func runList(cmd *base.Command, args []string) {
|
||||||
buildModeInit()
|
work.BuildModeInit()
|
||||||
out := newTrackingWriter(os.Stdout)
|
out := newTrackingWriter(os.Stdout)
|
||||||
defer out.w.Flush()
|
defer out.w.Flush()
|
||||||
|
|
||||||
|
@ -16,11 +16,12 @@ import (
|
|||||||
"cmd/go/internal/base"
|
"cmd/go/internal/base"
|
||||||
"cmd/go/internal/cfg"
|
"cmd/go/internal/cfg"
|
||||||
"cmd/go/internal/help"
|
"cmd/go/internal/help"
|
||||||
|
"cmd/go/internal/work"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
base.Commands = []*base.Command{
|
base.Commands = []*base.Command{
|
||||||
cmdBuild,
|
work.CmdBuild,
|
||||||
cmdClean,
|
cmdClean,
|
||||||
cmdDoc,
|
cmdDoc,
|
||||||
cmdEnv,
|
cmdEnv,
|
||||||
@ -29,7 +30,7 @@ func init() {
|
|||||||
cmdFmt,
|
cmdFmt,
|
||||||
cmdGenerate,
|
cmdGenerate,
|
||||||
cmdGet,
|
cmdGet,
|
||||||
cmdInstall,
|
work.CmdInstall,
|
||||||
cmdList,
|
cmdList,
|
||||||
cmdRun,
|
cmdRun,
|
||||||
cmdTest,
|
cmdTest,
|
||||||
|
@ -5,13 +5,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/go/internal/base"
|
|
||||||
"cmd/go/internal/cfg"
|
|
||||||
"cmd/go/internal/load"
|
"cmd/go/internal/load"
|
||||||
"cmd/go/internal/str"
|
"cmd/go/internal/str"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/go/internal/base"
|
|
||||||
"cmd/go/internal/cfg"
|
|
||||||
"cmd/go/internal/load"
|
|
||||||
"cmd/go/internal/str"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"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
|
var execCmd []string // -exec flag, for run and test
|
||||||
@ -59,8 +61,8 @@ See also: go build.
|
|||||||
func init() {
|
func init() {
|
||||||
cmdRun.Run = runRun // break init loop
|
cmdRun.Run = runRun // break init loop
|
||||||
|
|
||||||
addBuildFlags(cmdRun)
|
work.AddBuildFlags(cmdRun)
|
||||||
cmdRun.Flag.Var((*stringsFlag)(&execCmd), "exec", "")
|
cmdRun.Flag.Var((*base.StringsFlag)(&execCmd), "exec", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func printStderr(args ...interface{}) (int, error) {
|
func printStderr(args ...interface{}) (int, error) {
|
||||||
@ -68,11 +70,11 @@ func printStderr(args ...interface{}) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runRun(cmd *base.Command, args []string) {
|
func runRun(cmd *base.Command, args []string) {
|
||||||
instrumentInit()
|
work.InstrumentInit()
|
||||||
buildModeInit()
|
work.BuildModeInit()
|
||||||
var b builder
|
var b work.Builder
|
||||||
b.init()
|
b.Init()
|
||||||
b.print = printStderr
|
b.Print = printStderr
|
||||||
i := 0
|
i := 0
|
||||||
for i < len(args) && strings.HasSuffix(args[i], ".go") {
|
for i < len(args) && strings.HasSuffix(args[i], ".go") {
|
||||||
i++
|
i++
|
||||||
@ -126,17 +128,17 @@ func runRun(cmd *base.Command, args []string) {
|
|||||||
base.Fatalf("go run: no suitable source files%s", hint)
|
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
|
p.Internal.ExeName = src[:len(src)-len(".go")] // name temporary executable for first go file
|
||||||
a1 := b.action(modeBuild, modeBuild, p)
|
a1 := b.Action(work.ModeBuild, work.ModeBuild, p)
|
||||||
a := &action{f: (*builder).runProgram, args: cmdArgs, deps: []*action{a1}}
|
a := &work.Action{Func: buildRunProgram, Args: cmdArgs, Deps: []*work.Action{a1}}
|
||||||
b.do(a)
|
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.
|
// been compiled. We ignore exit status.
|
||||||
func (b *builder) runProgram(a *action) error {
|
func buildRunProgram(b *work.Builder, a *work.Action) error {
|
||||||
cmdline := str.StringList(findExecCmd(), a.deps[0].target, a.args)
|
cmdline := str.StringList(findExecCmd(), a.Deps[0].Target, a.Args)
|
||||||
if cfg.BuildN || cfg.BuildX {
|
if cfg.BuildN || cfg.BuildX {
|
||||||
b.showcmd("", "%s", strings.Join(cmdline, " "))
|
b.Showcmd("", "%s", strings.Join(cmdline, " "))
|
||||||
if cfg.BuildN {
|
if cfg.BuildN {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"cmd/go/internal/cfg"
|
"cmd/go/internal/cfg"
|
||||||
"cmd/go/internal/load"
|
"cmd/go/internal/load"
|
||||||
"cmd/go/internal/str"
|
"cmd/go/internal/str"
|
||||||
|
"cmd/go/internal/work"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
@ -409,8 +410,8 @@ func runTest(cmd *base.Command, args []string) {
|
|||||||
|
|
||||||
findExecCmd() // initialize cached result
|
findExecCmd() // initialize cached result
|
||||||
|
|
||||||
instrumentInit()
|
work.InstrumentInit()
|
||||||
buildModeInit()
|
work.BuildModeInit()
|
||||||
pkgs := load.PackagesForBuild(pkgArgs)
|
pkgs := load.PackagesForBuild(pkgArgs)
|
||||||
if len(pkgs) == 0 {
|
if len(pkgs) == 0 {
|
||||||
base.Fatalf("no packages to test")
|
base.Fatalf("no packages to test")
|
||||||
@ -454,8 +455,8 @@ func runTest(cmd *base.Command, args []string) {
|
|||||||
testC = true
|
testC = true
|
||||||
}
|
}
|
||||||
|
|
||||||
var b builder
|
var b work.Builder
|
||||||
b.init()
|
b.Init()
|
||||||
|
|
||||||
if cfg.BuildI {
|
if cfg.BuildI {
|
||||||
cfg.BuildV = testV
|
cfg.BuildV = testV
|
||||||
@ -497,18 +498,18 @@ func runTest(cmd *base.Command, args []string) {
|
|||||||
}
|
}
|
||||||
sort.Strings(all)
|
sort.Strings(all)
|
||||||
|
|
||||||
a := &action{}
|
a := &work.Action{}
|
||||||
for _, p := range load.PackagesForBuild(all) {
|
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)
|
b.Do(a)
|
||||||
if !testC || a.failed {
|
if !testC || a.Failed {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b.init()
|
b.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
var builds, runs, prints []*action
|
var builds, runs, prints []*work.Action
|
||||||
|
|
||||||
if testCoverPaths != nil {
|
if testCoverPaths != nil {
|
||||||
// Load packages that were asked about for coverage.
|
// 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.
|
// 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,
|
// Force the printing of results to happen in order,
|
||||||
// one at a time.
|
// one at a time.
|
||||||
for i, a := range prints {
|
for i, a := range prints {
|
||||||
if i > 0 {
|
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.
|
// Later runs must wait for the previous run's print.
|
||||||
for i, run := range runs {
|
for i, run := range runs {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
run.deps = append(run.deps, builds...)
|
run.Deps = append(run.Deps, builds...)
|
||||||
} else {
|
} 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
|
okBuild[p] = true
|
||||||
}
|
}
|
||||||
warned := false
|
warned := false
|
||||||
for _, a := range actionList(root) {
|
for _, a := range work.ActionList(root) {
|
||||||
if a.p == nil || okBuild[a.p] {
|
if a.Package == nil || okBuild[a.Package] {
|
||||||
continue
|
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
|
// Don't warn about packages being rebuilt because of
|
||||||
// things like coverage analysis.
|
// things like coverage analysis.
|
||||||
for _, p1 := range a.p.Internal.Imports {
|
for _, p1 := range a.Package.Internal.Imports {
|
||||||
if p1.Internal.Fake {
|
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 {
|
if !warned {
|
||||||
fmt.Fprintf(os.Stderr, "warning: building out-of-date packages:\n")
|
fmt.Fprintf(os.Stderr, "warning: building out-of-date packages:\n")
|
||||||
warned = true
|
warned = true
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "\t%s\n", a.p.ImportPath)
|
fmt.Fprintf(os.Stderr, "\t%s\n", a.Package.ImportPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if warned {
|
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)
|
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{
|
var windowsBadWords = []string{
|
||||||
@ -647,11 +648,11 @@ var windowsBadWords = []string{
|
|||||||
"update",
|
"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 {
|
if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
|
||||||
build := b.action(modeBuild, modeBuild, p)
|
build := b.Action(work.ModeBuild, work.ModeBuild, p)
|
||||||
run := &action{p: p, deps: []*action{build}}
|
run := &work.Action{Package: p, Deps: []*work.Action{build}}
|
||||||
print := &action{f: builderNoTest, p: p, deps: []*action{run}}
|
print := &work.Action{Func: builderNoTest, Package: p, Deps: []*work.Action{run}}
|
||||||
return build, run, print, nil
|
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.
|
// $WORK/unicode/utf8/_test/unicode/utf8.a.
|
||||||
// We write the external test package archive to
|
// We write the external test package archive to
|
||||||
// $WORK/unicode/utf8/_test/unicode/utf8_test.a.
|
// $WORK/unicode/utf8/_test/unicode/utf8_test.a.
|
||||||
testDir := filepath.Join(b.work, filepath.FromSlash(p.ImportPath+"/_test"))
|
testDir := filepath.Join(b.WorkDir, filepath.FromSlash(p.ImportPath+"/_test"))
|
||||||
ptestObj := buildToolchain.pkgpath(testDir, p)
|
ptestObj := work.BuildToolchain.Pkgpath(testDir, p)
|
||||||
|
|
||||||
// Create the directory for the .a files.
|
// Create the directory for the .a files.
|
||||||
ptestDir, _ := filepath.Split(ptestObj)
|
ptestDir, _ := filepath.Split(ptestObj)
|
||||||
if err := b.mkdir(ptestDir); err != nil {
|
if err := b.Mkdir(ptestDir); err != nil {
|
||||||
return nil, nil, nil, err
|
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.GOOS == "darwin" {
|
||||||
if cfg.BuildContext.GOARCH == "arm" || cfg.BuildContext.GOARCH == "arm64" {
|
if cfg.BuildContext.GOARCH == "arm" || cfg.BuildContext.GOARCH == "arm64" {
|
||||||
t.IsIOS = true
|
t.IsIOS = true
|
||||||
t.NeedCgo = true
|
t.NeedOS = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if t.TestMain == nil {
|
if t.TestMain == nil {
|
||||||
@ -922,24 +923,24 @@ func builderTest(b *builder, p *load.Package) (buildAction, runAction, printActi
|
|||||||
load.ComputeStale(pmain)
|
load.ComputeStale(pmain)
|
||||||
|
|
||||||
if ptest != p {
|
if ptest != p {
|
||||||
a := b.action(modeBuild, modeBuild, ptest)
|
a := b.Action(work.ModeBuild, work.ModeBuild, ptest)
|
||||||
a.objdir = testDir + string(filepath.Separator) + "_obj_test" + string(filepath.Separator)
|
a.Objdir = testDir + string(filepath.Separator) + "_obj_test" + string(filepath.Separator)
|
||||||
a.objpkg = ptestObj
|
a.Objpkg = ptestObj
|
||||||
a.target = ptestObj
|
a.Target = ptestObj
|
||||||
a.link = false
|
a.Link = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if pxtest != nil {
|
if pxtest != nil {
|
||||||
a := b.action(modeBuild, modeBuild, pxtest)
|
a := b.Action(work.ModeBuild, work.ModeBuild, pxtest)
|
||||||
a.objdir = testDir + string(filepath.Separator) + "_obj_xtest" + string(filepath.Separator)
|
a.Objdir = testDir + string(filepath.Separator) + "_obj_xtest" + string(filepath.Separator)
|
||||||
a.objpkg = buildToolchain.pkgpath(testDir, pxtest)
|
a.Objpkg = work.BuildToolchain.Pkgpath(testDir, pxtest)
|
||||||
a.target = a.objpkg
|
a.Target = a.Objpkg
|
||||||
}
|
}
|
||||||
|
|
||||||
a := b.action(modeBuild, modeBuild, pmain)
|
a := b.Action(work.ModeBuild, work.ModeBuild, pmain)
|
||||||
a.objdir = testDir + string(filepath.Separator)
|
a.Objdir = testDir + string(filepath.Separator)
|
||||||
a.objpkg = filepath.Join(testDir, "main.a")
|
a.Objpkg = filepath.Join(testDir, "main.a")
|
||||||
a.target = filepath.Join(testDir, testBinary) + cfg.ExeSuffix
|
a.Target = filepath.Join(testDir, testBinary) + cfg.ExeSuffix
|
||||||
if cfg.Goos == "windows" {
|
if cfg.Goos == "windows" {
|
||||||
// There are many reserved words on Windows that,
|
// There are many reserved words on Windows that,
|
||||||
// if used in the name of an executable, cause Windows
|
// 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.
|
// we could just do this always on Windows.
|
||||||
for _, bad := range windowsBadWords {
|
for _, bad := range windowsBadWords {
|
||||||
if strings.Contains(testBinary, bad) {
|
if strings.Contains(testBinary, bad) {
|
||||||
a.target = filepath.Join(testDir, "test.test") + cfg.ExeSuffix
|
a.Target = filepath.Join(testDir, "test.test") + cfg.ExeSuffix
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -981,33 +982,33 @@ func builderTest(b *builder, p *load.Package) (buildAction, runAction, printActi
|
|||||||
target = filepath.Join(base.Cwd, target)
|
target = filepath.Join(base.Cwd, target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buildAction = &action{
|
buildAction = &work.Action{
|
||||||
f: (*builder).install,
|
Func: work.BuildInstallFunc,
|
||||||
deps: []*action{buildAction},
|
Deps: []*work.Action{buildAction},
|
||||||
p: pmain,
|
Package: pmain,
|
||||||
target: target,
|
Target: target,
|
||||||
}
|
}
|
||||||
runAction = buildAction // make sure runAction != nil even if not running test
|
runAction = buildAction // make sure runAction != nil even if not running test
|
||||||
}
|
}
|
||||||
if testC {
|
if testC {
|
||||||
printAction = &action{p: p, deps: []*action{runAction}} // nop
|
printAction = &work.Action{Package: p, Deps: []*work.Action{runAction}} // nop
|
||||||
} else {
|
} else {
|
||||||
// run test
|
// run test
|
||||||
runAction = &action{
|
runAction = &work.Action{
|
||||||
f: builderRunTest,
|
Func: builderRunTest,
|
||||||
deps: []*action{buildAction},
|
Deps: []*work.Action{buildAction},
|
||||||
p: p,
|
Package: p,
|
||||||
ignoreFail: true,
|
IgnoreFail: true,
|
||||||
}
|
}
|
||||||
cleanAction := &action{
|
cleanAction := &work.Action{
|
||||||
f: builderCleanTest,
|
Func: builderCleanTest,
|
||||||
deps: []*action{runAction},
|
Deps: []*work.Action{runAction},
|
||||||
p: p,
|
Package: p,
|
||||||
}
|
}
|
||||||
printAction = &action{
|
printAction = &work.Action{
|
||||||
f: builderPrintTest,
|
Func: builderPrintTest,
|
||||||
deps: []*action{cleanAction},
|
Deps: []*work.Action{cleanAction},
|
||||||
p: p,
|
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 {
|
for i, dep := range p.Internal.Deps {
|
||||||
if p1 := testCopy[dep]; p1 != nil && p1 != dep {
|
if p1 := testCopy[dep]; p1 != nil && p1 != dep {
|
||||||
split()
|
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")
|
var noTestsToRun = []byte("\ntesting: warning: no tests to run\n")
|
||||||
|
|
||||||
// builderRunTest is the action for running a test binary.
|
// builderRunTest is the action for running a test binary.
|
||||||
func builderRunTest(b *builder, a *action) error {
|
func builderRunTest(b *work.Builder, a *work.Action) error {
|
||||||
args := str.StringList(findExecCmd(), a.deps[0].target, testArgs)
|
args := str.StringList(findExecCmd(), a.Deps[0].Target, testArgs)
|
||||||
a.testOutput = new(bytes.Buffer)
|
a.TestOutput = new(bytes.Buffer)
|
||||||
|
|
||||||
if cfg.BuildN || cfg.BuildX {
|
if cfg.BuildN || cfg.BuildX {
|
||||||
b.showcmd("", "%s", strings.Join(args, " "))
|
b.Showcmd("", "%s", strings.Join(args, " "))
|
||||||
if cfg.BuildN {
|
if cfg.BuildN {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.failed {
|
if a.Failed {
|
||||||
// We were unable to build the binary.
|
// We were unable to build the binary.
|
||||||
a.failed = false
|
a.Failed = false
|
||||||
fmt.Fprintf(a.testOutput, "FAIL\t%s [build failed]\n", a.p.ImportPath)
|
fmt.Fprintf(a.TestOutput, "FAIL\t%s [build failed]\n", a.Package.ImportPath)
|
||||||
base.SetExitStatus(1)
|
base.SetExitStatus(1)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.Command(args[0], args[1:]...)
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
cmd.Dir = a.p.Dir
|
cmd.Dir = a.Package.Dir
|
||||||
cmd.Env = envForDir(cmd.Dir, cfg.OrigEnv)
|
cmd.Env = envForDir(cmd.Dir, cfg.OrigEnv)
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
if testStreamOutput {
|
if testStreamOutput {
|
||||||
@ -1138,7 +1139,7 @@ func builderRunTest(b *builder, a *action) error {
|
|||||||
|
|
||||||
// If there are any local SWIG dependencies, we want to load
|
// If there are any local SWIG dependencies, we want to load
|
||||||
// the shared library from the build directory.
|
// the shared library from the build directory.
|
||||||
if a.p.UsesSwig() {
|
if a.Package.UsesSwig() {
|
||||||
env := cmd.Env
|
env := cmd.Env
|
||||||
found := false
|
found := false
|
||||||
prefix := "LD_LIBRARY_PATH="
|
prefix := "LD_LIBRARY_PATH="
|
||||||
@ -1196,23 +1197,23 @@ func builderRunTest(b *builder, a *action) error {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
norun := ""
|
norun := ""
|
||||||
if testShowPass {
|
if testShowPass {
|
||||||
a.testOutput.Write(out)
|
a.TestOutput.Write(out)
|
||||||
}
|
}
|
||||||
if bytes.HasPrefix(out, noTestsToRun[1:]) || bytes.Contains(out, noTestsToRun) {
|
if bytes.HasPrefix(out, noTestsToRun[1:]) || bytes.Contains(out, noTestsToRun) {
|
||||||
norun = " [no tests to run]"
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
base.SetExitStatus(1)
|
base.SetExitStatus(1)
|
||||||
if len(out) > 0 {
|
if len(out) > 0 {
|
||||||
a.testOutput.Write(out)
|
a.TestOutput.Write(out)
|
||||||
// assume printing the test binary's exit status is superfluous
|
// assume printing the test binary's exit status is superfluous
|
||||||
} else {
|
} 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
|
return nil
|
||||||
}
|
}
|
||||||
@ -1237,28 +1238,28 @@ func coveragePercentage(out []byte) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// builderCleanTest is the action for cleaning up after a test.
|
// 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 {
|
if cfg.BuildWork {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
run := a.deps[0]
|
run := a.Deps[0]
|
||||||
testDir := filepath.Join(b.work, filepath.FromSlash(run.p.ImportPath+"/_test"))
|
testDir := filepath.Join(b.WorkDir, filepath.FromSlash(run.Package.ImportPath+"/_test"))
|
||||||
os.RemoveAll(testDir)
|
os.RemoveAll(testDir)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// builderPrintTest is the action for printing a test result.
|
// builderPrintTest is the action for printing a test result.
|
||||||
func builderPrintTest(b *builder, a *action) error {
|
func builderPrintTest(b *work.Builder, a *work.Action) error {
|
||||||
clean := a.deps[0]
|
clean := a.Deps[0]
|
||||||
run := clean.deps[0]
|
run := clean.Deps[0]
|
||||||
os.Stdout.Write(run.testOutput.Bytes())
|
os.Stdout.Write(run.TestOutput.Bytes())
|
||||||
run.testOutput = nil
|
run.TestOutput = nil
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// builderNoTest is the action for testing a package with no test files.
|
// builderNoTest is the action for testing a package with no test files.
|
||||||
func builderNoTest(b *builder, a *action) error {
|
func builderNoTest(b *work.Builder, a *work.Action) error {
|
||||||
fmt.Printf("? \t%s\t[no test files]\n", a.p.ImportPath)
|
fmt.Printf("? \t%s\t[no test files]\n", a.Package.ImportPath)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,13 +5,16 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/go/internal/base"
|
|
||||||
"cmd/go/internal/cfg"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"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.
|
// The flag handling part of go test is large and distracting.
|
||||||
@ -66,7 +69,7 @@ var testFlagDefn = []*testFlagSpec{
|
|||||||
// add build flags to testFlagDefn
|
// add build flags to testFlagDefn
|
||||||
func init() {
|
func init() {
|
||||||
var cmd base.Command
|
var cmd base.Command
|
||||||
addBuildFlags(&cmd)
|
work.AddBuildFlags(&cmd)
|
||||||
cmd.Flag.VisitAll(func(f *flag.Flag) {
|
cmd.Flag.VisitAll(func(f *flag.Flag) {
|
||||||
if f.Name == "v" {
|
if f.Name == "v" {
|
||||||
// test overrides the build -v flag
|
// test overrides the build -v flag
|
||||||
@ -144,7 +147,7 @@ func testFlags(args []string) (packageNames, passToTest []string) {
|
|||||||
testO = value
|
testO = value
|
||||||
testNeedBinary = true
|
testNeedBinary = true
|
||||||
case "exec":
|
case "exec":
|
||||||
execCmd, err = splitQuotedFields(value)
|
execCmd, err = str.SplitQuotedFields(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
base.Fatalf("invalid flag argument for -%s: %v", f.name, err)
|
base.Fatalf("invalid flag argument for -%s: %v", f.name, err)
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,11 @@ import (
|
|||||||
"cmd/go/internal/cfg"
|
"cmd/go/internal/cfg"
|
||||||
"cmd/go/internal/load"
|
"cmd/go/internal/load"
|
||||||
"cmd/go/internal/str"
|
"cmd/go/internal/str"
|
||||||
|
"cmd/go/internal/work"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
addBuildFlags(cmdVet)
|
work.AddBuildFlags(cmdVet)
|
||||||
}
|
}
|
||||||
|
|
||||||
var cmdVet = &base.Command{
|
var cmdVet = &base.Command{
|
||||||
|
Loading…
Reference in New Issue
Block a user