mirror of
https://github.com/caddyserver/caddy.git
synced 2024-11-25 17:56:34 +08:00
Merge pull request #385 from radim/master
Support glob character in import
This commit is contained in:
commit
6a27968f73
6
caddy/parse/import_glob0.txt
Normal file
6
caddy/parse/import_glob0.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
glob0.host0 {
|
||||||
|
dir2 arg1
|
||||||
|
}
|
||||||
|
|
||||||
|
glob0.host1 {
|
||||||
|
}
|
4
caddy/parse/import_glob1.txt
Normal file
4
caddy/parse/import_glob1.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
glob1.host0 {
|
||||||
|
dir1
|
||||||
|
dir2 arg1
|
||||||
|
}
|
3
caddy/parse/import_glob2.txt
Normal file
3
caddy/parse/import_glob2.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
glob2.host0 {
|
||||||
|
dir2 arg1
|
||||||
|
}
|
|
@ -176,19 +176,52 @@ func (p *parser) directives() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// doImport swaps out the import directive and its argument
|
// doImport swaps out the import directive and its argument
|
||||||
// (a total of 2 tokens) with the tokens in the file specified.
|
// (a total of 2 tokens) with the tokens in the specified file
|
||||||
// When the function returns, the cursor is on the token before
|
// or globbing pattern. When the function returns, the cursor
|
||||||
// where the import directive was. In other words, call Next()
|
// is on the token before where the import directive was. In
|
||||||
// to access the first token that was imported.
|
// other words, call Next() to access the first token that was
|
||||||
|
// imported.
|
||||||
func (p *parser) doImport() error {
|
func (p *parser) doImport() error {
|
||||||
if !p.NextArg() {
|
if !p.NextArg() {
|
||||||
return p.ArgErr()
|
return p.ArgErr()
|
||||||
}
|
}
|
||||||
importFile := p.Val()
|
importPattern := p.Val()
|
||||||
if p.NextArg() {
|
if p.NextArg() {
|
||||||
return p.Err("Import allows only one file to import")
|
return p.Err("Import allows only one expression, either file or glob pattern")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
matches, err := filepath.Glob(importPattern)
|
||||||
|
if err != nil {
|
||||||
|
return p.Errf("Failed to use import pattern %s - %s", importPattern, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(matches) == 0 {
|
||||||
|
return p.Errf("No files matching the import pattern %s", importPattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Splice out the import directive and its argument (2 tokens total)
|
||||||
|
// and insert the imported tokens in their place.
|
||||||
|
tokensBefore := p.tokens[:p.cursor-1]
|
||||||
|
tokensAfter := p.tokens[p.cursor+1:]
|
||||||
|
// cursor was advanced one position to read filename; rewind it
|
||||||
|
p.cursor--
|
||||||
|
|
||||||
|
p.tokens = tokensBefore
|
||||||
|
|
||||||
|
for _, importFile := range matches {
|
||||||
|
if err := p.doSingleImport(importFile); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p.tokens = append(p.tokens, append(tokensAfter)...)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// doSingleImport lexes the individual files matching the
|
||||||
|
// globbing pattern from of the import directive.
|
||||||
|
func (p *parser) doSingleImport(importFile string) error {
|
||||||
file, err := os.Open(importFile)
|
file, err := os.Open(importFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return p.Errf("Could not import %s - %v", importFile, err)
|
return p.Errf("Could not import %s - %v", importFile, err)
|
||||||
|
@ -203,10 +236,7 @@ func (p *parser) doImport() error {
|
||||||
|
|
||||||
// Splice out the import directive and its argument (2 tokens total)
|
// Splice out the import directive and its argument (2 tokens total)
|
||||||
// and insert the imported tokens in their place.
|
// and insert the imported tokens in their place.
|
||||||
tokensBefore := p.tokens[:p.cursor-1]
|
p.tokens = append(p.tokens, append(importedTokens)...)
|
||||||
tokensAfter := p.tokens[p.cursor+1:]
|
|
||||||
p.tokens = append(tokensBefore, append(importedTokens, tokensAfter...)...)
|
|
||||||
p.cursor-- // cursor was advanced one position to read the filename; rewind it
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,6 +329,13 @@ func TestParseAll(t *testing.T) {
|
||||||
[]address{{"host1.com", "http"}, {"host2.com", "http"}},
|
[]address{{"host1.com", "http"}, {"host2.com", "http"}},
|
||||||
[]address{{"host3.com", "https"}, {"host4.com", "https"}},
|
[]address{{"host3.com", "https"}, {"host4.com", "https"}},
|
||||||
}},
|
}},
|
||||||
|
|
||||||
|
{`import import_glob*.txt`, false, [][]address{
|
||||||
|
[]address{{"glob0.host0", ""}},
|
||||||
|
[]address{{"glob0.host1", ""}},
|
||||||
|
[]address{{"glob1.host0", ""}},
|
||||||
|
[]address{{"glob2.host0", ""}},
|
||||||
|
}},
|
||||||
} {
|
} {
|
||||||
p := testParser(test.input)
|
p := testParser(test.input)
|
||||||
blocks, err := p.parseAll()
|
blocks, err := p.parseAll()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user