From fdf2a77feb53cb9dd6de772f811e96a5f6b2d2c4 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Mon, 1 Jun 2020 12:43:06 -0400 Subject: caddyfile: Add args on imports (#3423) * caddyfile: Add support for args on imports * caddyfile: Add more import args tests --- caddyconfig/caddyfile/parse.go | 33 ++++++++++++++++++++----- caddyconfig/caddyfile/parse_test.go | 8 ++++-- caddyconfig/caddyfile/testdata/import_args0.txt | 1 + caddyconfig/caddyfile/testdata/import_args1.txt | 1 + 4 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 caddyconfig/caddyfile/testdata/import_args0.txt create mode 100644 caddyconfig/caddyfile/testdata/import_args1.txt (limited to 'caddyconfig') diff --git a/caddyconfig/caddyfile/parse.go b/caddyconfig/caddyfile/parse.go index cdcac26..5cb5b68 100755 --- a/caddyconfig/caddyfile/parse.go +++ b/caddyconfig/caddyfile/parse.go @@ -20,7 +20,10 @@ import ( "log" "os" "path/filepath" + "strconv" "strings" + + "github.com/caddyserver/caddy/v2" ) // Parse parses the input just enough to group tokens, in @@ -292,11 +295,19 @@ func (p *parser) doImport() error { if importPattern == "" { return p.Err("Import requires a non-empty filepath") } - if p.NextArg() { - return p.Err("Import takes only one argument (glob pattern or file)") + + // grab remaining args as placeholder replacements + args := p.RemainingArgs() + + // add args to the replacer + repl := caddy.NewReplacer() + for index, arg := range args { + repl.Set("args."+strconv.Itoa(index), arg) } - // splice out the import directive and its argument (2 tokens total) - tokensBefore := p.tokens[:p.cursor-1] + + // splice out the import directive and its arguments + // (2 tokens, plus the length of args) + tokensBefore := p.tokens[:p.cursor-1-len(args)] tokensAfter := p.tokens[p.cursor+1:] var importedTokens []Token @@ -348,10 +359,20 @@ func (p *parser) doImport() error { } } + // copy the tokens so we don't overwrite p.definedSnippets + tokensCopy := make([]Token, len(importedTokens)) + copy(tokensCopy, importedTokens) + + // run the argument replacer on the tokens + for index, token := range tokensCopy { + token.Text = repl.ReplaceKnown(token.Text, "") + tokensCopy[index] = token + } + // splice the imported tokens in the place of the import statement // and rewind cursor so Next() will land on first imported token - p.tokens = append(tokensBefore, append(importedTokens, tokensAfter...)...) - p.cursor-- + p.tokens = append(tokensBefore, append(tokensCopy, tokensAfter...)...) + p.cursor -= len(args) + 1 return nil } diff --git a/caddyconfig/caddyfile/parse_test.go b/caddyconfig/caddyfile/parse_test.go index ed15367..12c30c8 100755 --- a/caddyconfig/caddyfile/parse_test.go +++ b/caddyconfig/caddyfile/parse_test.go @@ -182,14 +182,17 @@ func TestParseOneAndImport(t *testing.T) { "host1", }, []int{1, 2}}, - {`import testdata/import_test1.txt testdata/import_test2.txt`, true, []string{}, []int{}}, - {`import testdata/not_found.txt`, true, []string{}, []int{}}, {`""`, false, []string{}, []int{}}, {``, false, []string{}, []int{}}, + // import with args + {`import testdata/import_args0.txt a`, false, []string{"a"}, []int{}}, + {`import testdata/import_args1.txt a b`, false, []string{"a", "b"}, []int{}}, + {`import testdata/import_args*.txt a b`, false, []string{"a"}, []int{2}}, + // test cases found by fuzzing! {`import }{$"`, true, []string{}, []int{}}, {`import /*/*.txt`, true, []string{}, []int{}}, @@ -210,6 +213,7 @@ func TestParseOneAndImport(t *testing.T) { t.Errorf("Test %d: Expected no error, but got: %v", i, err) } + // t.Logf("%+v\n", result) if len(result.Keys) != len(test.keys) { t.Errorf("Test %d: Expected %d keys, got %d", i, len(test.keys), len(result.Keys)) diff --git a/caddyconfig/caddyfile/testdata/import_args0.txt b/caddyconfig/caddyfile/testdata/import_args0.txt new file mode 100644 index 0000000..af946fe --- /dev/null +++ b/caddyconfig/caddyfile/testdata/import_args0.txt @@ -0,0 +1 @@ +{args.0} \ No newline at end of file diff --git a/caddyconfig/caddyfile/testdata/import_args1.txt b/caddyconfig/caddyfile/testdata/import_args1.txt new file mode 100644 index 0000000..519a92d --- /dev/null +++ b/caddyconfig/caddyfile/testdata/import_args1.txt @@ -0,0 +1 @@ +{args.0} {args.1} \ No newline at end of file -- cgit v1.2.3