From 541f4c5166cebaec5b7ad1627a5bcad2ceafb4d7 Mon Sep 17 00:00:00 2001 From: eNV25 Date: Tue, 25 Oct 2022 18:45:13 +0000 Subject: [PATCH] cmd/bundle: quote command-line arguments in output The previous version of bundle simply joins together with a space " ". While this works for simple arguments this causes problems when you need to pass special strings like an empty string or a string containing a space. The following example shows how the previous version handles an empty string argument `-prefix ""`. //go:generate bundle -o /dev/stdout -prefix example.com/mod This change quotes the arguments with strconv.Quote, if needed, before joining together with a space: //go:generate bundle -o /dev/stdout -prefix "" example.com/mod Change-Id: Ic706a3bd7916515ba91dbe5e0def956703ab2988 GitHub-Last-Rev: 8dc0c88fc17c73bb432ed60a9578ec222814e68b GitHub-Pull-Request: golang/tools#411 Reviewed-on: https://go-review.googlesource.com/c/tools/+/444956 Run-TryBot: Alan Donovan TryBot-Result: Gopher Robot gopls-CI: kokoro Reviewed-by: Heschi Kreinick Auto-Submit: Alan Donovan Reviewed-by: Alan Donovan --- cmd/bundle/main.go | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/cmd/bundle/main.go b/cmd/bundle/main.go index 96cbce9a13..194797bd82 100644 --- a/cmd/bundle/main.go +++ b/cmd/bundle/main.go @@ -84,6 +84,7 @@ import ( "os" "strconv" "strings" + "unicode" "golang.org/x/tools/go/packages" ) @@ -233,7 +234,7 @@ func bundle(src, dst, dstpkg, prefix, buildTags string) ([]byte, error) { fmt.Fprintf(&out, "// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.\n") if *outputFile != "" && buildTags == "" { - fmt.Fprintf(&out, "//go:generate bundle %s\n", strings.Join(os.Args[1:], " ")) + fmt.Fprintf(&out, "//go:generate bundle %s\n", strings.Join(quoteArgs(os.Args[1:]), " ")) } else { fmt.Fprintf(&out, "// $ bundle %s\n", strings.Join(os.Args[1:], " ")) } @@ -447,6 +448,35 @@ func printSameLineComment(out *bytes.Buffer, comments []*ast.CommentGroup, fset return pos } +func quoteArgs(ss []string) []string { + // From go help generate: + // + // > The arguments to the directive are space-separated tokens or + // > double-quoted strings passed to the generator as individual + // > arguments when it is run. + // + // > Quoted strings use Go syntax and are evaluated before execution; a + // > quoted string appears as a single argument to the generator. + // + var qs []string + for _, s := range ss { + if s == "" || containsSpace(s) { + s = strconv.Quote(s) + } + qs = append(qs, s) + } + return qs +} + +func containsSpace(s string) bool { + for _, r := range s { + if unicode.IsSpace(r) { + return true + } + } + return false +} + type flagFunc func(string) func (f flagFunc) Set(s string) error {