fix: using files from context in source
This commit is contained in:
+3
-8
@@ -56,11 +56,6 @@ func (op *Source) Configure(config map[string]any) error {
|
||||
var _ cabret.ListOperation = &Source{}
|
||||
|
||||
func (op Source) ProcessList(ctx *cabret.Context, contents []cabret.Content) ([]cabret.Content, error) {
|
||||
files, err := cabret.FindFiles()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
matches := []cabret.MatchResult{}
|
||||
|
||||
for _, rawPattern := range op.Patterns {
|
||||
@@ -69,10 +64,10 @@ func (op Source) ProcessList(ctx *cabret.Context, contents []cabret.Content) ([]
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
if ok, captures, _ := pattern.Match(f); ok {
|
||||
for _, file := range ctx.Files {
|
||||
if ok, captures, _ := pattern.Match(file); ok {
|
||||
matches = append(matches, cabret.MatchResult{
|
||||
File: f,
|
||||
File: file,
|
||||
Captures: captures,
|
||||
})
|
||||
}
|
||||
|
||||
+51
-44
@@ -16,6 +16,11 @@ type PathPart interface {
|
||||
regex() string
|
||||
}
|
||||
|
||||
var _ PathPart = PathLiteral{}
|
||||
var _ PathPart = PathShortPattern{}
|
||||
var _ PathPart = PathLongPattern{}
|
||||
var _ PathPart = PathString{}
|
||||
|
||||
type PathLiteral struct {
|
||||
LongAny bool `parser:" @'**'"`
|
||||
ShortAny bool `parser:"| @'*' "`
|
||||
@@ -25,7 +30,7 @@ type PathLiteral struct {
|
||||
func (p PathLiteral) regex() string {
|
||||
switch {
|
||||
case p.Slash:
|
||||
return "/"
|
||||
return regexp.QuoteMeta("/")
|
||||
case p.ShortAny:
|
||||
return "([^/]+?)"
|
||||
case p.LongAny:
|
||||
@@ -52,7 +57,7 @@ func (p PathLongPattern) regex() string {
|
||||
}
|
||||
|
||||
type PathString struct {
|
||||
Value string `parser:"@Ident"`
|
||||
Value string `parser:"@(Ident|Rune)+"`
|
||||
}
|
||||
|
||||
func (p PathString) regex() string {
|
||||
@@ -63,18 +68,44 @@ type Pattern struct {
|
||||
Parts []PathPart `parser:"@@+"`
|
||||
}
|
||||
|
||||
func (pp Pattern) regex() string {
|
||||
sb := &strings.Builder{}
|
||||
var parser = participle.MustBuild[Pattern](
|
||||
participle.Union[PathPart](
|
||||
&PathLiteral{},
|
||||
&PathLongPattern{},
|
||||
&PathShortPattern{},
|
||||
&PathString{},
|
||||
),
|
||||
participle.Lexer(
|
||||
lexer.MustSimple([]lexer.SimpleRule{
|
||||
{Name: "Slash", Pattern: `/`},
|
||||
{Name: "LongAny", Pattern: `\*\*`},
|
||||
{Name: "ShortAny", Pattern: `\*`},
|
||||
{Name: "PatternLongOpen", Pattern: `{{`},
|
||||
{Name: "PatternLongClose", Pattern: `}}`},
|
||||
{Name: "PatternShortOpen", Pattern: `{`},
|
||||
{Name: "PatternShortClose", Pattern: `}`},
|
||||
{Name: "Ident", Pattern: `[a-zA-Z][a-zA-Z0-9\_]*`},
|
||||
{Name: "Rune", Pattern: `[^/{}]+`},
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
for _, p := range pp.Parts {
|
||||
sb.WriteString(p.regex())
|
||||
}
|
||||
|
||||
return sb.String()
|
||||
func ParsePattern(path string) (*Pattern, error) {
|
||||
return parser.ParseString("", path)
|
||||
}
|
||||
|
||||
func (pp Pattern) Match(s string) (bool, map[string]string, error) {
|
||||
r, err := regexp.Compile("^" + pp.regex() + "$")
|
||||
func MustParsePattern(path string) *Pattern {
|
||||
p, err := ParsePattern(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// Match takes a path "s" and matches it against this pattern and returns whether it matched and in that case a map containing all captures for this pattern. This will throw an error if it can't compile the internal regex (should never happen).
|
||||
func (p Pattern) Match(s string) (bool, map[string]string, error) {
|
||||
r, err := regexp.Compile("^" + p.regex() + "$")
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
@@ -96,26 +127,15 @@ func (pp Pattern) Match(s string) (bool, map[string]string, error) {
|
||||
return true, ctx, nil
|
||||
}
|
||||
|
||||
var parser = participle.MustBuild[Pattern](
|
||||
participle.Union[PathPart](
|
||||
&PathLiteral{},
|
||||
&PathLongPattern{},
|
||||
&PathShortPattern{},
|
||||
&PathString{},
|
||||
),
|
||||
participle.Lexer(
|
||||
lexer.MustSimple([]lexer.SimpleRule{
|
||||
{Name: "Slash", Pattern: `/`},
|
||||
{Name: "LongAny", Pattern: `\*\*`},
|
||||
{Name: "ShortAny", Pattern: `\*`},
|
||||
{Name: "PatternLongOpen", Pattern: `{{`},
|
||||
{Name: "PatternLongClose", Pattern: `}}`},
|
||||
{Name: "PatternShortOpen", Pattern: `{`},
|
||||
{Name: "PatternShortClose", Pattern: `}`},
|
||||
{Name: "Ident", Pattern: `[^/{}]+`},
|
||||
}),
|
||||
),
|
||||
)
|
||||
func (p Pattern) regex() string {
|
||||
sb := &strings.Builder{}
|
||||
|
||||
for _, part := range p.Parts {
|
||||
sb.WriteString(part.regex())
|
||||
}
|
||||
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func RenderTemplate(tmpl string, ctx map[string]string) string {
|
||||
s := tmpl
|
||||
@@ -124,16 +144,3 @@ func RenderTemplate(tmpl string, ctx map[string]string) string {
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func ParsePattern(path string) (*Pattern, error) {
|
||||
return parser.ParseString("", path)
|
||||
}
|
||||
|
||||
func MustParsePattern(path string) *Pattern {
|
||||
p, err := ParsePattern(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package path_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unicode"
|
||||
|
||||
"github.com/aziis98/cabret/path"
|
||||
"gotest.tools/assert"
|
||||
@@ -170,3 +171,37 @@ func TestMultipleGroups(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzMatch(f *testing.F) {
|
||||
f.Add(`{a}.txt`)
|
||||
f.Add(`{a}/{b}.txt`)
|
||||
f.Add(`src/{{a}}/index.html`)
|
||||
f.Add(`/a/{b}/c-{d}.go`)
|
||||
|
||||
path.MustParsePattern(`{a}.txt`)
|
||||
path.MustParsePattern(`{a}/{b}.txt`)
|
||||
path.MustParsePattern(`src/{{a}}/index.html`)
|
||||
path.MustParsePattern(`/a/{b}/c-{d}.go`)
|
||||
|
||||
f.Fuzz(func(t *testing.T, pattern string) {
|
||||
goodPattern := make([]rune, 0, len(pattern))
|
||||
|
||||
// filter in only ascii runes
|
||||
for _, c := range pattern {
|
||||
if c <= unicode.MaxASCII {
|
||||
goodPattern = append(goodPattern, c)
|
||||
}
|
||||
}
|
||||
|
||||
pattern = string(goodPattern)
|
||||
|
||||
p, err := path.ParsePattern(pattern)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, _, err := p.Match(""); err != nil {
|
||||
t.Errorf(`invalid regexp generated by pattern %q`, pattern)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user