diff options
author | Bryan C. Mills <bcmills@google.com> | 2018-07-31 14:37:43 -0400 |
---|---|---|
committer | Bryan C. Mills <bcmills@google.com> | 2018-07-31 19:14:46 +0000 |
commit | f152f83a6e3aba0eb7d5ce2f0c73463ac307ec55 (patch) | |
tree | 59d353d5fc909a4a73e8760e59d0f476bb019214 | |
parent | ce06f5a222b48fd16461730c4b0dcb75b005609f (diff) | |
download | go-f152f83a6e3aba0eb7d5ce2f0c73463ac307ec55.tar.gz go-f152f83a6e3aba0eb7d5ce2f0c73463ac307ec55.zip |
cmd/go/internal/modfetch/codehost: quote arguments to commands printed from -x
Some of the arguments — particularly format strings passed to git commands — may
contain spaces, and it's useful to be able to paste commands from 'go get -x
foo' directly into a shell to reproduce their output.
Change-Id: I4f0c0b4e05db8b5232458e9a271f2ccbb665e85a
Reviewed-on: https://go-review.googlesource.com/126955
Run-TryBot: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r-- | src/cmd/go/internal/modfetch/codehost/codehost.go | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/src/cmd/go/internal/modfetch/codehost/codehost.go b/src/cmd/go/internal/modfetch/codehost/codehost.go index 9c07b96957..4103ddc717 100644 --- a/src/cmd/go/internal/modfetch/codehost/codehost.go +++ b/src/cmd/go/internal/modfetch/codehost/codehost.go @@ -201,6 +201,10 @@ func Run(dir string, cmdline ...interface{}) ([]byte, error) { return RunWithStdin(dir, nil, cmdline...) } +// bashQuoter escapes characters that have special meaning in double-quoted strings in the bash shell. +// See https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html. +var bashQuoter = strings.NewReplacer(`"`, `\"`, `$`, `\$`, "`", "\\`", `\`, `\\`) + func RunWithStdin(dir string, stdin io.Reader, cmdline ...interface{}) ([]byte, error) { if dir != "" { muIface, ok := dirLock.Load(dir) @@ -214,11 +218,31 @@ func RunWithStdin(dir string, stdin io.Reader, cmdline ...interface{}) ([]byte, cmd := str.StringList(cmdline...) if cfg.BuildX { - var text string + text := new(strings.Builder) if dir != "" { - text = "cd " + dir + "; " + text.WriteString("cd ") + text.WriteString(dir) + text.WriteString("; ") + } + for i, arg := range cmd { + if i > 0 { + text.WriteByte(' ') + } + switch { + case strings.ContainsAny(arg, "'"): + // Quote args that could be mistaken for quoted args. + text.WriteByte('"') + text.WriteString(bashQuoter.Replace(arg)) + text.WriteByte('"') + case strings.ContainsAny(arg, "$`\\*?[\"\t\n\v\f\r \u0085\u00a0"): + // Quote args that contain special characters, glob patterns, or spaces. + text.WriteByte('\'') + text.WriteString(arg) + text.WriteByte('\'') + default: + text.WriteString(arg) + } } - text += strings.Join(cmd, " ") fmt.Fprintf(os.Stderr, "%s\n", text) start := time.Now() defer func() { |