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 the pattern has size 1 we can match it directly against the filename
|
||||||
if len(p.parsedValues) == 1 {
|
if len(p.parsedValues) == 1 {
|
||||||
return matchBracketPattern(p.parsedValues[0], fileNameWithoutDir)
|
return matchCurlyBracePattern(p.parsedValues[0], fileNameWithoutDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.matchPatterns(fileNameWithoutDir)
|
return p.matchPatterns(fileNameWithoutDir)
|
||||||
@@ -159,7 +159,7 @@ func (p *pattern) matchPatterns(fileName string) bool {
|
|||||||
cursor = j
|
cursor = j
|
||||||
subPattern := strings.Join(partsToMatch[j:j+patternSize], string(filepath.Separator))
|
subPattern := strings.Join(partsToMatch[j:j+patternSize], string(filepath.Separator))
|
||||||
|
|
||||||
if matchBracketPattern(pattern, subPattern) {
|
if matchCurlyBracePattern(pattern, subPattern) {
|
||||||
cursor = j + patternSize - 1
|
cursor = j + patternSize - 1
|
||||||
|
|
||||||
break
|
break
|
||||||
@@ -174,24 +174,10 @@ func (p *pattern) matchPatterns(fileName string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// we also check for the following bracket syntax: /path/*.{php,twig,yaml}
|
// we also check for the following syntax: /path/*.{php,twig,yaml}
|
||||||
func matchBracketPattern(pattern string, fileName string) bool {
|
func matchCurlyBracePattern(pattern string, fileName string) bool {
|
||||||
openingBracket := strings.Index(pattern, "{")
|
for _, subPattern := range expandCurlyBraces(pattern) {
|
||||||
closingBracket := strings.Index(pattern, "}")
|
if matchPattern(subPattern, fileName) {
|
||||||
|
|
||||||
// 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) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,6 +185,26 @@ func matchBracketPattern(pattern string, fileName string) bool {
|
|||||||
return false
|
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 {
|
func matchPattern(pattern string, fileName string) bool {
|
||||||
if pattern == "" {
|
if pattern == "" {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ func TestInvalidDirectoryPatterns(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidExtendedPatterns(t *testing.T) {
|
func TestValidCurlyBracePatterns(t *testing.T) {
|
||||||
data := []struct {
|
data := []struct {
|
||||||
pattern string
|
pattern string
|
||||||
dir string
|
dir string
|
||||||
@@ -272,6 +272,10 @@ func TestValidExtendedPatterns(t *testing.T) {
|
|||||||
{"/path/{dir1,dir2}/file.php", "/path/dir2/file.php"},
|
{"/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/app/subpath/file.php"},
|
||||||
{"/app/{app,config,resources}/**/*.php", "/app/config/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 {
|
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 {
|
data := []struct {
|
||||||
pattern string
|
pattern string
|
||||||
dir string
|
dir string
|
||||||
@@ -293,6 +297,9 @@ func TestInvalidExtendedPatterns(t *testing.T) {
|
|||||||
{"/path/{file.php,file.twig}", "/path/file.txt"},
|
{"/path/{file.php,file.twig}", "/path/file.txt"},
|
||||||
{"/path/{dir1,dir2}/file.php", "/path/dir3/file.php"},
|
{"/path/{dir1,dir2}/file.php", "/path/dir3/file.php"},
|
||||||
{"/path/{dir1,dir2}/**/*.php", "/path/dir1/subpath/file.txt"},
|
{"/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 {
|
for _, d := range data {
|
||||||
|
|||||||
Reference in New Issue
Block a user