Git Product home page Git Product logo

node-ignore's Introduction

Linux OS X Windows Coverage Downloads
Build Status Windows Build Status Coverage Status npm module downloads per month

ignore

ignore is a manager, filter and parser which implemented in pure JavaScript according to the .gitignore spec 2.22.1.

ignore is used by eslint, gitbook and many others.

Pay ATTENTION that minimatch (which used by fstream-ignore) does not follow the gitignore spec.

To filter filenames according to a .gitignore file, I recommend this npm package, ignore.

To parse an .npmignore file, you should use minimatch, because an .npmignore file is parsed by npm using minimatch and it does not work in the .gitignore way.

Tested on

ignore is fully tested, and has more than five hundreds of unit tests.

  • Linux + Node: 0.8 - 7.x
  • Windows + Node: 0.10 - 7.x, node < 0.10 is not tested due to the lack of support of appveyor.

Actually, ignore does not rely on any versions of node specially.

Since 4.0.0, ignore will no longer support node < 6 by default, to use in node < 6, require('ignore/legacy'). For details, see CHANGELOG.

Table Of Main Contents

Install

npm i ignore

Usage

import ignore from 'ignore'
const ig = ignore().add(['.abc/*', '!.abc/d/'])

Filter the given paths

const paths = [
  '.abc/a.js',    // filtered out
  '.abc/d/e.js'   // included
]

ig.filter(paths)        // ['.abc/d/e.js']
ig.ignores('.abc/a.js') // true

As the filter function

paths.filter(ig.createFilter()); // ['.abc/d/e.js']

Win32 paths will be handled

ig.filter(['.abc\\a.js', '.abc\\d\\e.js'])
// if the code above runs on windows, the result will be
// ['.abc\\d\\e.js']

Why another ignore?

  • ignore is a standalone module, and is much simpler so that it could easy work with other programs, unlike isaacs's fstream-ignore which must work with the modules of the fstream family.

  • ignore only contains utility methods to filter paths according to the specified ignore rules, so

    • ignore never try to find out ignore rules by traversing directories or fetching from git configurations.
    • ignore don't cares about sub-modules of git projects.
  • Exactly according to gitignore man page, fixes some known matching issues of fstream-ignore, such as:

    • '/*.js' should only match 'a.js', but not 'abc/a.js'.
    • '**/foo' should match 'foo' anywhere.
    • Prevent re-including a file if a parent directory of that file is excluded.
    • Handle trailing whitespaces:
      • 'a '(one space) should not match 'a '(two spaces).
      • 'a \ ' matches 'a '
    • All test cases are verified with the result of git check-ignore.

Methods

.add(pattern: string | Ignore): this

.add(patterns: Array<string | Ignore>): this

  • pattern String | Ignore An ignore pattern string, or the Ignore instance
  • patterns Array<String | Ignore> Array of ignore patterns.

Adds a rule or several rules to the current manager.

Returns this

