Skip to content

Commit 5d278de

Browse files
committed
core: supports .add({pattern, mark})
test: fixes tests and coverage
1 parent da6e194 commit 5d278de

File tree

5 files changed

+99
-40
lines changed

5 files changed

+99
-40
lines changed

README.md

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,11 @@ ig.filter(['.abc\\a.js', '.abc\\d\\e.js'])
124124

125125
## .add(pattern: string | Ignore): this
126126
## .add(patterns: Array<string | Ignore>): this
127+
## .add({pattern: string, mark?: string}): this
127128

128-
- **pattern** `String | Ignore` An ignore pattern string, or the `Ignore` instance
129-
- **patterns** `Array<String | Ignore>` Array of ignore patterns.
129+
- **pattern** `string | Ignore` An ignore pattern string, or the `Ignore` instance
130+
- **patterns** `Array<string | Ignore>` Array of ignore patterns.
131+
- **mark?** `string` Pattern mark, which is used to associate the pattern with a certain marker, such as the line no of the `.gitignore` file. Actually it could be an arbitrary string and is optional.
130132

131133
Adds a rule or several rules to the current manager.
132134

@@ -284,17 +286,50 @@ interface TestResult {
284286
ignored: boolean
285287
// true if the `pathname` is finally unignored by some negative pattern
286288
unignored: boolean
289+
// The `IgnoreRule` which ignores the pathname
290+
rule?: IgnoreRule
291+
}
292+
293+
interface IgnoreRule {
294+
// The original pattern
295+
pattern: string
296+
// Whether the pattern is a negative pattern
297+
negative: boolean
298+
// Which is used for other packages to build things upon `node-ignore`
299+
mark?: string
287300
}
288301
```
289302

290303
- `{ignored: true, unignored: false}`: the `pathname` is ignored
291304
- `{ignored: false, unignored: true}`: the `pathname` is unignored
292305
- `{ignored: false, unignored: false}`: the `pathname` is never matched by any ignore rules.
293306

294-
## .checkIgnore(pattern) since 6.1.0
307+
## .checkIgnore(pattern) since 7.0.0
295308

296309
> new in 6.1.0
297310
311+
Debug gitignore / exclude files, which is equivalent to `git check-ignore -v`. Usually this method is used for other packages to implement the function of `git check-ignore -v` upon `node-ignore`
312+
313+
Returns `TestResult`
314+
315+
```js
316+
ig.add({
317+
pattern: 'foo/*',
318+
mark: '60'
319+
})
320+
321+
const {
322+
ignored,
323+
rule
324+
} = checkIgnore('foo/')
325+
326+
if (ignored) {
327+
console.log(`.gitignore:${result}:${rule.mark}:${rule.pattern} foo/`)
328+
}
329+
330+
// .gitignore:60:foo/* foo/
331+
```
332+
298333
Please pay attention that this method does not have a strong built-in cache mechanism.
299334

300335
The purpose of introducing this method is to make it possible to implement the `git check-ignore` command in JavaScript based on `node-ignore`.

index.js

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -361,17 +361,21 @@ const checkPattern = pattern => pattern
361361
// > A line starting with # serves as a comment.
362362
&& pattern.indexOf('#') !== 0
363363

364-
const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF)
364+
const splitPattern = pattern => pattern
365+
.split(REGEX_SPLITALL_CRLF)
366+
.filter(Boolean)
365367

366368
class IgnoreRule {
367369
constructor (
368370
pattern,
371+
mark,
369372
body,
370373
ignoreCase,
371374
negative,
372375
prefix
373376
) {
374377
this.pattern = pattern
378+
this.mark = mark
375379
this.negative = negative
376380

377381
define(this, 'body', body)
@@ -415,7 +419,10 @@ class IgnoreRule {
415419
}
416420
}
417421

418-
const createRule = (pattern, ignoreCase) => {
422+
const createRule = ({
423+
pattern,
424+
mark
425+
}, ignoreCase) => {
419426
let negative = false
420427
let body = pattern
421428

@@ -437,6 +444,7 @@ const createRule = (pattern, ignoreCase) => {
437444

438445
return new IgnoreRule(
439446
pattern,
447+
mark,
440448
body,
441449
ignoreCase,
442450
negative,
@@ -453,18 +461,18 @@ class RuleManager {
453461
_add (pattern) {
454462
// #32
455463
if (pattern && pattern[KEY_IGNORE]) {
456-
this._rules = this._rules.concat(
457-
pattern._rules._rules
458-
||
459-
// Compatible with the old version
460-
/* istanbul ignore next */
461-
pattern._rules
462-
)
464+
this._rules = this._rules.concat(pattern._rules._rules)
463465
this._added = true
464466
return
465467
}
466468

467-
if (checkPattern(pattern)) {
469+
if (isString(pattern)) {
470+
pattern = {
471+
pattern
472+
}
473+
}
474+
475+
if (checkPattern(pattern.pattern)) {
468476
const rule = createRule(pattern, this._ignoreCase)
469477
this._added = true
470478
this._rules.push(rule)
@@ -638,7 +646,7 @@ class Ignore {
638646
// If the path doest not end with a slash, `.ignores()` is much equivalent
639647
// to `git check-ignore`
640648
if (!REGEX_TEST_TRAILING_SLASH.test(path)) {
641-
return this.ignores(path)
649+
return this.test(path)
642650
}
643651

644652
const slices = path.split(SLASH).filter(Boolean)
@@ -647,17 +655,17 @@ class Ignore {
647655
if (slices.length) {
648656
const parent = this._t(
649657
slices.join(SLASH) + SLASH,
650-
this._ignoreCache,
651-
false,
658+
this._testCache,
659+
true,
652660
slices
653661
)
654662

655663
if (parent.ignored) {
656-
return true
664+
return parent
657665
}
658666
}
659667

660-
return this._rules.test(path, false, MODE_CHECK_IGNORE).ignored
668+
return this._rules.test(path, false, MODE_CHECK_IGNORE)
661669
}
662670

663671
_t (

test/fixtures/cases.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const cases = [
3737
'#77: directory ending with / not always correctly ignored',
3838
[
3939
'c/*',
40-
'foo/bar/*'
40+
{pattern: 'foo/bar/*'}
4141
],
4242
{
4343
'c/': 1,

test/git-check-ignore.test.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,17 @@ const debugSpawn = (...args) => {
6565
debug(out.output.toString())
6666
}
6767

68+
const mapObjectRule = rule =>
69+
typeof rule === 'string'
70+
? rule
71+
: rule.pattern
72+
6873
const getNativeGitIgnoreResults = (rules, paths) => {
6974
const dir = createUniqueTmp()
7075

7176
const gitignore = typeof rules === 'string'
7277
? rules
73-
: rules.join('\n')
78+
: rules.map(mapObjectRule).join('\n')
7479

7580
touch(dir, '.gitignore', gitignore)
7681

test/ignore.test.js

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -62,29 +62,40 @@ cases(({
6262
t.end()
6363
})
6464

65-
const run_ignores = name => {
66-
tt(`.${name}(path): ${description}`, t => {
67-
const ig = ignore().addPattern(patterns)
68-
69-
Object.keys(paths_object).forEach(path => {
70-
const should_ignore = !!paths_object[path]
71-
const not = should_ignore ? '' : 'not '
72-
73-
t.equal(
74-
ig[name](path),
75-
should_ignore,
76-
`path: "${path}" should ${not}be ignored`
77-
)
78-
})
79-
t.end()
80-
})
81-
}
82-
8365
check('IGNORE_ONLY_IGNORES', 'ignores')
84-
&& run_ignores('ignores')
66+
&& tt(`.ignores(path): ${description}`, t => {
67+
const ig = ignore().addPattern(patterns)
68+
69+
Object.keys(paths_object).forEach(path => {
70+
const should_ignore = !!paths_object[path]
71+
const not = should_ignore ? '' : 'not '
72+
73+
t.equal(
74+
ig.ignores(path),
75+
should_ignore,
76+
`path: "${path}" should ${not}be ignored`
77+
)
78+
})
79+
t.end()
80+
})
8581

8682
check('IGNORE_ONLY_CHECK_IGNORE', 'checkIgnore')
87-
&& run_ignores('checkIgnore')
83+
&& tt(`.checkIgnore(path): ${description}`, t => {
84+
const ig = ignore().addPattern(patterns)
85+
86+
Object.keys(paths_object).forEach(path => {
87+
const should_ignore = !!paths_object[path]
88+
const not = should_ignore ? '' : 'not '
89+
const {ignored} = ig.checkIgnore(path)
90+
91+
t.equal(
92+
ignored,
93+
should_ignore,
94+
`path: "${path}" should ${not}be ignored`
95+
)
96+
})
97+
t.end()
98+
})
8899

89100
if (!SHOULD_TEST_WINDOWS) {
90101
return

0 commit comments

Comments
 (0)