]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: allow output in non-existent directory
authorSam Xie <xsambundy@gmail.com>
Thu, 17 Sep 2020 02:59:28 +0000 (02:59 +0000)
committerJay Conrod <jayconrod@google.com>
Thu, 17 Sep 2020 15:51:14 +0000 (15:51 +0000)
When 'go build' is given an output path with -o, if the output path
ends with a path separator, always treat it as a directory.

Fixes #41313

Change-Id: I9a9c25448abfcd6297ad973f5ed2025b2568a4a7
GitHub-Last-Rev: 20a19bd63a2779a2c94b0efdf86146ffd551293c
GitHub-Pull-Request: golang/go#41314
Reviewed-on: https://go-review.googlesource.com/c/go/+/253821
Run-TryBot: Jay Conrod <jayconrod@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Trust: Bryan C. Mills <bcmills@google.com>
Trust: Jay Conrod <jayconrod@google.com>

src/cmd/go/alldocs.go
src/cmd/go/internal/work/build.go
src/cmd/go/testdata/script/build_output.txt

index b7e5bbed2d88c3a0ed66135d263349bf02ad3517..5f1c7aaecb6adf64b3071457acccd6c787113d55 100644 (file)
@@ -93,8 +93,9 @@
 //
 // The -o flag forces build to write the resulting executable or object
 // to the named output file or directory, instead of the default behavior described
-// in the last two paragraphs. If the named output is a directory that exists,
-// then any resulting executables will be written to that directory.
+// in the last two paragraphs. If the named output is an existing directory or
+// ends with a slash or backslash, then any resulting executables
+// will be written to that directory.
 //
 // The -i flag installs the packages that are dependencies of the target.
 //
index 990e5d9ecd62d0363ca367d331bed33eb7a4cbbc..86423f118c1deeb33b5d324a579ea7ba83043edb 100644 (file)
@@ -53,8 +53,9 @@ serving only as a check that the packages can be built.
 
 The -o flag forces build to write the resulting executable or object
 to the named output file or directory, instead of the default behavior described
-in the last two paragraphs. If the named output is a directory that exists,
-then any resulting executables will be written to that directory.
+in the last two paragraphs. If the named output is an existing directory or
+ends with a slash or backslash, then any resulting executables
+will be written to that directory.
 
 The -i flag installs the packages that are dependencies of the target.
 
@@ -387,10 +388,13 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) {
        }
 
        if cfg.BuildO != "" {
-               // If the -o name exists and is a directory, then
+               // If the -o name exists and is a directory or
+               // ends with a slash or backslash, then
                // write all main packages to that directory.
                // Otherwise require only a single package be built.
-               if fi, err := os.Stat(cfg.BuildO); err == nil && fi.IsDir() {
+               if fi, err := os.Stat(cfg.BuildO); (err == nil && fi.IsDir()) ||
+                       strings.HasSuffix(cfg.BuildO, "/") ||
+                       strings.HasSuffix(cfg.BuildO, string(os.PathSeparator)) {
                        if !explicitO {
                                base.Fatalf("go build: build output %q already exists and is a directory", cfg.BuildO)
                        }
index ced7cf82a6ef8d2c5cbbde8dda7eb35bebcb0e5f..1e82950dbc1f1a9de1c9b9da768e2ad886bd4233 100644 (file)
@@ -18,6 +18,32 @@ go build -o myprog x.go
 exists -exec myprog
 ! exists myprogr.exe
 
+! exists bin
+go build -o bin/x x.go
+exists -exec bin/x
+rm bin
+
+! exists bin
+go build -o bin/ x.go
+exists -exec bin/x$GOEXE
+rm bin
+
+[windows] ! exists bin
+[windows] go build -o bin\x x.go
+[windows] exists -exec bin\x
+[windows] rm bin
+
+[windows] ! exists bin
+[windows] go build -o bin\ x.go
+[windows] exists -exec bin\x.exe
+[windows] rm bin
+
+! exists bin
+mkdir bin
+go build -o bin x.go
+exists -exec bin/x$GOEXE
+rm bin
+
 go build p.go
 ! exists p
 ! exists p.a