Notice that a line starting with '#'(hash) is treated as a comment. Put a backslash ('\') in front of the first hash for patterns that begin with a hash, if you want to ignore a file with a hash at the beginning of the filename.

ignore().add('#abc').ignores('#abc')    // false
ignore().add('\\#abc').ignores('#abc')   // true

pattern could either be a line of ignore pattern or a string of multiple ignore patterns, which means we could just ignore().add() the content of a ignore file:

ignore()
.add(fs.readFileSync(filenameOfGitignore).toString())
.filter(filenames)

pattern could also be an ignore instance, so that we could easily inherit the rules of another Ignore instance.

.addIgnoreFile(path)

REMOVED in 3.x for now.

To upgrade [email protected] up to 3.x, use

import fs from 'fs'

if (fs.existsSync(filename)) {
  ignore().add(fs.readFileSync(filename).toString())
}

instead.

.filter(paths: Array<Pathname>): Array<Pathname>

type Pathname = string

Filters the given array of pathnames, and returns the filtered array.

  • paths Array.<Pathname> The array of pathnames to be filtered.

Pathname Conventions:

1. Pathname should be a path.relative()d pathname

Pathname should be a string that have been path.join()ed, or the return value of path.relative() to the current directory,

// WRONG, an error will be thrown
ig.ignores('./abc')

// WRONG, for it will never happen, and an error will be thrown
// If the gitignore rule locates at the root directory,
// `'/abc'` should be changed to `'abc'`.
// ```
// path.relative('/', '/abc')  -> 'abc'
// ```
ig.ignores('/abc')

// WRONG, that it is an absolute path on Windows, an error will be thrown
ig.ignores('C:\\abc')

// Right
ig.ignores('abc')

// Right
ig.ignores(path.join('./abc'))  // path.join('./abc') -> 'abc'

In other words, each Pathname here should be a relative path to the directory of the gitignore rules.

Suppose the dir structure is:

/path/to/your/repo
    |-- a
    |   |-- a.js
    |
    |-- .b
    |
    |-- .c
         |-- .DS_store

Then the paths might be like this:

[
  'a/a.js'
  '.b',
  '.c/.DS_store'
]

2. filenames and dirnames

node-ignore does NO fs.stat during path matching, so for the example below:

// First, we add a ignore pattern to ignore a directory
ig.add('config/')

// `ig` does NOT know if 'config', in the real world,
//   is a normal file, directory or something.

ig.ignores('config')
// `ig` treats `config` as a file, so it returns `false`

ig.ignores('config/')
// returns `true`

Specially for people who develop some library based on node-ignore, it is important to understand that.

Usually, you could use glob with option.mark = true to fetch the structure of the current directory:

import glob from 'glob'

glob('**', {
  // Adds a / character to directory matches.
  mark: true
}, (err, files) => {
  if (err) {
    return console.error(err)
  }

  let filtered = ignore().add(patterns).filter(files)
  console.log(filtered)
})

.ignores(pathname: Pathname): boolean

new in 3.2.0

Returns Boolean whether pathname should be ignored.

ig.ignores('.abc/a.js')    // true

.createFilter()

Creates a filter function which could filter an array of paths with Array.prototype.filter.

Returns function(path) the filter function.

.test(pathname: Pathname) since 5.0.0

Returns TestResult

interface TestResult {
  ignored: boolean
  // true if the `pathname` is finally unignored by some negative pattern
  unignored: boolean
}
  • {ignored: true, unignored: false}: the pathname is ignored
  • {ignored: false, unignored: true}: the pathname is unignored
  • {ignored: false, unignored: false}: the pathname is never matched by any ignore rules.

static ignore.isPathValid(pathname): boolean since 5.0.0

Check whether the pathname is an valid path.relative()d path according to the convention.

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

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

ignore(options)

options.ignorecase since 4.0.0

Similar as the core.ignorecase option of git-config, node-ignore will be case insensitive if options.ignorecase is set to true (the default value), otherwise case sensitive.

const ig = ignore({
  ignorecase: false
})

ig.add('*.png')

ig.ignores('*.PNG')  // false

options.ignoreCase?: boolean since 5.2.0

Which is alternative to options.ignoreCase

options.allowRelativePaths?: boolean since 5.2.0

This option brings backward compatibility with projects which based on [email protected]. If options.allowRelativePaths is true, ignore will not check whether the given path to be tested is path.relative()d.

However, passing a relative path, such as './foo' or '../foo', to test if it is ignored or not is not a good practise, which might lead to unexpected behavior

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

Upgrade Guide

Upgrade 4.x -> 5.x

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

.ignores(pathname: Pathname): boolean

.filter(pathnames: Array<Pathname>): Array<Pathname>

.createFilter(): (pathname: Pathname) => boolean

.test(pathname: Pathname): {ignored: boolean, unignored: boolean}

See the convention here for details.

If there are invalid pathnames, the conversion and filtration should be done by users.

import {isPathValid} from 'ignore' // introduced in 5.0.0

const paths = [
  // invalid
  //////////////////
  '',
  false,
  '../foo',
  '.',
  //////////////////

  // valid
  'foo'
]
.filter(isValidPath)

ig.filter(paths)

Upgrade 3.x -> 4.x

Since 4.0.0, ignore will no longer support node < 6, to use ignore in node < 6:

var ignore = require('ignore/legacy')

Upgrade 2.x -> 3.x

  • All options of 2.x are unnecessary and removed, so just remove them.
  • ignore() instance is no longer an EventEmitter, and all events are unnecessary and removed.
  • .addIgnoreFile() is removed, see the .addIgnoreFile section for details.

Collaborators

node-ignore's People

Contributors

aquibm avatar azproduction avatar damianglowala avatar dependabot[bot] avatar gfyoung avatar janmattner avatar kaelzhang avatar kasperisager avatar mhemrg avatar nicojs avatar ntwb avatar samypesse avatar sandersn avatar sanjaymsh avatar sonicdoe avatar trysound avatar wclr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-ignore's Issues

`?` should match a single character

? in a pattern should match a single character. Eg. .*.sw? should ignore .testfile.swo. It's missing from the documentation page you link to for the spec (https://git-scm.com/docs/gitignore), but it is in https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository#Ignoring-Files, and it is the functionality that git (git status) follows.

11:05:09 j ~/Development/ls-ignore [master] $ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working tree clean
11:05:11 j ~/Development/ls-ignore [master] $ cat .gitignore
*~
node_modules
yarn*
11:05:21 j ~/Development/ls-ignore [master] $ touch test.swo
11:05:31 j ~/Development/ls-ignore [master]?1 $ git status
On branch master
Your branch is up-to-date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        test.swo

nothing added to commit but untracked files present (use "git add" to track)
11:05:35 j ~/Development/ls-ignore [master]?1 $ echo "*.sw?" >> .gitignore
11:05:40 j ~/Development/ls-ignore [master]โ‰ 1 $ cat .gitignore
*~
node_modules
yarn*
*.sw?
11:05:51 j ~/Development/ls-ignore [master]โ‰ 1 $ git status
On branch master
Your branch is up-to-date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   .gitignore

no changes added to commit (use "git add" and/or "git commit -a")
> nore = ignore().add(['.*.sw?'])
IgnoreBase {
  _rules: 
   [ { origin: '.*.sw?',
       pattern: '.*.sw?',
       negative: false,
       regex: /(?:^|\/)\.[^\/]*\.sw\?(?=$|\/)/i } ],
  _cache: {},
  _added: true,
  [Symbol(node-ignore)]: true }
> nore.filter(['.this.swo'])
[ '.this.swo' ]
> nore.ignores(['.this.swo'])
false

Negate broken

Using the star * to match everything and then negating certain patterns doesn't work and returns an empty array.

const paths = ["modules/ignore", "modules/include"];
const globs = ["*", "!modules/include"];
const filtered = ignore().add(globs).filter(paths);
// filtered == []

If however one uses */* it does.

const paths = ["modules/ignore", "modules/include"];
const globs = ["*/*", "!modules/include"];
const filtered = ignore().add(globs).filter(paths);
// filtered == ["modules/include"]

See here: https://codepen.io/abemedia/pen/JjNBvOR?editors=1111

It should not be possible to re-include a file from an ignored parent directory

According to the spec:

An optional prefix "!" which negates the pattern; any matching file excluded by a previous pattern will become included again. It is not possible to re-include a file if a parent directory of that file is excluded.

Given:

var ignore = require('ignore');
var ig = ignore().addPattern(['/abc/', '!/abc/a.js']);
var paths = ['abc/a.js', 'abc/d/e.js'];
ig.filter(paths);

Output:

[ 'abc/a.js' ]

Expected:

[]

README example broken in `3.0.3`

The example provided in the README no longer works correctly with the latest version (3.0.3).

For example, if I run the following code:

var ignore = require("ignore");
var path = require("path");

var ig = ignore().addPattern([".abc/*", "!.abc/d/*"]);

var paths = [
    path.normalize(".abc/a.js"),
    path.normalize(".abc/d/e.js")
];

console.log("paths:   ", paths);
console.log("filtered:", ig.filter(paths));

Actual Result

2.2.19:

paths:    [ '.abc/a.js', '.abc/d/e.js' ]
filtered: [ '.abc/d/e.js' ]

3.0.3:

paths:    [ '.abc/a.js', '.abc/d/e.js' ]
filtered: []

Expected:

The result from 2.2.19. Because of the splat in the first pattern, the negating pattern should be able to override it. This is in contrast to the issue in #10, whereby the entire folder is ignored without a splat.

Make `ignore` platform/os agnostic?

First thank you for making such a sick library!

https://runkit.com/neeksandhu/runkit-npm-ignore

Snippet above shows how dist/* matches dist/index.js but won't match dist\build.

A windows path being matched against a unix glob that is.

As we all know, and as mentioned in one of the previous issues here, almost all applications and programs just work given above scenario; windows paths <-> unix paths

I think there aren't any side effects if ignore is made platform agnostic as far as type of slashes are concerned.

We can very well remove process.platform === 'win32' thing in code just by using [\/\\]+ instead.

I'm trying to use ignore in a webapp where I'd love to have this feature :)

TypeScript: add support for `readonly string[]`

Both add and ignore accept an array. However, the type definitions specify that it has to be a writable array. For example:

image

I think read-only input is a valid use case, is it not? If so, I'd be happy to implement a small PR for this.

Feature request: .remove method

In order to use this in a watch mode tool, we need to be able to remove and replace rules whenever a .gitignore file is changed or even deleted.

Ignore rules containing .. as a path element

This is very minor but I'm just thinking about edge cases in guaranteeing I fully emulate git's behavior. Git seems to ignore any rules with .. as a path element, but ignore doesn't when testing a similarly relative path.

Also i.ignores('../foo') will error since the path starts with ../, but it won't error on /../ in the middle of the path.

> var i = require("ignore").default()
> i.add('test/../*')
> i.ignores('foo')
false
> i.ignores('test/../foo')
true

Whereas with this rule in .gitignore, and existing directory test and file foo in the root dir:

$ git check-ignore foo || echo not ignored
not ignored
$ git check-ignore test/../foo || echo not ignored
not ignored

4.0.0

  • fixes fnmatch(3) and glob(3)
  • make symbol non-enumerable
  • eslint
  • mocha -> tap
  • remove support for node < 6 by default
  • supports wildcard ?
  • supports *.[oa] (range)
  • supports [a-z] (character set)
  • [a-9] special cases: range out of order
  • special range: [0-z]
  • ignorecase?
  • update index.d.ts

Directory whitelisting doesn't work

Using the whitelisting pattern from https://jasonstitt.com/gitignore-whitelisting-patterns of

# Ignore everything, then add specific subtrees example
*
!*/
!/nested/file/to/whitelist

doesn't seem to work.

Example:

var ignore = require("ignore");
const ig = ignore().add(['*', '!*/', '!/foo/bar']);
const results = ['a','b/c','b/d/','foo/e','foo/bar'].forEach(p => {
  console.log([p, ig.ignores(p)]);
});
// [ 'a', true ]
// [ 'b/c', false ] this should be true
// [ 'b/d/', false ]
// [ 'foo/e', false ] this should be true
// [ 'foo/bar', false ]

Add include syntax

This package is used by various tools for parsing an ignore file. Since basically every tool, especially linter, simply needs to ignore files from .gitignore, and maybe some other files, it would be nice if they could simply include the file list from .gitignore.

In the Google Cloud SDK, this is solved using the following syntax:

#!include:.gitignore

See https://cloud.google.com/sdk/gcloud/reference/topic/gcloudignore

Currently Prettier, ESLint, and Stylelint all use separate ignore, all parsed using this package. All of their ignore files typically contain the same content.

Unable to ignore a path containing square brackets

I'm using the ESLint no-restricted-imports rule, which uses this package under the hood. I've reproduced this issue against node-ignore directly.

We have some tokens in our import paths which are denoted by square brackets. Ignoring these doesn't currently seem to work. I've escaped them in the pattern as required by gitignore (and another \ to escape the \ for JavaScript), and tried the same scenario using git check-ignore which works.

it('ignores patterns containing square brackets', () => {
  const ignorer = ignore().add(['src/\\[app\\]']);

  expect(ignorer.ignores('src/[app]')).toBe(true); // fails
});

Such paths also can't be un-ignored:

it('un-ignores negated patterns containing square brackets', () => {
  const ignorer = ignore().add(['src/**', '!src/\\[app\\]']);

  expect(ignorer.ignores('src/a')).toBe(true);
  expect(ignorer.ignores('src/[app]')).toBe(false); // fails
});

Version: 5.1.4

ignores() returns unexpected results for some ignored paths with leading "/"

Example:

const ignore = require("ignore");

let ig = ignore().add(['/abc/']) // directory in the beginning of the pathname called "abc"
ig.ignores('./abc/'); // returns false although true is expected

This works as expected using git check-ignore:

mkdir /tmp/foobar
cd /tmp/foobar
git init
echo "/abc/" > .gitignore
git check-ignore ./abc/ # returns ./abc/

Is it not possible to test .npmignore using this library?

I have an .npmignore file like this:

# Ignore everything
**
# Bring back just the "dist" folder
!/dist/**

When I do npm pack, NPM selects everything under the "dist" folder.

Whereas node-ignore does not seem to reflect this behavior:

let ig = require('ignore')();
ig.add("**");
ig.add("!/dist/**");

# --> prints: true
ig.ignores("dist/bundle.js")

Could you write up the difference of gitignore and minimatch rules?

Thank you very much for this awesome library!

I think a write-up on the difference of gitignore rules and minimatch rules would further explain why this library is necessary.

Another reason is that I want to improve how globby does globbing with ignoring gitignore patterns and only if there is a translator between these two rules sets. If you can implement yourself, that would be perfect! If not, any documentation of how it should be would be very helpful!

negative with a double glob

Following the eslint documentation I was playing around with the --ignore-pattern argument and noticed patterns with a negative and a glob were not being ignored.

I created a failing test, I can submit it as a PR if it's needed

[
  'negative with a double glob', [
    '!**/*.{test,mock}.js'
  ], {
    'a.js': 1,
    'a.test.js': 0,
    'a.mock.js': 0,
    'src/a.js': 1,
    'src/a.test.js': 0,
    'src/a.mock.js': 0,
  }
]

