Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

gulp-newer

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gulp-newer - npm Package Compare versions

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.

@@ -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;

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc