aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2018-04-25 13:03:03 -0400
committerRuss Cox <rsc@golang.org>2018-05-10 19:15:27 +0000
commit9ccfde6ee7df654be64a79c79ec4178c10d8fd18 (patch)
tree5cbef9e1a203f2f166544b4f5fbaf0390cecaedc /src
parent670cb7603a02f4955d2b53176f9114a13b778062 (diff)
downloadgo-9ccfde6ee7df654be64a79c79ec4178c10d8fd18.tar.xz
cmd/go: add support for 'go run pkg' or 'go run .'
To date, go run has required a list of .go files. This CL allows in place of that list a single import path or a directory name or a pattern matching a single patckage. This allows 'go run pkg' or 'go run dir', most importantly 'go run .'. The discussion in #22726 gives more motivation. The basic idea is that you can already run 'go test .' but if you're developing a command it's pretty awkward to iterate at the same speed. This lets you do that, by using 'go run . [args]'. Fixes #22726. Change-Id: Ibfc8172a4f752588ad96df0a6b0928e9b61fa27f Reviewed-on: https://go-review.googlesource.com/109341 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/go/alldocs.go9
-rw-r--r--src/cmd/go/go_test.go12
-rw-r--r--src/cmd/go/internal/run/run.go44
-rw-r--r--src/cmd/go/testdata/src/hello/hello.go5
4 files changed, 54 insertions, 16 deletions
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index fa0d57f16b..8cccbf4de0 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -718,10 +718,12 @@
//
// Usage:
//
-// go run [build flags] [-exec xprog] gofiles... [arguments...]
+// go run [build flags] [-exec xprog] package [arguments...]
//
-// Run compiles and runs the main package comprising the named Go source files.
-// A Go source file is defined to be a file ending in a literal ".go" suffix.
+// Run compiles and runs the named main Go package.
+// Typically the package is specified as a list of .go source files,
+// but it may also be an import path, file system path, or pattern
+// matching a single known package, as in 'go run .' or 'go run my/cmd'.
//
// By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
// If the -exec flag is given, 'go run' invokes the binary using xprog:
@@ -736,6 +738,7 @@
// The exit status of Run is not the exit status of the compiled binary.
//
// For more about build flags, see 'go help build'.
+// For more about specifying packages, see 'go help packages'.
//
// See also: go build.
//
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 06948525ad..33fbc2cc48 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -1273,6 +1273,18 @@ func TestRunInternal(t *testing.T) {
tg.grepStderr(`testdata(\/|\\)src(\/|\\)run(\/|\\)bad\.go\:3\:8\: use of internal package not allowed`, "unexpected error for run/bad.go")
}
+func TestRunPkg(t *testing.T) {
+ tg := testgo(t)
+ defer tg.cleanup()
+ dir := filepath.Join(tg.pwd(), "testdata")
+ tg.setenv("GOPATH", dir)
+ tg.run("run", "hello")
+ tg.grepStderr("hello, world", "did not find hello, world")
+ tg.cd(filepath.Join(dir, "src/hello"))
+ tg.run("run", ".")
+ tg.grepStderr("hello, world", "did not find hello, world")
+}
+
func testMove(t *testing.T, vcs, url, base, config string) {
testenv.MustHaveExternalNetwork(t)
diff --git a/src/cmd/go/internal/run/run.go b/src/cmd/go/internal/run/run.go
index 6ff2090095..8460d1fac6 100644
--- a/src/cmd/go/internal/run/run.go
+++ b/src/cmd/go/internal/run/run.go
@@ -18,11 +18,13 @@ import (
)
var CmdRun = &base.Command{
- UsageLine: "run [build flags] [-exec xprog] gofiles... [arguments...]",
+ UsageLine: "run [build flags] [-exec xprog] package [arguments...]",
Short: "compile and run Go program",
Long: `
-Run compiles and runs the main package comprising the named Go source files.
-A Go source file is defined to be a file ending in a literal ".go" suffix.
+Run compiles and runs the named main Go package.
+Typically the package is specified as a list of .go source files,
+but it may also be an import path, file system path, or pattern
+matching a single known package, as in 'go run .' or 'go run my/cmd'.
By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
If the -exec flag is given, 'go run' invokes the binary using xprog:
@@ -37,6 +39,7 @@ available.
The exit status of Run is not the exit status of the compiled binary.
For more about build flags, see 'go help build'.
+For more about specifying packages, see 'go help packages'.
See also: go build.
`,
@@ -62,18 +65,33 @@ func runRun(cmd *base.Command, args []string) {
for i < len(args) && strings.HasSuffix(args[i], ".go") {
i++
}
- files, cmdArgs := args[:i], args[i:]
- if len(files) == 0 {
- 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.
- base.Fatalf("go run: cannot run *_test.go files (%s)", file)
+ var p *load.Package
+ if i > 0 {
+ files := args[:i]
+ 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.
+ base.Fatalf("go run: cannot run *_test.go files (%s)", file)
+ }
+ }
+ p = load.GoFilesPackage(files)
+ } else if len(args) > 0 && !strings.HasPrefix(args[0], "-") {
+ pkgs := load.PackagesAndErrors(args[:1])
+ if len(pkgs) > 1 {
+ var names []string
+ for _, p := range pkgs {
+ names = append(names, p.ImportPath)
+ }
+ base.Fatalf("go run: pattern %s matches multiple packages:\n\t%s", args[0], strings.Join(names, "\n\t"))
}
+ p = pkgs[0]
+ i++
+ } else {
+ base.Fatalf("go run: no go files listed")
}
- p := load.GoFilesPackage(files)
+ cmdArgs := args[i:]
+
if p.Error != nil {
base.Fatalf("%s", p.Error)
}
diff --git a/src/cmd/go/testdata/src/hello/hello.go b/src/cmd/go/testdata/src/hello/hello.go
new file mode 100644
index 0000000000..73d83e646f
--- /dev/null
+++ b/src/cmd/go/testdata/src/hello/hello.go
@@ -0,0 +1,5 @@
+package main
+
+func main() {
+ println("hello, world")
+}