Skip to content

Commit

Permalink
refactor to use miniglob / minimatch combo, working on windows \o/
Browse files Browse the repository at this point in the history
  • Loading branch information
mklabs committed Jan 7, 2012
1 parent 58dc14a commit 5bbb1bd
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 479 deletions.
5 changes: 5 additions & 0 deletions .travis.yml
@@ -0,0 +1,5 @@
language: node_js

node_js:
- 0.4
- 0.6
6 changes: 3 additions & 3 deletions README.md
Expand Up @@ -16,7 +16,7 @@ Can be used with callback or emitter style.
* **exclude**: *optional* list of glob patterns to filter include results `foo/**/*.js *.md`
* **callback**: *optional* function that gets called with an error if something wrong happend, otherwise null with an array of results

The callback is optional since the fileset method return an instance of EventEmitter which emit different events you might use:
The callback is optional since the fileset method return an instance of EventEmitter which emit different events you might use:

* *match*: triggered on findit.file and each glob returned by node-glob, triggerd multiple times
* *includes*: array of includes files, triggered once
Expand All @@ -42,8 +42,8 @@ The callback is optional since the fileset method return an instance of EventEmi

fileset('**.coffee README.md *.json Cakefile **.js', 'node_modules')
.on('match', console.log.bind(console, 'error'))
.on('includes', console.log.bind(console, 'includes'))
.on('excludes', console.log.bind(console, 'excludes'))
.on('include', console.log.bind(console, 'includes'))
.on('exclude', console.log.bind(console, 'excludes'))
.on('end', console.log.bind(console, 'end'));

Check out the [tests](https://github.com/mklabs/node-fileset/tree/master/tests) for more examples.
Expand Down
193 changes: 62 additions & 131 deletions lib/fileset.js
@@ -1,134 +1,65 @@
(function() {
var EventEmitter, findit, fs, glob, globs, path, rsplit;
glob = require('glob');



var util = require('util'),
minimatch = require('minimatch'),
Miniglob = require('miniglob').Miniglob,
EventEmitter = require('events').EventEmitter;
path = require('path');
fs = require('fs');
findit = require('findit');
rsplit = /\s|,\s/;
module.exports = function(include, exclude, callback) {
var em, excludes, exludesLength, includes, includesLength, match;
em = new EventEmitter;
match = {
includes: [],
excludes: []
};
if (!callback && typeof exclude === 'function') {
callback = exclude;
exclude = "";
}
if (!callback && !exclude) {
exclude = "";
}
includes = include.split(rsplit).filter(function(it) {
return it;
}) || [];
excludes = exclude.split(rsplit).filter(function(it) {
return it;
}) || [];
exludesLength = excludes.length;
includesLength = includes.length;
globs(includes, em, function(err, results) {
if (err) {
if (callback) {
callback(err);
}
return em.emit('error', err);
}
match.includes = results;
em.emit('include', results);
if (!excludes.length) {
if (callback) {
callback(null, results);
}
return em.emit('end', results);
}
return globs(excludes, em, function(err, results) {
if (err) {
if (callback) {
callback(err);
}
return em.emit('error', err);
}
match.excludes = results;
em.emit('exclude', results);
match.includes = match.includes.filter(function(it) {
var dotbegin, excluded;
dotbegin = /^\./.test(it.split('/').reverse()[0]);
excluded = !!~match.excludes.indexOf(it);
return !excluded;
});
em.emit('end', match.includes);
if (callback) {
return callback(null, match.includes);
}

module.exports = fileset;

function fileset(include, exclude, cb) {
if (typeof exclude === 'function') cb = exclude, exclude = '';

var em = new EventEmitter,
includes = include.split(' '),
excludes = exclude.split(' '),
remaining = includes.length,
results = [];

if(!includes.length) return cb(new Error('Must provide an include pattern'));

em.includes = includes.map(function(pattern) {
return new fileset.Fileset(pattern)
.on('error', cb ? cb : em.emit.bind(em, 'error'))
.on('match', em.emit.bind(em, 'match'))
.on('match', em.emit.bind(em, 'include'))
.on('end', next.bind({}, pattern))
});

function next(pattern, matches) {
results = results.concat(matches);

if(!(--remaining)) {
results = results.filter(function(file) {
return !excludes.filter(function(glob) {
var match = minimatch(file, glob, { matchBase: true });
if(match) em.emit('exclude', file);
return match;
}).length;
});
});
return em;
};
globs = function(patterns, em, callback) {
var index, matches, pattern, remaining, _len, _results;
if (!patterns.length) {
return callback(new Error('patterns is empty'));
}
matches = [];
patterns = patterns.filter(function(it) {
return it;
});
remaining = patterns.length;
_results = [];
for (index = 0, _len = patterns.length; index < _len; index++) {
pattern = patterns[index];
_results.push((function(pattern, index) {
var absolute, errors, files, isGlob;
isGlob = /\*/.test(pattern);
if (isGlob) {
return glob(pattern, function(err, results) {
if (err) {
return callback(err);
}
matches = matches.concat(results.map(function(it) {
return path.resolve(it);
}));
if (--remaining === 0) {
return callback(null, matches);
}
});
}
files = [];
errors = [];
absolute = path.resolve(pattern);
return fs.stat(absolute, function(err, stat) {
if (err) {
if (--remaining === 0) {
callback(null, matches);
}
return;
}
if (stat && stat.isFile()) {
matches = matches.concat([absolute]);
if (--remaining === 0) {
callback(null, matches);
}
return;
}
return findit(absolute).on('file', function(file) {
em.emit('match', file);
return files.push(file);
}).on('error', function(err) {
return errors.push(err);
}).on('end', function() {
if (errors.length) {
return callback(new Error('findit returned with errors'), errors);
}
matches = matches.concat(files);
if (--remaining === 0) {
return callback(null, matches);
}
});
});
})(pattern, index));

if(cb) cb(null, results);
em.emit('end', results);
}
return _results;
};
}).call(this);
}

return em;
}

fileset.Fileset = function Fileset(pattern, options, cb) {

if (typeof options === 'function') cb = options, options = {};
if (!options) options = {};

Miniglob.call(this, pattern, options);

if(typeof cb === 'function') {
this.on('error', cb);
this.on('end', function(matches) { cb(null, matches); });
}
};

util.inherits(fileset.Fileset, Miniglob);


44 changes: 0 additions & 44 deletions lib/mini-fileset.js

This file was deleted.

8 changes: 4 additions & 4 deletions package.json
Expand Up @@ -8,15 +8,15 @@
"type": "git",
"url": "git://github.com/mklabs/node-fileset.git"
},
"main": "./lib/mini-fileset",
"main": "./lib/fileset",
"scripts": {
"test": "node tests/test.js"
},
"engines": {
"node": "> 0.4"
"node": "*"
},
"dependencies": {
"findit": "~0.1.2",
"minimatch": "~0.1.3"
"miniglob": "https://nodeload.github.com/isaacs/miniglob/tarball/master",
"minimatch": "https://nodeload.github.com/mklabs/minimatch/tarball/windows-path-prefixing"
}
}
70 changes: 0 additions & 70 deletions tests/callback.js

This file was deleted.

0 comments on commit 5bbb1bd

Please sign in to comment.