broccoli-funnel
Advanced tools
Comparing version 0.2.7 to 0.2.8
47
index.js
@@ -8,2 +8,3 @@ 'use strict'; | ||
var Minimatch = require('minimatch').Minimatch; | ||
var arrayEqual = require('array-equal'); | ||
var Plugin = require('broccoli-plugin'); | ||
@@ -20,3 +21,18 @@ var symlinkOrCopy = require('symlink-or-copy'); | ||
} | ||
// copied mostly from node-glob cc @isaacs | ||
function isNotAPattern(pattern) { | ||
var set = new Minimatch(pattern).set; | ||
if (set.length > 1) { | ||
return false; | ||
} | ||
for (var j = 0; j < set[0].length; j++) { | ||
if (typeof set[0][j] !== 'string') { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
Funnel.prototype = Object.create(Plugin.prototype); | ||
@@ -40,6 +56,23 @@ Funnel.prototype.constructor = Funnel; | ||
if (this.files && !Array.isArray(this.files)) { | ||
throw new Error('Invalid files option, it must be an array.'); | ||
if (this.files && typeof this.files === 'function') { | ||
// Save dynamic files func as a different variable and let the rest of the code | ||
// still assume that this.files is always an array. | ||
this._dynamicFilesFunc = this.files; | ||
delete this.files; | ||
} else if (this.files && !Array.isArray(this.files)) { | ||
throw new Error('Invalid files option, it must be an array or function (that returns an array).'); | ||
} | ||
if ((this.files || this._dynamicFilesFunc) && (this.include || this.exclude)) { | ||
throw new Error('Cannot pass files option (array or function) and a include/exlude filter. You can only have one or the other'); | ||
} | ||
if (this.files) { | ||
if (this.files.filter(isNotAPattern).length !== this.files.length) { | ||
console.warn('broccoli-funnel does not support `files:` option with globs, please use `include:` instead'); | ||
this.include = this.files; | ||
this.files = undefined; | ||
} | ||
} | ||
this._setupFilter('include'); | ||
@@ -111,2 +144,12 @@ this._setupFilter('exclude'); | ||
if (this._dynamicFilesFunc) { | ||
this.lastFiles = this.files; | ||
this.files = this._dynamicFilesFunc() || []; | ||
// Blow away the include cache if the list of files is new | ||
if (this.lastFiles !== undefined && !arrayEqual(this.lastFiles, this.files)) { | ||
this._includeFileCache = makeDictionary(); | ||
} | ||
} | ||
var linkedRoots = false; | ||
@@ -113,0 +156,0 @@ if (this.shouldLinkRoots()) { |
{ | ||
"name": "broccoli-funnel", | ||
"version": "0.2.7", | ||
"version": "0.2.8", | ||
"description": "Broccoli plugin that allows you to filter files selected from an input node down based on regular expressions.", | ||
@@ -21,2 +21,3 @@ "main": "index.js", | ||
"dependencies": { | ||
"array-equal": "^1.0.0", | ||
"broccoli-plugin": "^1.0.0", | ||
@@ -23,0 +24,0 @@ "debug": "^2.2.0", |
@@ -249,2 +249,32 @@ 'use strict'; | ||
it('matches the deprecated: files *.css', function() { | ||
var inputPath = path.join(fixturePath, 'dir1/subdir2'); | ||
var oldWarn = console.warn; | ||
var message; | ||
console.warn = function(s) { | ||
message = arguments[0]; | ||
}; | ||
var node; | ||
try { | ||
expect(message).to.equal(undefined); | ||
node = new Funnel(inputPath, { | ||
files: ['*.css'] | ||
}); | ||
expect(message).to.equal('broccoli-funnel does not support `files:` option with globs, please use `include:` instead'); | ||
} finally { | ||
console.warn = oldWarn; | ||
} | ||
builder = new broccoli.Builder(node); | ||
return builder.build() | ||
.then(function(results) { | ||
var outputPath = results.directory; | ||
expect(walkSync(outputPath)).to.eql(['bar.css']); | ||
}); | ||
}); | ||
it('does not error with input node at a missing nested source', function() { | ||
@@ -335,2 +365,163 @@ var inputPath = path.join(fixturePath, 'dir1'); | ||
describe('`files` is incompatible with filters', function() { | ||
it('so error if `files` and `include` are set', function() { | ||
var inputPath = path.join(fixturePath, 'dir1'); | ||
expect(function() { | ||
new Funnel(inputPath, { | ||
files: ['anything'], | ||
include: ['*.txt'] | ||
}); | ||
}).to.throwException('Cannot pass files option (array or function) and a include/exlude filter. You can only have one or the other'); | ||
}); | ||
it('so error if `files` and `exclude` are set', function() { | ||
var inputPath = path.join(fixturePath, 'dir1'); | ||
expect(function() { | ||
new Funnel(inputPath, { | ||
files: function() { return ['anything']; }, | ||
exclude: ['*.md'] | ||
}); | ||
}).to.throwException('Cannot pass files option (array or function) and a include/exlude filter. You can only have one or the other'); | ||
}); | ||
}); | ||
describe('filtering with a `files` function', function() { | ||
it('can take files as a function', function() { | ||
var inputPath = path.join(fixturePath, 'dir1'); | ||
var filesCounter = 0; | ||
var filesByCounter = [ | ||
[ | ||
'subdir1/subsubdir1/foo.png', | ||
'subdir2/bar.css' | ||
], | ||
[ 'subdir1/subsubdir1/foo.png' ], | ||
[], | ||
['subdir1/subsubdir2/some.js'] | ||
]; | ||
var tree = new Funnel(inputPath, { | ||
files: function() { | ||
return filesByCounter[filesCounter++]; | ||
} | ||
}); | ||
builder = new broccoli.Builder(tree); | ||
return builder.build() | ||
.then(function(results) { | ||
var outputPath = results.directory; | ||
var expected = [ | ||
'subdir1/', | ||
'subdir1/subsubdir1/', | ||
'subdir1/subsubdir1/foo.png', | ||
'subdir2/', | ||
'subdir2/bar.css' | ||
]; | ||
expect(walkSync(outputPath)).to.eql(expected); | ||
// Build again | ||
return builder.build(); | ||
}) | ||
.then(function(results) { | ||
var outputPath = results.directory; | ||
var expected = [ | ||
'subdir1/', | ||
'subdir1/subsubdir1/', | ||
'subdir1/subsubdir1/foo.png', | ||
]; | ||
expect(walkSync(outputPath)).to.eql(expected); | ||
// Build again | ||
return builder.build(); | ||
}) | ||
.then(function(results) { | ||
var outputPath = results.directory; | ||
var expected = []; | ||
expect(walkSync(outputPath)).to.eql(expected); | ||
// Build again | ||
return builder.build(); | ||
}) | ||
.then(function(results) { | ||
var outputPath = results.directory; | ||
var expected = [ | ||
'subdir1/', | ||
'subdir1/subsubdir2/', | ||
'subdir1/subsubdir2/some.js' | ||
]; | ||
expect(walkSync(outputPath)).to.eql(expected); | ||
}); | ||
}); | ||
it('can take files as a function with exclude (includeCache needs to be cleared)', function() { | ||
var inputPath = path.join(fixturePath, 'dir1'); | ||
var filesCounter = 0; | ||
var filesByCounter = [ | ||
[], | ||
[ 'subdir1/subsubdir1/foo.png' ], | ||
[ | ||
'subdir1/subsubdir1/foo.png', | ||
'subdir2/bar.css' | ||
] | ||
]; | ||
var tree = new Funnel(inputPath, { | ||
files: function() { | ||
return filesByCounter[filesCounter++]; | ||
} | ||
}); | ||
builder = new broccoli.Builder(tree); | ||
return builder.build() | ||
.then(function(results) { | ||
var outputPath = results.directory; | ||
var expected = []; | ||
expect(walkSync(outputPath)).to.eql(expected); | ||
// Build again | ||
return builder.build(); | ||
}) | ||
.then(function(results) { | ||
var outputPath = results.directory; | ||
var expected = [ | ||
'subdir1/', | ||
'subdir1/subsubdir1/', | ||
'subdir1/subsubdir1/foo.png', | ||
]; | ||
expect(walkSync(outputPath)).to.eql(expected); | ||
// Build again | ||
return builder.build(); | ||
}) | ||
.then(function(results) { | ||
var outputPath = results.directory; | ||
var expected = [ | ||
'subdir1/', | ||
'subdir1/subsubdir1/', | ||
'subdir1/subsubdir1/foo.png', | ||
'subdir2/', | ||
'subdir2/bar.css' | ||
]; | ||
expect(walkSync(outputPath)).to.eql(expected); | ||
}); | ||
}); | ||
}); | ||
describe('include filtering', function() { | ||
@@ -337,0 +528,0 @@ function testAllIncludeMatchers(glob, regexp, func, expected) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
42093
833
7
+ Addedarray-equal@^1.0.0
+ Addedarray-equal@1.0.2(transitive)