Socket
Socket
Sign inDemoInstall

ignore

Package Overview
Dependencies
0
Maintainers
1
Versions
88
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.2 to 1.1.3

.travis.yml

289

index.js
'use strict';
module.exports = ignore;
ignore.Ignore = Ignore;
var Readable = require('stream').Readable;
var node_util = require('util');
var node_fs = require('fs');
var node_path = require('path');
var glob = require('glob');
var EE = require('events').EventEmitter;
var node_util = require('util');
var ignoreRules = require('ignore-rules');
function ignore (options) {
function ignore (options){
return new Ignore(options);
}
ignore.Ignore = Ignore;
// Select the first existing file of the file list
ignore.select = function (files) {
var exists;
// @param {Object} options
// - ignore: {Array}
// - twoGlobstars: {boolean=false} enable pattern '`**`' (two consecutive asterisks), default to `false`.
// If false, ignore patterns with two globstars will be omitted
// - noCase: {boolean=true} case sensitive.
// By default, git is case-insensitive
function Ignore (options){
options = options || {};
options.noCase = 'noCase' in options ? options.noCase : true;
files.some(function (file) {
if( node_fs.existsSync(file) ){
exists = file;
return true;
}
});
this.options = options;
this._patterns = [];
this._rules = [];
return exists;
};
this.add(options.ignore);
}
// Events:
// 'warn': ,
// will warn when encounter '`**`' (two consecutive asterisks)
// which is not compatible with all platforms (not works on Mac OS for example)
node_util.inherits(Ignore, EE);
function Ignore (options) {
options = options || {};
function makeArray (subject) {
return Array.isArray(subject) ?
subject :
subject === undefined || subject === null ?
[] :
[subject];
}
Readable.call(this, options);
this.cwd = options.cwd ?
node_path.resolve(options.cwd) :
process.cwd();
this.options = options;
// @param {Array.<string>|string} pattern
Ignore.prototype.add = function(pattern) {
makeArray(pattern).forEach(this._add, this);
return this;
};
options.ignore = options.ignore || [
// Some files or directories which we should ignore for most cases.
'.git',
'.svn',
'.DS_Store'
];
this.ignoreRules = ignoreRules(options);
this.ignoreFiles = [];
this.addRuleFiles(options.ignoreFiles);
Ignore.prototype.filter = function(paths) {
return paths.filter(this._filter, this);
};
node_util.inherits(Ignore, Readable);
// @implementation
// stream.Readable interface
Ignore.prototype._read = function(size) {
// body...
Ignore.prototype._add = function(pattern) {
if(this._simpleTest(pattern)){
var rule = this._createRule(pattern);
this._rules.push(rule);
}
};
Ignore.prototype._simpleTest = function(pattern) {
var pass =
// Whitespace dirs are allowed, so only filter blank pattern.
pattern &&
// And not start with a '#'
pattern.indexOf('#') !== 0 &&
// @param {Array} files
Ignore.prototype.filter = function(files) {
return this.ignoreRules.filter(files);
};
! ~ this._patterns.indexOf(pattern);
this._patterns.push(pattern);
// get filtered files
Ignore.prototype.filtered = function(callback) {
var self = this;
if( ~ pattern.indexOf('**') ){
this.emit('warn', {
code: 'WGLOBSTARS',
data: {
pattern: origin
},
message: '`**` found, which is not compatible cross all platforms.'
});
this._filelist(function (err, files) {
if(err){
return callback(err);
if(!this.options.twoGlobstars){
return false;
}
}
callback(null, self.filter(files));
});
return pass;
};
var REGEX_LEADING_EXCLAMATION = /^\\\!/;
var REGEX_LEADING_HASH = /^\\#/;
Ignore.prototype._filelist = function(callback) {
glob('**/*', {
cwd: this.cwd,
Ignore.prototype._createRule = function(pattern) {
var rule_object = {
origin: pattern
};
// Includes files which start with '.'
dot: this.options.dot,
var match_start;
// Add a / character to directory matches
// i.e. [
// 'foo/',
// 'foo/a.js'
// ]
// instead of [
// 'foo',
// 'foo/a.js'
// ]
mark: true
if(pattern.indexOf('!') === 0){
rule_object.negative = true;
pattern = pattern.substr(1);
}
}, callback);
};
pattern = pattern
.replace(REGEX_LEADING_EXCLAMATION, '!')
.replace(REGEX_LEADING_HASH, '#');
rule_object.pattern = pattern;
Ignore.prototype.addRules = function (rules) {
this.ignoreRules.add(rules);
return this;
rule_object.regex = this.makeRegex(pattern);
return rule_object;
};
// > If the pattern ends with a slash, it is removed for the purpose of the following description, but it would only find a match with a directory. In other words, foo/ will match a directory foo and paths underneath it, but will not match a regular file or a symbolic link foo (this is consistent with the way how pathspec works in general in Git).
// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`'
// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call
// you could use option `mark: true` with `glob`
// @param {Array.<path>|path} a
Ignore.prototype.addRuleFiles = function(files) {
makeArray(files).forEach(this._addRuleFile, this);
return this;
};
// '`foo/`' should not continue with the '`..`'
var REPLACERS = [
// leading slash
[
// > A leading slash matches the beginning of the pathname. For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
// A leading slash matches the beginning of the pathname
/^\//,
'^'
],
Ignore.prototype._addRuleFile = function (file) {
if(this._checkRuleFile(file)){
this.ignoreFiles.push(file);
[
// > A leading "**" followed by a slash means match in all directories. For example, "**/foo" matches file or directory "foo" anywhere, the same as pattern "foo". "**/foo/bar" matches file or directory "bar" anywhere that is directly under directory "foo".
/\*\*\//,
// make sure `file` is an absolute path
file = node_path.resolve(this.cwd, file);
// '**/foo' <-> 'foo'
// just remove it
''
],
var content;
// 'f'
// matches
// - /f(end)
// - /f/
// - (start)f(end)
// - (start)f/
// doesn't match
// - oof
// - foo
// pseudo:
// -> (^|/)f(/|$)
try {
content = node_fs.readFileSync(file);
} catch(e) {
// ending
[
// 'js' will not match 'js.'
/(?:[^*\/])$/,
function (match1) {
return match1 + '(?=$|\\/)';
}
],
if(content){
this.addRules( content.toString().split(/\r?\n/) );
// starting
[
// there will be no leading '/' (which has been replaced by the first replacer)
// If starts with '**', adding a '^' to the regular expression also works
/^(?=[^\^])/,
'(?:^|\\/)'
],
// two globstars
[
// > A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.
// '/**/'
/\/\*\*\//g,
// Zero, one or several directories
// should not use '*', or it will be replaced by the next replacer
'(?:\\/[^\\/]+){0,}\\/'
],
// wildcard
[
/\*+/g,
// 'abc/*.js' matches 'abc/...js'
'[^\\/]*'
]
];
// @param {pattern}
Ignore.prototype.makeRegex = function(pattern) {
var source = REPLACERS.reduce(function (prev, current) {
return prev.replace( current[0], current[1] );
}, pattern);
return new RegExp(source, this.options.noCase ? 'i' : '');
};
Ignore.prototype._filter = function(path) {
var rules = this._rules;
var i = 0;
var length = rules.length;
var matched;
var rule;
for(; i < length; i ++){
rule = rules[i];
// if matched = true, then we only test negative rules
// if matched = false, then we test non-negative rules
if( !( matched ^ rule.negative ) ){
matched = rule.negative ^ rule.regex.test(path);
}else{
continue;
}
}
return !matched;
};
Ignore.prototype._checkRuleFile = function(file) {
return file !== '.' &&
file !== '..' &&
! ~ this.ignoreFiles.indexOf(file);
Ignore.prototype.createFilter = function() {
var self = this;
return function (path) {
return self._filter(path);
};
};
function makeArray (subject) {
return Array.isArray(subject) ?
subject :
subject === undefined || subject === null ?
[] :
[subject];
}
{
"name": "ignore",
"version": "0.1.2",
"description": "Ignore is a lightweight readable stream(not implemented until 0.2.x) to apply minimatch ignore rules (like .gitignore). And it is also has util methods to get filtered files and directories.",
"version": "1.1.3",
"description": "Ignore is a manager and filter for .gitignore rules.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "mocha"
},
"repository": {
"type": "git",
"url": "git://github.com/kaelzhang/ignore.git"
"url": "git@github.com:kaelzhang/node-ignore.git"
},
"keywords": [
"ignore",
"ignore-rules",
"ignore-files",
"readable",
"stream",
"minimatch"
".gitignore",
"gitignore",
"rules",
"manager",
"filter",
"regexp",
"regex",
"regular-expression"
],

@@ -24,11 +27,9 @@ "author": "kael",

"bugs": {
"url": "https://github.com/kaelzhang/ignore/issues"
"url": "https://github.com/kaelzhang/node-ignore/issues"
},
"dependencies": {
"glob": "~3.2.6",
"ignore-rules": "~0.1.0"
},
"dependencies": {},
"devDependencies": {
"chai": "~1.7.2"
"chai": "~1.7.2",
"mocha": "~1.13.0"
}
}

@@ -1,99 +0,94 @@

# Ignore
[![Build Status](https://travis-ci.org/kaelzhang/node-ignore.png?branch=master)](https://travis-ci.org/kaelzhang/node-ignore)
Ignore is a lightweight node.js readable stream (** won't implemented until 0.2.x **) to apply minimatch ignore rules (like .gitignore).
# ignore
And it also has some utility methods to get filtered files and directories.
`ignore` is a manager and filter for .gitignore rules.
## Installation
# Installation
npm install ignore --save
## Usage
# Usage
```js
var ignore = require('ignore');
```
var ig = ignore({
ignore: [
'.abc/*' // or use the `.add()` method
]
### Filter the given paths
}).add('!.abc/d/');
```js
var filtered = ignore({
ignore: [
'.abc/*',
'!.abc/d/'
]
}).filter([
'.abc',
'.abc/a.js',
'.abc/d/e.js'
]);
var paths = [
'.abc/a.js', // filtered out
'.abc/d/e.js' // included
];
console.log(filtered); // ['.abc/d/e.js'];
ig.filter(paths); // ['.abc/d/e.js']
paths.filter(ig.createFilter()); // ['.abc/d/e.js']
```
### Filter the cwd
# Why another ignore?
```js
ignore({
cwd: '/path/to/cwd/',
ignoreFiles: [
'.gitignore'
],
// include files each of which starts with a `'.'`
dot: true
}).filtered(function(err, files){
console.log(files);
});
```
1. `ignore` is a standalone module, and is much simpler so that it could easily work with other programs, unlike [isaacs](https://npmjs.org/~isaacs)'s [fstream-ignore](https://npmjs.org/package/fstream-ignore) which must work with the modules of the fstream family.
## Methods
2. `ignore` only contains utility methods to filter paths according to the specified ignore rules.
### ignore(options)
3. Exactly according to [gitignore man page](http://git-scm.com/docs/gitignore), fixes some known matching issues of fstream-ignore, such as:
- '`/*.js`' should match '`a.js`', but not '`abc/a.js`'.
- '`**/foo`' should match '`foo`' anywhere.
##### options.ignoreFiles `Array`
The array of ignore files.
##### options.ignore `Array`
# Methods
The array of ignore rules.
## .add(rule)
Notice that the rules of `options.ignore` will be added before the `options.ignoreFiles`, so `options.ignore` has much lower priority.
Adds a rule or several rules to the current manager.
##### options.dot `boolean=false`
#### Returns `this`
Include .(dot) files in normal matches and globstar matches. Note that an explicit dot in a portion of the pattern will always match dot files.
#### Rule `String|Array.<String>`
##### options.`<xxxxx>`
The ignore rule or a array of rules.
Other [`ignore-rules`](https://github.com/kaelzhang/ignore-rules) options.
## .filter(paths)
### .filter(paths)
Filters the given array of pathnames, and returns the filtered array.
##### paths `Array.<String>`
#### paths `Array`
The array of paths to be filtered
### .filtered(callback)
## .createFilter()
Get all filtered pathnames(files and directories) inside the `options.cwd`, according to the `options.ignoreFiles` and `options.ignore`.
Creates a filter function which could be used with `Array.prototype.filter`.
##### callback `function(err, paths)`
#### Returns `function(path)`
##### paths `Array`
The filter function.
The array of filtered pathnames
### .addRuleFiles(files)
# Constructor: ignore.Ignore
##### files `String|Array.<String>`
```js
new ignore.Ignore(options);
ignore(options);
```
Add one or more ignore files
#### options.noCase `boolean=true`
### .addRules(rules)
By default, all ignore rules will be treated as case-insensitive ones as well as the git does.
##### rules `String|Array.<String>`
#### options.twoGlobstars `boolean=false`
Add one or more ignore rules
By defailt, `ignoreRules` will omit every pattern that includes '`**`' (two consecutive asterisks) which is not compatible cross operating systems, because the behavior of file .gitignore depends on the implementation of command `fnmatch` in shell.
By the way, Mac OS doesn't support '`**`'.
#### options.ignore `Array.<String>`
The ignore rules to be added.
You can also use `.add()` method to do this.
'use strict';
var ignore = require('../');
var node_path = require('path');
var expect = require('chai').expect;
describe("could apply ignoreRules", function(){
it("could has exceptions of ignore rules ", function(){
var filtered = ignore({
describe(".makeRegex(), normal options, pattern 'foo':", function(){
var ig = ignore();
var r_foo = ig.makeRegex('foo');
it("'foo' should match 'foo'", function(){
expect( r_foo.test('foo') ).to.equal(true);
});
it("'foo' should match 'foo/'", function(){
expect( r_foo.test('foo/') ).to.equal(true);
});
it("'foo' should match '/foo'", function(){
expect( r_foo.test('/foo') ).to.equal(true);
});
it("'foo' should not match 'fooo'", function(){
expect( r_foo.test('fooo') ).to.equal(false);
});
it("'foo' should not match 'ofoo'", function(){
expect( r_foo.test('ofoo') ).to.equal(false);
});
});
describe(".makeRegex(), normal options, pattern '**/foo' matches 'foo' anywhere:", function(){
var ig = ignore();
var r_foo = ig.makeRegex('**/foo');
it("'**/foo' should match 'foo'", function(){
expect( r_foo.test('foo') ).to.equal(true);
});
it("'**/foo' should match 'foo/'", function(){
expect( r_foo.test('foo/') ).to.equal(true);
});
it("'**/foo' should match '/foo'", function(){
expect( r_foo.test('/foo') ).to.equal(true);
});
it("'**/foo' should not match 'fooo'", function(){
expect( r_foo.test('fooo') ).to.equal(false);
});
it("'**/foo' should not match 'ofoo'", function(){
expect( r_foo.test('ofoo') ).to.equal(false);
});
});
describe(".makeRegex(), normal options, pattern 'foo/':", function(){
var ig = ignore();
var r_foo_slash = ig.makeRegex('foo/');
it("'foo' should match 'foo/'", function(){
expect( r_foo_slash.test('foo/') ).to.equal(true);
});
it("'foo' should match 'foo/a'", function(){
expect( r_foo_slash.test('foo/a') ).to.equal(true);
});
it("'foo' should match '/foo/'", function(){
expect( r_foo_slash.test('/foo/') ).to.equal(true);
});
it("'foo' should not match 'foo'", function(){
expect( r_foo_slash.test('foo') ).to.equal(false);
});
it("'foo' should not match '/foo'", function(){
expect( r_foo_slash.test('/foo') ).to.equal(false);
});
});
describe(".makeRegex(), normal options, pattern '/.js':", function(){
var ig = ignore();
var r_slash_dot_js = ig.makeRegex('/.js');
it("collection:", function(){
expect( r_slash_dot_js.test('.js') ).to.equal(true);
expect( r_slash_dot_js.test('.js/') ).to.equal(true);
expect( r_slash_dot_js.test('.js/a') ).to.equal(true);
expect( r_slash_dot_js.test('/.js') ).to.equal(false);
expect( r_slash_dot_js.test('.jsa') ).to.equal(false);
});
});
describe(".makeRegex(), normal options, pattern '/*.js':", function(){
var ig = ignore();
var r_slash_wild_dot_js = ig.makeRegex('/*.js');
it("collection:", function(){
expect( r_slash_wild_dot_js.test('.js') ).to.equal(true);
expect( r_slash_wild_dot_js.test('.js/') ).to.equal(true);
expect( r_slash_wild_dot_js.test('.js/a') ).to.equal(true);
expect( r_slash_wild_dot_js.test('a.js/a') ).to.equal(true);
expect( r_slash_wild_dot_js.test('a.js/a.js') ).to.equal(true);
expect( r_slash_wild_dot_js.test('/.js') ).to.equal(false);
expect( r_slash_wild_dot_js.test('.jsa') ).to.equal(false);
});
});
describe(".makeRegex(), normal options, pattern '*.js':", function(){
var ig = ignore();
var r_wild_dot_js = ig.makeRegex('*.js');
it("collection:", function(){
expect( r_wild_dot_js.test('.js') ).to.equal(true);
expect( r_wild_dot_js.test('.js/') ).to.equal(true);
expect( r_wild_dot_js.test('.js/a') ).to.equal(true);
expect( r_wild_dot_js.test('a.js/a') ).to.equal(true);
expect( r_wild_dot_js.test('a.js/a.js') ).to.equal(true);
expect( r_wild_dot_js.test('/.js') ).to.equal(true);
expect( r_wild_dot_js.test('.jsa') ).to.equal(false);
});
});
describe(".makeRegex(), normal options, pattern '.js*':", function(){
var ig = ignore();
var r_dot_js_wild = ig.makeRegex('.js*');
it("collection:", function(){
expect( r_dot_js_wild.test('.js') ).to.equal(true);
expect( r_dot_js_wild.test('.js/') ).to.equal(true);
expect( r_dot_js_wild.test('.js/a') ).to.equal(true);
// pay attension
expect( r_dot_js_wild.test('a.js/a') ).to.equal(false);
expect( r_dot_js_wild.test('a.js/a.js') ).to.equal(false);
expect( r_dot_js_wild.test('/.js') ).to.equal(true);
expect( r_dot_js_wild.test('.jsa') ).to.equal(true);
});
});
describe(".makeRegex(), normal options, pattern 'foo/**/':", function(){
var ig = ignore();
var r_foo_globstar_slash = ig.makeRegex('foo/**/');
it("should match 'foo/'", function(){
expect( r_foo_globstar_slash.test('foo/') ).to.equal(true);
});
it("should match 'foo/abc/'", function(){
expect( r_foo_globstar_slash.test('foo/abc/') ).to.equal(true);
});
it("should match 'foo/x/y/z/'", function(){
expect( r_foo_globstar_slash.test('foo/x/y/z/') ).to.equal(true);
});
it("should match 'foo/x/y/z/'", function(){
expect( r_foo_globstar_slash.test('foo/x/y/z/') ).to.equal(true);
});
it("should not match 'foo'", function(){
expect( r_foo_globstar_slash.test('foo') ).to.equal(false);
});
it("should not match '/foo'", function(){
expect( r_foo_globstar_slash.test('/foo') ).to.equal(false);
});
});
describe(".filter()", function(){
it("could filter paths", function(){
var ig = ignore({
ignore: [
'.abc/*',
'!.abc/d/'
'abc',
'!abc/b'
]
});
}).filter([
'.abc/abc.js',
'.abc/d/e.js'
var filtered = ig.filter([
'abc/a.js',
'abc/b/b.js'
]);
expect(filtered).to.deep.equal(['.abc/d/e.js']);
expect(filtered).to.deep.equal(['abc/b/b.js']);
});
});
it("could read rules from the ignore file", function(){
var filtered = ignore({
cwd: node_path.join(__dirname, 'fixtures'),
ignoreFiles: [
'.ignore'
],
// include files each of which starts with a `'.'`
dot: true
}).filter([
'.abc/abc.js',
'.abc/d/e.js',
'.blah'
]);
describe(".createFilter()", function(){
it("basic usage", function(){
var ig = ignore({
ignore: [
'abc',
'!abc/b'
]
});
expect(filtered).to.deep.equal(['.abc/d/e.js']);
var filtered = [
'abc/a.js',
'abc/b/b.js'
].filter(ig.createFilter());
expect(filtered).to.deep.equal(['abc/b/b.js']);
});
it("will ignore comments", function(){
it("test context", function(){
var ig = ignore({
cwd: node_path.join(__dirname, 'fixtures'),
ignoreFiles: [
'.ignore2'
],
ignore: [
'abc',
'!abc/b'
]
});
ignore: [],
var filtered = [
'abc/a.js',
'abc/b/b.js'
].filter(ig.createFilter(), []);
// include files each of which starts with a `'.'`
dot: true
expect(filtered).to.deep.equal(['abc/b/b.js']);
});
});
describe("_private properties", function(){
describe("constructor", function(){
it("will not mess up, if `options.ignore` not specified", function(){
var ig = ignore();
expect(ig._patterns.length).to.equal(0);
expect(ig._rules.length).to.equal(0);
});
});
});
var files = [
'.abc/abc.js',
'.abc/d/e.js',
'.blah'
];
var filtered = ig.filter(files);
describe(".add()", function(){
it(".add(rule), chained", function(){
var ig = ignore().add('abc').add('!abc/b');
expect(filtered).to.deep.equal(['.abc/d/e.js', '.blah']);
var filtered = [
'abc/a.js',
'abc/b/b.js'
].filter(ig.createFilter());
expect(filtered).to.deep.equal(['abc/b/b.js']);
});
});
describe("could filtered the cwd with the specified ignore files", function(){
it("could read files list from the cwd", function(done){
ignore({
cwd: node_path.join(__dirname, 'fixtures'),
ignoreFiles: [
'.ignore3'
],
// include files each of which starts with a `'.'`
dot: true
it(".add(rule), chained", function(){
var ig = ignore().add(['abc', '!abc/b']);
}).filtered(function (err, filtered) {
expect(err).to.equal(null);
var filtered = [
'abc/a.js',
'abc/b/b.js'
].filter(ig.createFilter());
done();
});
expect(filtered).to.deep.equal(['abc/b/b.js']);
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc