Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd009e2f

Browse files
authored
fix: support special characters and invalid ignore rules when filtering files (#477)
1 parentb129918 commitd009e2f

File tree

3 files changed

+87
-25
lines changed

3 files changed

+87
-25
lines changed

‎.gitignore‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@ Thumbs.db
4444
.DS_Store
4545
._*
4646
webidentity.json
47-
.cursor
47+
.cursor
48+
.windsurf

‎pkg/utils/file_filter.go‎

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ import (
1515
"gopkg.in/yaml.v3"
1616
)
1717

18+
// by default, all rules are valid
19+
vardefaultInvalidRules= []string{}
20+
1821
typeFileFilterstruct {
1922
pathstring
2023
defaultRules []string
@@ -179,10 +182,10 @@ func (fw *FileFilter) parseDotSnykFile(content []byte, filePath string) []string
179182

180183
varglobs []string
181184
for_,codeRule:=rangerules.Exclude.Code {
182-
globs=append(globs,parseIgnoreRuleToGlobs(codeRule,filePath)...)
185+
globs=append(globs,parseIgnoreRuleToGlobs(codeRule,filePath,defaultInvalidRules)...)
183186
}
184187
for_,codeRule:=rangerules.Exclude.Global {
185-
globs=append(globs,parseIgnoreRuleToGlobs(codeRule,filePath)...)
188+
globs=append(globs,parseIgnoreRuleToGlobs(codeRule,filePath,defaultInvalidRules)...)
186189
}
187190

188191
returnglobs
@@ -193,23 +196,52 @@ func parseIgnoreFile(content []byte, filePath string) []string {
193196
varignores []string
194197
lines:=strings.Split(string(content),"\n")
195198

199+
// Invalid .gitignore style patterns
200+
invalidRules:= []string{"."}
201+
196202
for_,line:=rangelines {
197203
ifstrings.HasPrefix(line,"#")||strings.TrimSpace(line)=="" {
198204
continue
199205
}
200-
globs:=parseIgnoreRuleToGlobs(line,filePath)
206+
globs:=parseIgnoreRuleToGlobs(line,filePath,invalidRules)
201207
ignores=append(ignores,globs...)
202208
}
203209
returnignores
204210
}
205211

212+
// escapeSpecialGlobChars escapes special characters that should be treated literally in glob patterns.
213+
// Special Characters to escape: $
214+
funcescapeSpecialGlobChars(rulestring)string {
215+
varresult strings.Builder
216+
fori:=0;i<len(rule);i++ {
217+
ch:=rule[i]
218+
switchch {
219+
case'$':
220+
result.WriteByte('\\')
221+
result.WriteByte(ch)
222+
default:
223+
result.WriteByte(ch)
224+
}
225+
}
226+
returnresult.String()
227+
}
228+
206229
// parseIgnoreRuleToGlobs contains the business logic to build glob patterns from a given ignore file
207-
funcparseIgnoreRuleToGlobs(rulestring,filePathstring) (globs []string) {
230+
// we try to implement the same logic as gitignore pattern format - https://git-scm.com/docs/gitignore#_pattern_format
231+
funcparseIgnoreRuleToGlobs(rulestring,filePathstring,invalidRules []string) (globs []string) {
208232
// Mappings from .gitignore format to glob format:
209233
// `/foo/` => `/foo/**` (meaning: Ignore root (not sub) foo dir and its paths underneath.)
210234
// `/foo`=> `/foo/**`, `/foo` (meaning: Ignore root (not sub) file and dir and its paths underneath.)
211235
// `foo/` => `**/foo/**` (meaning: Ignore (root/sub) foo dirs and their paths underneath.)
212236
// `foo` => `**/foo/**`, `foo` (meaning: Ignore (root/sub) foo filesToFilter and dirs and their paths underneath.)
237+
238+
// If a rule is invalid, we skip it
239+
for_,invalidRule:=rangeinvalidRules {
240+
ifstrings.TrimSpace(rule)==invalidRule {
241+
returnglobs
242+
}
243+
}
244+
213245
prefix:=""
214246
constnegation="!"
215247
constslash="/"
@@ -235,24 +267,28 @@ func parseIgnoreRuleToGlobs(rule string, filePath string) (globs []string) {
235267
// case `/foo/`, `/foo` => `{baseDir}/foo/**`
236268
// case `**/foo/`, `**/foo` => `{baseDir}/**/foo/**`
237269
if!endingGlobstar {
238-
globs=append(globs,filepath.ToSlash(prefix+filepath.Join(baseDir,rule,all)))
270+
glob:=filepath.ToSlash(prefix+filepath.Join(baseDir,rule,all))
271+
globs=append(globs,escapeSpecialGlobChars(glob))
239272
}
240273
// case `/foo` => `{baseDir}/foo`
241274
// case `**/foo` => `{baseDir}/**/foo`
242275
// case `/foo/**` => `{baseDir}/foo/**`
243276
// case `**/foo/**` => `{baseDir}/**/foo/**`
244277
if!endingSlash {
245-
globs=append(globs,filepath.ToSlash(prefix+filepath.Join(baseDir,rule)))
278+
glob:=filepath.ToSlash(prefix+filepath.Join(baseDir,rule))
279+
globs=append(globs,escapeSpecialGlobChars(glob))
246280
}
247281
}else {
248282
// case `foo/`, `foo` => `{baseDir}/**/foo/**`
249283
if!endingGlobstar {
250-
globs=append(globs,filepath.ToSlash(prefix+filepath.Join(baseDir,all,rule,all)))
284+
glob:=filepath.ToSlash(prefix+filepath.Join(baseDir,all,rule,all))
285+
globs=append(globs,escapeSpecialGlobChars(glob))
251286
}
252287
// case `foo` => `{baseDir}/**/foo`
253288
// case `foo/**` => `{baseDir}/**/foo/**`
254289
if!endingSlash {
255-
globs=append(globs,filepath.ToSlash(prefix+filepath.Join(baseDir,all,rule)))
290+
glob:=filepath.ToSlash(prefix+filepath.Join(baseDir,all,rule))
291+
globs=append(globs,escapeSpecialGlobChars(glob))
256292
}
257293
}
258294
returnglobs

‎pkg/utils/file_filter_test.go‎

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -382,59 +382,84 @@ func TestParseIgnoreRuleToGlobs(t *testing.T) {
382382
namestring
383383
rulestring
384384
baseDirstring
385+
invalidRules []string
385386
expectedGlobs []string
386387
}{
388+
{
389+
name:"invalid rules are ignored",
390+
rule:".",
391+
baseDir:"/tmp/test",
392+
invalidRules: []string{"."},
393+
expectedGlobs: []string{},
394+
},
395+
{
396+
name:"handles special characters",
397+
rule:"*$",
398+
baseDir:"/tmp/test",
399+
invalidRules: []string{},
400+
expectedGlobs: []string{
401+
"/tmp/test/**/*\\$",
402+
"/tmp/test/**/*\\$/**",
403+
},
404+
},
387405
{
388406
name:"single slash has no effect",
389407
rule:"/",
390408
baseDir:"/tmp/test",
409+
invalidRules: []string{},
391410
expectedGlobs: []string{},
392411
},
393412
{
394413
name:"negated single slash has no effect",
395414
rule:"!/",
396415
baseDir:"/tmp/test",
416+
invalidRules: []string{},
397417
expectedGlobs: []string{},
398418
},
399419
{
400-
name:"slash with star ignores everything",
401-
rule:"/*",
402-
baseDir:"/tmp/test",
420+
name:"slash with star ignores everything",
421+
rule:"/*",
422+
baseDir:"/tmp/test",
423+
invalidRules: []string{},
403424
expectedGlobs: []string{
404425
"/tmp/test/*/**",
405426
"/tmp/test/*",
406427
},
407428
},
408429
{
409-
name:"root directory pattern",
410-
rule:"/foo",
411-
baseDir:"/tmp/test",
430+
name:"root directory pattern",
431+
rule:"/foo",
432+
baseDir:"/tmp/test",
433+
invalidRules: []string{},
412434
expectedGlobs: []string{
413435
"/tmp/test/foo/**",
414436
"/tmp/test/foo",
415437
},
416438
},
417439
{
418-
name:"root directory with trailing slash",
419-
rule:"/foo/",
420-
baseDir:"/tmp/test",
440+
name:"root directory with trailing slash",
441+
rule:"/foo/",
442+
baseDir:"/tmp/test",
443+
invalidRules: []string{},
421444
expectedGlobs: []string{
422445
"/tmp/test/foo/**",
423446
},
424447
},
425448
{
426-
name:"non-root directory pattern",
427-
rule:"foo",
428-
baseDir:"/tmp/test",
449+
name:"non-root directory pattern",
450+
rule:"foo",
451+
baseDir:"/tmp/test",
452+
invalidRules: []string{},
429453
expectedGlobs: []string{
430454
"/tmp/test/**/foo/**",
431455
"/tmp/test/**/foo",
432456
},
433457
},
434458
{
435-
name:"non-root directory with trailing slash",
436-
rule:"foo/",
437-
baseDir:"/tmp/test",
459+
name:"non-root directory with trailing slash",
460+
rule:"foo/",
461+
baseDir:"/tmp/test",
462+
invalidRules: []string{},
438463
expectedGlobs: []string{
439464
"/tmp/test/**/foo/**",
440465
},
@@ -443,7 +468,7 @@ func TestParseIgnoreRuleToGlobs(t *testing.T) {
443468

444469
for_,tc:=rangetestCases {
445470
t.Run(tc.name,func(t*testing.T) {
446-
globs:=parseIgnoreRuleToGlobs(tc.rule,tc.baseDir)
471+
globs:=parseIgnoreRuleToGlobs(tc.rule,tc.baseDir,tc.invalidRules)
447472
assert.ElementsMatch(t,tc.expectedGlobs,globs,
448473
"Rule: %q, Expected: %v, Got: %v",tc.rule,tc.expectedGlobs,globs)
449474
})

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp