diff --git a/caddyfile/parse.go b/caddyfile/parse.go index 83dea0160..eb5512cbb 100644 --- a/caddyfile/parse.go +++ b/caddyfile/parse.go @@ -365,6 +365,12 @@ func (p *parser) directive() error { nesting-- } else if p.Val() == "}" && nesting == 0 { return p.Err("Unexpected '}' because no matching opening brace") + } else if p.Val() == "import" && p.isNewLine() { + if err := p.doImport(); err != nil { + return err + } + p.cursor-- // cursor is advanced when we continue, so roll back one more + continue } p.tokens[p.cursor].Text = replaceEnvVars(p.tokens[p.cursor].Text) p.block.Tokens[dir] = append(p.block.Tokens[dir], p.tokens[p.cursor]) diff --git a/caddyfile/parse_test.go b/caddyfile/parse_test.go index b42711a8a..741dbcbf7 100644 --- a/caddyfile/parse_test.go +++ b/caddyfile/parse_test.go @@ -371,6 +371,68 @@ func TestRecursiveImport(t *testing.T) { } } +func TestDirectiveImport(t *testing.T) { + testParseOne := func(input string) (ServerBlock, error) { + p := testParser(input) + p.Next() // parseOne doesn't call Next() to start, so we must + err := p.parseOne() + return p.block, err + } + + isExpected := func(got ServerBlock) bool { + if len(got.Keys) != 1 || got.Keys[0] != "localhost" { + t.Errorf("got keys unexpected: expect localhost, got %v", got.Keys) + return false + } + if len(got.Tokens) != 2 { + t.Errorf("got wrong number of tokens: expect 2, got %d", len(got.Tokens)) + return false + } + if len(got.Tokens["dir1"]) != 1 || len(got.Tokens["proxy"]) != 8 { + t.Errorf("got unexpect tokens: %v", got.Tokens) + return false + } + return true + } + + directiveFile, err := filepath.Abs("testdata/directive_import_test") + if err != nil { + t.Fatal(err) + } + + err = ioutil.WriteFile(directiveFile, []byte(`prop1 1 + prop2 2`), 0644) + if err != nil { + t.Fatal(err) + } + defer os.Remove(directiveFile) + + // import from existing file + result, err := testParseOne(`localhost + dir1 + proxy { + import testdata/directive_import_test + transparent + }`) + if err != nil { + t.Fatal(err) + } + if !isExpected(result) { + t.Error("directive import failed") + } + + // import from nonexisting file + _, err = testParseOne(`localhost + dir1 + proxy { + import testdata/nonexistent_file + transparent + }`) + if err == nil { + t.Fatal("expected error when importing a nonexistent file") + } +} + func TestParseAll(t *testing.T) { for i, test := range []struct { input string