mirror of
https://github.com/dunglas/frankenphp.git
synced 2025-12-24 13:38:11 +08:00
feat: multiple curly braces for watcher (#2068)
Allows doing something like this:
```caddyfile
watch "/app/{config,src}/*.{php,js}"
```
In the long term it would be nice to have pattern matching in the
watcher repo itself
This commit is contained in:
committed by
GitHub
parent
a8f75d0eef
commit
175e644d10
@@ -127,7 +127,7 @@ func (p *pattern) isValidPattern(fileName string) bool {
|
||||
|
||||
// if the pattern has size 1 we can match it directly against the filename
|
||||
if len(p.parsedValues) == 1 {
|
||||
return matchBracketPattern(p.parsedValues[0], fileNameWithoutDir)
|
||||
return matchCurlyBracePattern(p.parsedValues[0], fileNameWithoutDir)
|
||||
}
|
||||
|
||||
return p.matchPatterns(fileNameWithoutDir)
|
||||
@@ -159,7 +159,7 @@ func (p *pattern) matchPatterns(fileName string) bool {
|
||||
cursor = j
|
||||
subPattern := strings.Join(partsToMatch[j:j+patternSize], string(filepath.Separator))
|
||||
|
||||
if matchBracketPattern(pattern, subPattern) {
|
||||
if matchCurlyBracePattern(pattern, subPattern) {
|
||||
cursor = j + patternSize - 1
|
||||
|
||||
break
|
||||
@@ -174,24 +174,10 @@ func (p *pattern) matchPatterns(fileName string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// we also check for the following bracket syntax: /path/*.{php,twig,yaml}
|
||||
func matchBracketPattern(pattern string, fileName string) bool {
|
||||
openingBracket := strings.Index(pattern, "{")
|
||||
closingBracket := strings.Index(pattern, "}")
|
||||
|
||||
// if there are no brackets we can match regularly
|
||||
if openingBracket == -1 || closingBracket == -1 {
|
||||
return matchPattern(pattern, fileName)
|
||||
}
|
||||
|
||||
beforeTheBrackets := pattern[:openingBracket]
|
||||
betweenTheBrackets := pattern[openingBracket+1 : closingBracket]
|
||||
afterTheBrackets := pattern[closingBracket+1:]
|
||||
|
||||
// all bracket entries are checked individually, only one needs to match
|
||||
// *.{php,twig,yaml} -> *.php, *.twig, *.yaml
|
||||
for pattern := range strings.SplitSeq(betweenTheBrackets, ",") {
|
||||
if matchPattern(beforeTheBrackets+pattern+afterTheBrackets, fileName) {
|
||||
// we also check for the following syntax: /path/*.{php,twig,yaml}
|
||||
func matchCurlyBracePattern(pattern string, fileName string) bool {
|
||||
for _, subPattern := range expandCurlyBraces(pattern) {
|
||||
if matchPattern(subPattern, fileName) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -199,6 +185,26 @@ func matchBracketPattern(pattern string, fileName string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// {dir1,dir2}/path -> []string{"dir1/path", "dir2/path"}
|
||||
func expandCurlyBraces(s string) []string {
|
||||
before, rest, found := strings.Cut(s, "{")
|
||||
if !found {
|
||||
return []string{s}
|
||||
}
|
||||
|
||||
inside, after, found := strings.Cut(rest, "}")
|
||||
if !found {
|
||||
return []string{s} // no closing brace
|
||||
}
|
||||
|
||||
var out []string
|
||||
for _, subPattern := range strings.Split(inside, ",") {
|
||||
out = append(out, expandCurlyBraces(before+subPattern+after)...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func matchPattern(pattern string, fileName string) bool {
|
||||
if pattern == "" {
|
||||
return true
|
||||
|
||||
@@ -259,7 +259,7 @@ func TestInvalidDirectoryPatterns(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidExtendedPatterns(t *testing.T) {
|
||||
func TestValidCurlyBracePatterns(t *testing.T) {
|
||||
data := []struct {
|
||||
pattern string
|
||||
dir string
|
||||
@@ -272,6 +272,10 @@ func TestValidExtendedPatterns(t *testing.T) {
|
||||
{"/path/{dir1,dir2}/file.php", "/path/dir2/file.php"},
|
||||
{"/app/{app,config,resources}/**/*.php", "/app/app/subpath/file.php"},
|
||||
{"/app/{app,config,resources}/**/*.php", "/app/config/subpath/file.php"},
|
||||
{"/path/{dir1,dir2}/{a,b}{a,b}.php", "/path/dir1/ab.php"},
|
||||
{"/path/{dir1,dir2}/{a,b}{a,b}.php", "/path/dir2/aa.php"},
|
||||
{"/path/{dir1,dir2}/{a,b}{a,b}.php", "/path/dir2/bb.php"},
|
||||
{"/path/{dir1/test.php,dir2/test.php}", "/path/dir1/test.php"},
|
||||
}
|
||||
|
||||
for _, d := range data {
|
||||
@@ -283,7 +287,7 @@ func TestValidExtendedPatterns(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidExtendedPatterns(t *testing.T) {
|
||||
func TestInvalidCurlyBracePatterns(t *testing.T) {
|
||||
data := []struct {
|
||||
pattern string
|
||||
dir string
|
||||
@@ -293,6 +297,9 @@ func TestInvalidExtendedPatterns(t *testing.T) {
|
||||
{"/path/{file.php,file.twig}", "/path/file.txt"},
|
||||
{"/path/{dir1,dir2}/file.php", "/path/dir3/file.php"},
|
||||
{"/path/{dir1,dir2}/**/*.php", "/path/dir1/subpath/file.txt"},
|
||||
{"/path/{dir1,dir2}/{a,b}{a,b}.php", "/path/dir1/ac.php"},
|
||||
{"/path/{}/{a,b}{a,b}.php", "/path/dir1/ac.php"},
|
||||
{"/path/}dir{/{a,b}{a,b}.php", "/path/dir1/aa.php"},
|
||||
}
|
||||
|
||||
for _, d := range data {
|
||||
|
||||
Reference in New Issue
Block a user