From f5618a3f9434c623228c9d3e5c51136cc2850737 Mon Sep 17 00:00:00 2001 From: Roger Peppe Date: Fri, 30 Nov 2018 11:46:42 +0000 Subject: [PATCH] testscript: allow quoting of regexp metacharacters in env vars (#31) --- testscript/doc.go | 6 ++++++ testscript/scripts/regexpquote.txt | 5 +++++ testscript/testscript.go | 7 ++++++- 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 testscript/scripts/regexpquote.txt diff --git a/testscript/doc.go b/testscript/doc.go index 8d55cfec..73f3f327 100644 --- a/testscript/doc.go +++ b/testscript/doc.go @@ -87,6 +87,12 @@ quote indicates a literal single quote, as in: A line beginning with # is a comment and conventionally explains what is being done or tested at the start of a new phase in the script. +A special form of environment variable syntax can be used to quote +regexp metacharacters inside environment variables. The "@R" suffix +is special, and indicates that the variable should be quoted. + + ${VAR@R} + The command prefix ! indicates that the command on the rest of the line (typically go or a matching predicate) must fail, not succeed. Only certain commands support this prefix. They are indicated below by [!] in the synopsis. diff --git a/testscript/scripts/regexpquote.txt b/testscript/scripts/regexpquote.txt new file mode 100644 index 00000000..b1b5720f --- /dev/null +++ b/testscript/scripts/regexpquote.txt @@ -0,0 +1,5 @@ +env XXX='hello)' +grep ^${XXX@R}$ file.txt + +-- file.txt -- +hello) diff --git a/testscript/testscript.go b/testscript/testscript.go index 58da803b..0f750bf7 100644 --- a/testscript/testscript.go +++ b/testscript/testscript.go @@ -477,7 +477,12 @@ func (ts *TestScript) Exec(command string, args ...string) error { // expand applies environment variable expansion to the string s. func (ts *TestScript) expand(s string) string { - return os.Expand(s, func(key string) string { return ts.envMap[key] }) + return os.Expand(s, func(key string) string { + if key1 := strings.TrimSuffix(key, "@R"); len(key1) != len(key) { + return regexp.QuoteMeta(ts.envMap[key1]) + } + return ts.envMap[key] + }) } // fatalf aborts the test with the given failure message.