mirror of
https://github.com/golang/go
synced 2024-11-23 23:30:10 -07:00
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>
This commit is contained in:
parent
670cb7603a
commit
9ccfde6ee7
@ -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.
|
||||
//
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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 {
|
||||
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")
|
||||
}
|
||||
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)
|
||||
cmdArgs := args[i:]
|
||||
|
||||
if p.Error != nil {
|
||||
base.Fatalf("%s", p.Error)
|
||||
}
|
||||
|
5
src/cmd/go/testdata/src/hello/hello.go
vendored
Normal file
5
src/cmd/go/testdata/src/hello/hello.go
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
println("hello, world")
|
||||
}
|
Loading…
Reference in New Issue
Block a user