aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2018-07-31 14:37:43 -0400
committerBryan C. Mills <bcmills@google.com>2018-07-31 19:14:46 +0000
commitf152f83a6e3aba0eb7d5ce2f0c73463ac307ec55 (patch)
tree59d353d5fc909a4a73e8760e59d0f476bb019214
parentce06f5a222b48fd16461730c4b0dcb75b005609f (diff)
downloadgo-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.go30
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() {