Skip to content

Commit

Permalink
#75: main, README.md, test, ts: new options.allowRelativePaths to bri…
Browse files Browse the repository at this point in the history
…ng backward compatibility
  • Loading branch information
kaelzhang committed Dec 19, 2021
1 parent 92e83e2 commit 052a722
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 19 deletions.
32 changes: 26 additions & 6 deletions README.md
Expand Up @@ -298,7 +298,19 @@ interface TestResult {
- `{ignored: false, unignored: true}`: the `pathname` is unignored
- `{ignored: false, unignored: false}`: the `pathname` is never matched by any ignore rules.

## `options.ignorecase` since 4.0.0
## static `ignore.isPathValid(pathname): boolean` since 5.0.0

Check whether the `pathname` is an valid `path.relative()`d path according to the [convention](#1-pathname-should-be-a-pathrelatived-pathname).

This method is **NOT** used to check if an ignore pattern is valid.

```js
ignore.isPathValid('./foo') // false
```

## ignore(options)

### `options.ignorecase` since 4.0.0

Similar as the `core.ignorecase` option of [git-config](https://git-scm.com/docs/git-config), `node-ignore` will be case insensitive if `options.ignorecase` is set to `true` (the default value), otherwise case sensitive.

Expand All @@ -312,14 +324,20 @@ ig.add('*.png')
ig.ignores('*.PNG') // false
```

## static `ignore.isPathValid(pathname): boolean` since 5.0.0
### `options.ignoreCase?: boolean` since 5.2.0

Check whether the `pathname` is an valid `path.relative()`d path according to the [convention](#1-pathname-should-be-a-pathrelatived-pathname).
Which is alternative to `options.ignoreCase`

This method is **NOT** used to check if an ignore pattern is valid.
### `options.allowRelativePaths?: boolean` since 5.2.0

This option brings backward compatibility with projects which based on `ignore@4.x`

However, passing a relative path to test if it is ignored or not is not a good practise, which might lead to unexpected behavior

```js
ignore.isPathValid('./foo') // false
ignore({
allowRelativePaths: true
}).ignores('../foo/bar.js') // And it will not throw
```

****
Expand All @@ -328,7 +346,9 @@ ignore.isPathValid('./foo') // false

## Upgrade 4.x -> 5.x

Since `5.0.0`, if an invalid `Pathname` passed into `ig.ignores()`, an error will be thrown, while `ignore < 5.0.0` did not make sure what the return value was, as well as
Since `5.0.0`, if an invalid `Pathname` passed into `ig.ignores()`, an error will be thrown, unless `options.allowRelative = true` is passed to the `Ignore` factory.

While `ignore < 5.0.0` did not make sure what the return value was, as well as

```ts
.ignores(pathname: Pathname): boolean
Expand Down
5 changes: 4 additions & 1 deletion index.d.ts
Expand Up @@ -20,7 +20,7 @@ export interface Ignore {
* @returns The filtered array of paths
*/
filter(pathnames: readonly Pathname[]): Pathname[]

/**
* Creates a filter function which could filter
* an array of paths with Array.prototype.filter.
Expand All @@ -44,6 +44,9 @@ export interface Ignore {

interface Options {
ignorecase?: boolean
// For compatibility
ignoreCase?: boolean
allowRelativePaths?: boolean
}

/**
Expand Down
31 changes: 20 additions & 11 deletions index.js
Expand Up @@ -30,6 +30,8 @@ const define = (object, key, value) =>

const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g

const RETURN_FALSE = () => false

// Sanitize the range of a regular expression
// The cases are complicated, see test cases for details
const sanitizeRange = range => range.replace(
Expand Down Expand Up @@ -288,7 +290,7 @@ const REPLACERS = [
const regexCache = Object.create(null)

// @param {pattern}
const makeRegex = (pattern, ignorecase) => {
const makeRegex = (pattern, ignoreCase) => {
let source = regexCache[pattern]

if (!source) {
Expand All @@ -299,7 +301,7 @@ const makeRegex = (pattern, ignorecase) => {
regexCache[pattern] = source
}

return ignorecase
return ignoreCase
? new RegExp(source, 'i')
: new RegExp(source)
}
Expand Down Expand Up @@ -330,7 +332,7 @@ class IgnoreRule {
}
}

const createRule = (pattern, ignorecase) => {
const createRule = (pattern, ignoreCase) => {
const origin = pattern
let negative = false

Expand All @@ -348,7 +350,7 @@ const createRule = (pattern, ignorecase) => {
// > begin with a hash.
.replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#')

const regex = makeRegex(pattern, ignorecase)
const regex = makeRegex(pattern, ignoreCase)

return new IgnoreRule(
origin,
Expand Down Expand Up @@ -394,12 +396,15 @@ checkPath.convert = p => p

class Ignore {
constructor ({
ignorecase = true
ignorecase = true,
ignoreCase = ignorecase,
allowRelativePaths = false
} = {}) {
define(this, KEY_IGNORE, true)

this._rules = []
this._ignorecase = ignorecase
this._ignoreCase = ignoreCase
this._allowRelativePaths = allowRelativePaths
this._initCache()
}

Expand All @@ -417,7 +422,7 @@ class Ignore {
}

if (checkPattern(pattern)) {
const rule = createRule(pattern, this._ignorecase)
const rule = createRule(pattern, this._ignoreCase)
this._added = true
this._rules.push(rule)
}
Expand Down Expand Up @@ -496,7 +501,13 @@ class Ignore {
// Supports nullable path
&& checkPath.convert(originalPath)

checkPath(path, originalPath, throwError)
checkPath(
path,
originalPath,
this._allowRelativePaths
? RETURN_FALSE
: throwError
)

return this._t(path, cache, checkUnignored, slices)
}
Expand Down Expand Up @@ -554,10 +565,8 @@ class Ignore {

const factory = options => new Ignore(options)

const returnFalse = () => false

const isPathValid = path =>
checkPath(path && checkPath.convert(path), path, returnFalse)
checkPath(path && checkPath.convert(path), path, RETURN_FALSE)

factory.isPathValid = isPathValid

Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "ignore",
"version": "5.1.9",
"version": "5.2.0",
"description": "Ignore is a manager and filter for .gitignore rules, the one used by eslint, gitbook and many others.",
"files": [
"legacy.js",
Expand Down
14 changes: 14 additions & 0 deletions test/others.js
Expand Up @@ -227,3 +227,17 @@ IGNORE_TEST_CASES.forEach(([d, patterns, path, [ignored, unignored]]) => {
t.end()
})
})

_test('options.allowRelativePaths', t => {
const ig = ignore({
allowRelativePaths: true
})

ig.add('foo')

t.is(ig.ignores('../foo/bar.js'), true)

t.throws(() => ignore().ignores('../foo/bar.js'))

t.end()
})

0 comments on commit 052a722

Please sign in to comment.