gulp-newer
Advanced tools
Comparing version 1.1.0 to 1.2.0
154
index.js
@@ -5,2 +5,3 @@ var Transform = require('stream').Transform; | ||
var util = require('util'); | ||
var glob = require('glob'); | ||
@@ -40,2 +41,10 @@ var Q = require('kew'); | ||
if (options.extra) { | ||
if (typeof options.extra === 'string') { | ||
options.extra = [options.extra]; | ||
} else if (!Array.isArray(options.extra)) { | ||
throw new PluginError(PLUGIN_NAME, 'Requires options.extra to be a string or array'); | ||
} | ||
} | ||
/** | ||
@@ -82,2 +91,51 @@ * Path to destination directory or file. | ||
/** | ||
* Indicates that there are extra files (configuration files, etc.) | ||
* that are not to be fed into the stream, but that should force | ||
* all files to be rebuilt if *any* are older than one of the extra | ||
* files. | ||
*/ | ||
this._extraStats = null; | ||
if (options.extra) { | ||
var extraFiles = []; | ||
for (var i = 0; i < options.extra.length; ++i) { | ||
extraFiles.push(Q.nfcall(glob, options.extra[i])); | ||
} | ||
this._extraStats = Q.all(extraFiles) | ||
.then(function(fileArrays) { | ||
// First collect all the files in all the glob result arrays | ||
var allFiles = []; | ||
var i; | ||
for (i = 0; i < fileArrays.length; ++i) { | ||
allFiles = allFiles.concat(fileArrays[i]); | ||
} | ||
var extraStats = []; | ||
for (i = 0; i < allFiles.length; ++i) { | ||
extraStats.push(Q.nfcall(fs.stat, allFiles[i])); | ||
} | ||
return Q.all(extraStats); | ||
}) | ||
.then(function(resolvedStats) { | ||
// We get all the file stats here; find the *latest* modification. | ||
var latestStat = resolvedStats[0]; | ||
for (var j = 1; j < resolvedStats.length; ++j) { | ||
if (resolvedStats[j].mtime > latestStat.mtime) { | ||
latestStat = resolvedStats[j]; | ||
} | ||
} | ||
return latestStat; | ||
}) | ||
.fail(function(error) { | ||
if (error && error.path) { | ||
throw new PluginError(PLUGIN_NAME, 'Failed to read stats for an extra file: ' + error.path); | ||
} else { | ||
throw new PluginError(PLUGIN_NAME, 'Failed to stat extra files; unknown error: ' + error); | ||
} | ||
}); | ||
// When extra files are present, we buffer all the files. | ||
this._bufferedFiles = []; | ||
} | ||
} | ||
@@ -99,53 +157,59 @@ util.inherits(Newer, Transform); | ||
var self = this; | ||
this._destStats.then(function(destStats) { | ||
if ((destStats && destStats.isDirectory()) || self._ext || self._map) { | ||
// stat dest/relative file | ||
var relative = srcFile.relative; | ||
var ext = path.extname(relative); | ||
var destFileRelative = self._ext ? | ||
Q.resolve([this._destStats, this._extraStats]) | ||
.spread(function(destStats, extraStats) { | ||
if ((destStats && destStats.isDirectory()) || self._ext || self._map) { | ||
// stat dest/relative file | ||
var relative = srcFile.relative; | ||
var ext = path.extname(relative); | ||
var destFileRelative = self._ext ? | ||
relative.substr(0, relative.length - ext.length) + self._ext : | ||
relative; | ||
if (self._map) { | ||
destFileRelative = self._map(destFileRelative); | ||
} | ||
var destFileJoined = self._dest ? | ||
if (self._map) { | ||
destFileRelative = self._map(destFileRelative); | ||
} | ||
var destFileJoined = self._dest ? | ||
path.join(self._dest, destFileRelative) : destFileRelative; | ||
return Q.nfcall(fs.stat, destFileJoined); | ||
} else { | ||
// wait to see if any are newer, then pass through all | ||
if (!self._bufferedFiles) { | ||
self._bufferedFiles = []; | ||
return Q.all([Q.nfcall(fs.stat, destFileJoined),extraStats]); | ||
} else { | ||
// wait to see if any are newer, then pass through all | ||
if (!self._bufferedFiles) { | ||
self._bufferedFiles = []; | ||
} | ||
return [destStats, extraStats]; | ||
} | ||
return Q.resolve(destStats); | ||
} | ||
}).fail(function(err) { | ||
if (err.code === 'ENOENT') { | ||
// dest file or directory doesn't exist, pass through all | ||
return Q.resolve(null); | ||
} else { | ||
// unexpected error | ||
return Q.reject(err); | ||
} | ||
}).then(function(destFileStats) { | ||
var newer = !destFileStats || srcFile.stat.mtime > destFileStats.mtime; | ||
if (self._all) { | ||
self.push(srcFile); | ||
} else if (!newer) { | ||
if (self._bufferedFiles) { | ||
self._bufferedFiles.push(srcFile); | ||
}).fail(function(err) { | ||
if (err.code === 'ENOENT') { | ||
// dest file or directory doesn't exist, pass through all | ||
return Q.resolve([null,this._extraStats]); | ||
} else { | ||
// unexpected error | ||
return Q.reject(err); | ||
} | ||
} else { | ||
if (self._bufferedFiles) { | ||
// flush buffer | ||
self._bufferedFiles.forEach(function(file) { | ||
self.push(file); | ||
}); | ||
self._bufferedFiles.length = 0; | ||
// pass through all remaining files as well | ||
self._all = true; | ||
}).spread(function(destFileStats, extraFileStats) { | ||
var newer = !destFileStats || srcFile.stat.mtime > destFileStats.mtime; | ||
// If *any* extra file is newer than a destination file, then ALL | ||
// are newer. | ||
if (extraFileStats && extraFileStats.mtime > destFileStats.mtime) { | ||
newer = true; | ||
} | ||
self.push(srcFile); | ||
} | ||
done(); | ||
}).fail(done).end(); | ||
if (self._all) { | ||
self.push(srcFile); | ||
} else if (!newer) { | ||
if (self._bufferedFiles) { | ||
self._bufferedFiles.push(srcFile); | ||
} | ||
} else { | ||
if (self._bufferedFiles) { | ||
// flush buffer | ||
self._bufferedFiles.forEach(function(file) { | ||
self.push(file); | ||
}); | ||
self._bufferedFiles.length = 0; | ||
// pass through all remaining files as well | ||
self._all = true; | ||
} | ||
self.push(srcFile); | ||
} | ||
done(); | ||
}).fail(done).end(); | ||
@@ -152,0 +216,0 @@ }; |
{ | ||
"name": "gulp-newer", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "Only pass through newer source files", | ||
@@ -31,6 +31,5 @@ "homepage": "https://github.com/tschaub/gulp-newer", | ||
"chai": "^3.4.0", | ||
"eslint": "^1.7.3", | ||
"eslint-config-tschaub": "^2.0.0", | ||
"eslint": "^2.11.1", | ||
"eslint-config-tschaub": "^4.0.0", | ||
"gulp": "^3.9.0", | ||
"jshint": "~2.5.10", | ||
"mocha": "^2.3.3", | ||
@@ -40,5 +39,6 @@ "mock-fs": "^3.4.0" | ||
"dependencies": { | ||
"kew": "^0.7.0", | ||
"gulp-util": "^3.0.7" | ||
"glob": "^7.0.3", | ||
"gulp-util": "^3.0.7", | ||
"kew": "^0.7.0" | ||
} | ||
} |
@@ -73,2 +73,3 @@ # `gulp-newer` | ||
* **options.map** - `function` Map relative source paths to relative destination paths (e.g. `function(relativePath) { return relativePath + '.bak'; }`) | ||
* **options.extra** - `string` or `array` An extra file, file glob, or list of extra files and/or globs, to check for updated time stamp(s). If any of these files are newer than the destination files, then all source files will be passed into the stream. | ||
@@ -75,0 +76,0 @@ Create a [transform stream](http://nodejs.org/api/stream.html#stream_class_stream_transform_1) that passes through files whose modification time is more recent than the corresponding destination file's modification time. |
77
spec.js
@@ -91,2 +91,77 @@ /* eslint-env mocha */ | ||
describe('config.extra', function() { | ||
beforeEach(function() { | ||
mock({ | ||
main: mock.file({ | ||
content: 'main content', | ||
mtime: new Date(1) | ||
}), | ||
imported: mock.file({ | ||
content: '2: other content, used by main', | ||
mtime: new Date(3) | ||
}), | ||
collected: mock.file({ | ||
content: 'main content\n1: other content, used by main', | ||
mtime: new Date(2) | ||
}) | ||
}); | ||
}); | ||
afterEach(mock.restore); | ||
it('must be a string or an array', function() { | ||
assert.throws(function() { | ||
newer({dest: 'foo', extra: 1}); | ||
}); | ||
assert.throws(function() { | ||
newer({dest: 'foo', extra: function() {}}); | ||
}); | ||
assert.doesNotThrow(function() { | ||
newer({dest: 'foo', extra: 'extra1'}); | ||
}); | ||
assert.doesNotThrow(function() { | ||
newer({dest: 'foo', extra: ['extra1', 'extra2']}); | ||
}); | ||
}); | ||
it('must not be passed into stream', function(done) { | ||
var stream = newer({dest: 'collected', extra: 'imported'}); | ||
var paths = ['main']; | ||
stream.on('data', function(file) { | ||
assert.notEqual(file.path, path.resolve('imported')); | ||
}); | ||
stream.on('error', done); | ||
stream.on('end', done); | ||
write(stream, paths); | ||
}); | ||
it('must let other files through stream if an "extra" is newer', function(done) { | ||
var stream = newer({dest: 'collected', extra: 'imported'}); | ||
var paths = ['main']; | ||
var calls = 0; | ||
stream.on('data', function(file) { | ||
assert.equal(file.path, path.resolve(paths[calls])); | ||
++calls; | ||
}); | ||
stream.on('error', done); | ||
stream.on('end', function() { | ||
assert.equal(calls, paths.length); | ||
done(); | ||
}); | ||
write(stream, paths); | ||
}); | ||
}); | ||
describe('dest dir that does not exist', function() { | ||
@@ -521,3 +596,3 @@ | ||
var calls = 0; | ||
stream.on('data', function(file) { | ||
stream.on('data', function() { | ||
done(new Error('Expected no source files')); | ||
@@ -524,0 +599,0 @@ ++calls; |
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
28574
6
815
82
3
+ Addedglob@^7.0.3
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedwrappy@1.0.2(transitive)