Ignores() seems to behave differently on windows

I notice you have a lot of similar issues related to windows paths. This one is specifically relative paths:

On unix, this throws an error.
cwd is /mnt/c/module

ignore.ignores('/mnt/c/module/package.json')

fatal error RangeError: path should be a `path.relative()`d string, but got "/mnt/c/module/package.json"

On windows it behaves differently. Possibly a false positive, but there's no error:

cwd is C:\module

ignore.ignores('C:\module\package.json')

instanceof breaks in some case

When using node-glob-gitignore, in specific circumstances I'll describe just after the line below fails and ignore rules gets ignored.

if (pattern instanceof IgnoreBase) {

When does it fails ?

Seems related to npm duplicating the dependency to ignore in my module and node-glob-gitignore. I end up with my node_modules structure having two different ignore directory and thus my instances differs what node-glob-gitignore is expecting.

Suggested fix

if (pattern instanceof IgnoreBase) { 

Would become

if (pattern && '_rules' in pattern) {

3.0.0

  • fixes excludes issues, related to #10

Need Support of pattern **folder

The pattern **folder is currently not respected. This pattern is not documented in the official git documentation here https://git-scm.com/docs/gitignore but is enforced by git and is different from the pattern **/folder.

The difference

**/subfolder \n
!folder/subfolder/testFile.txt

Will ignore the folder subfolder and the negation pattern will not work, as explained in the gitignore documentation.

It is not possible to re-include a file if a parent directory of that file is excluded.

While with those lines the file folder/subfolder/testFile.txt will be re-included as the pattern **subfolder does not match the folder subfolder but any file containing the string subfolder.

**subfolder
!folder/subfolder/testFile.txt

Actual behaviour:

const ignore = require('ignore') ;
const ig = ignore().add(['**subfolder']);

let isIgnored = ig.ignores('folder/subfolder/testFile.txt') // false

const ignore = require('ignore') ;
const ig = ignore().add(['**/subfolder']);

let isIgnored = ig.ignores('folder/subfolder/testFile.txt') // true

Expected behaviour

const ignore = require('ignore') ;
const ig = ignore().add(['**subfolder']);

let isIgnored = ig.ignores('folder/subfolder/testFile.txt') // true

const ignore = require('ignore') ;
const ig = ignore().add(['**/subfolder']);

let isIgnored = ig.ignores('folder/subfolder/testFile.txt') // true

License file

Hi, would it be possible to add a license file the npm distribute package ? If you're not including the full license text it's almost impossible to use this library in various environments.

Thank you

Warn about files ignoring themselves?

Another silly edge case. Unsurprisingly, it seems a .gitignore file can't ignore itself, but it can ignore other .gitignore files. For example the rule .gitignore won't ignore the file containing it, but it will ignore .gitignore files in subdirectories.

Since ignore only deals with rules, if one naively loads all the rules from a .gitignore file into it, ignore will think that .gitignore file is itself ignored. Especially in the worst case that there is a * rule followed by negative rules, but not !.gitignore.

I think we should add a warnings section to the README about pitfalls like this.

ignoring .git

git has its stuff in directory .git, so i guess users of git wont have to add .git to .gitignore cause git ignores it by default.

so, should this library also ignore .git by default? (v5.0.2 does not)
or should we add .git entry to our .gitignore?

Example in the git man page fails

const ignore = require('ignore')

// Patterns copied straight from the last example at the very end of
// https://git-scm.com/docs/gitignore
const ig = ignore().add([
  '# exclude everything except directory foo/bar',
  '/*',
  '!/foo',
  '/foo/*',
  '!/foo/bar',
])

const paths = [
  'no.js',
  'foo/no.js',
  'foo/bar/yes.js',
  'foo/bar/baz/yes.js',
  'boo/no.js',
]

console.log(ig.filter(paths))
// Actual: []
// Expected: ['foo/bar/yes.js', 'foo/bar/baz/yes.js']

ignore version: 3.2.0

nesting in node_modules

Why does this module nest in a node_modules folder inside the folder of a dependency in the main node_modules folder? The new behavior since npm 3.11 or something was that all the dependency would be in the main node_modules folder, no more nesting. Why does ignore not adhere to this standard?

Relative paths should be invalid

I think node-ignore should not filter relative paths starting with ./ or ../

const ignore = require('ignore');
var ig = ignore().add(['.*']);
ig.filter(['foo', '.bar', './baz', '../quuz']);

Outputs: [ 'foo' ]

Similarly, relative ignore paths should be discarded as invalid:

const ignore = require('ignore')
var ig = ignore().add(['../*'])
ig.filter(['foo', '.bar', './baz', '../quuz'])
[ 'foo', '.bar', './baz' ]

Mismatch between this package and gitignore files

Given the following reproduction:

mkdir /tmp/ignoretest
cd /tmp/ignoretest

mkdir foo
touch foo/bar.js

echo > .gitignore <<'EOT'
/*/
!/foo/
EOT

git init
git add .
git status

The foo/bar.js file got added to the repository. Doing the same on ignore, however:

const ignore = require(`ignore`);

ignore().add([
  `/*/`,
  `!/foo/`,
]).ignores(`foo/bar.js`) // true

How to check if the working directory should be ignored?

I understand that paths need to be relative to the working directory, but how do I check the working directory itself?

If I use path.relative(process.cwd(), process.cwd()) I get an empty string which is also invalid for checking.

If it is impossible to ignore the working directory I could add an if statement to don't check that case, but I am not sure if it is not possible to create a rule to skip the working directory.

And what about parent directories to the working directory, for example, ../.. should those paths have a special treatment too? Be discarded because they are invalid in terms of git ignore files?

distinguish between "unignored" and "not ignored" (so results can be combined)

I need to implement hierarchical .gitignore files for my application, and I've run into an issue trying to combine the results of multiple rulesets. My approach has been to walk down the pathname and apply .gitignore files successively.ยน However, with the current API I cannot tell whether a file is merely "not ignored" or is actually "unignored".

Here's a specific scenario:

// In real life this would be wrapped in a loop or recursion,
// I'm just hard-coding variables for demonstration purposes

rootRules = ignore().add(readFileSync('.gitignore', 'utf8')) // contains 'foo.txt'
rootIgnoredA = rules.ignores("/A/foo.txt") // true
rootIgnoredB = rules.ignores("/B/foo.txt") // true

ARules = ignore().add(readFileSync('A/.gitignore', 'utf8')) // is empty
BRules = ignore().add(readFileSync('B/.gitignore', 'utf8')) // contains '!foo.txt'
ignoredA = ARules.ignores("/A/foo.txt") // false
ignoredB = BRules.ignores("/B/foo.txt") // also false

Given the result values of both .gitignore files, there's not enough information to determine the combined result. "/A/foo.txt" should be ignored, but "/B/foo.txt" should NOT be ignored, because it was unignored.

I think the cleanest way to solve this would be to allow specifying an starting value to .ignores. Like:

ignoredA = ARules.ignores("/A/foo.txt", rootIgnoredA) // true
ignoredB = BRules.ignores("/B/foo.txt", rootIgnoredB) // false

But I would also be OK with a new function that returned a ternary value, like true/null/false or "ignored"/"nochange"/"unignored".

ยน and yes I take into account the "It is not possible to re-include a file if a parent directory of that file is excluded." by testing the rules on the parent directory first and breaking out of the loop if they match.

Incorrect filter management

Hi @kaelzhang ,

my filter:
.git
!.git/config
.ftpconfig

0: Object
    negative: false
    origin: ".git"
    pattern: ".git"
    regex: /(?:^|\/)\.git(?=$|\/)/i
1: Object
    negative: true
    origin: "!.git/config"
    pattern: ".git/config"
    regex: /^\.git\/config(?=$|\/$)/i
2: Object
    negative: false
    origin: ".ftpconfig"
    pattern: ".ftpconfig"
    regex: /(?:^|\/)\.ftpconfig(?=$|\/)/i

I use the ignores function, but result (cache):
D:/ => true
D:/DEV/ => true
D:/DEV/test/ => true
D:/DEV/test/.git/ => false
D:/DEV/test/.git/COMMIT_EDITMSG => false
D:/DEV/test/.git/packed-refs => false
D:/DEV/test/.git/config => false || False positive, because this is negative rule!

Question: How to ignore all but some files

Hi,
I use your plugin in my project. My Project is located in c:\programming\test.
I have a .ignore file in my folder root which is used by ignore like follows:

this.ignore.add(readFileSync(join(path.fsPath, ".ignore")).toString());

if( this.ignore.ignores("c:/programming/test/includes/test.log") === false )
  doSomething();

The content of my .ignore File is

*.*
!*.log

But this does ignore all files. How can I make this work?

Not working..

Just added a .gitignore file containing the following rules:

# git-ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
/.project
/.settings
/sharedTools/external/*
Thumbs.db
/packs
*.pyc
/.cache
/bigtxt
.metadata/*
*~
/sharedTools/jsApiLua.lua
._*
.DS_Store
/DISABLED
/.pydevproject
/testbox
*.swp
/packs/packagesTree
/packs/*.ini
.buildpath
/resources/hooks/*
.idea
.idea/*
/tags
**.iml
.sonar/*

And none of those files are being ignored. For example if I take out the leading slash in '/packs', it correctly ignores the packs directory.

Also, the following rules in a submodule are not working either, .js files are being ignored!

*~
._*
.DS_Store
*.pyc
.idea
.idea/*
.*.sw?

Am I doing something wrong? Do I need to send the full file path or just the base name when filtering?

Can't unignore pattern with **

This works:

const ignore = require('ignore')
var ig = ignore().add(['foo/*', '!foo/bar.js'])
ig.filter(['foo/bar.js'])
[ 'foo/bar.js' ]

This doesn't:

const ignore = require('ignore')
var ig = ignore().add(['foo/**', '!foo/bar.js'])
ig.filter(['foo/bar.js'])
[]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.