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

grunt-newer

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

grunt-newer - npm Package Compare versions

Comparing version 0.6.1 to 0.7.0

.cache/cafemocha/all/timestamp

61

lib/util.js

@@ -12,2 +12,3 @@ var crypto = require('crypto');

* @param {Date} time The comparison time.
* @param {function(string, Date, function(boolean))} override Override.
* @param {function(Err, Array.<string>)} callback Callback called with any

@@ -17,3 +18,3 @@ * error and a list of files that have mtimes newer than the provided time.

var filterPathsByTime = exports.filterPathsByTime = function(paths, time,
callback) {
override, callback) {
async.map(paths, fs.stat, function(err, stats) {

@@ -23,5 +24,17 @@ if (err) {

}
callback(null, paths.filter(function(filePath, index) {
return stats[index].mtime > time;
}));
var olderPaths = [];
var newerPaths = paths.filter(function(filePath, index) {
var newer = stats[index].mtime > time;
if (!newer) {
olderPaths.push(filePath);
}
return newer;
});
async.filter(olderPaths, function(filePath, include) {
override(filePath, time, include);
}, function(overrides) {
callback(null, newerPaths.concat(overrides));
});
});

@@ -35,2 +48,3 @@ };

* @param {Date} time The comparison time.
* @param {function(string, Date, function(boolean))} override Override.
* @param {function(Err, boolean)} callback Callback called with any error and

@@ -40,3 +54,3 @@ * a boolean indicating whether any one of the supplied files is newer than

*/
var anyNewer = exports.anyNewer = function(paths, time, callback) {
var anyNewer = exports.anyNewer = function(paths, time, override, callback) {
var complete = 0;

@@ -50,8 +64,15 @@ function iterate() {

return callback(null, true);
} else {
override(paths[complete], time, function(include) {
if (include) {
callback(null, true);
} else {
++complete;
if (complete >= paths.length) {
return callback(null, false);
}
iterate();
}
});
}
++complete;
if (complete >= paths.length) {
return callback(null, false);
}
iterate();
});

@@ -71,2 +92,3 @@ }

* @param {Date} previous Comparison time.
* @param {function(string, Date, function(boolean))} override Override.
* @param {function(Error, Array.<Object>)} callback Callback called with

@@ -77,3 +99,3 @@ * modified file config objects. Objects with no more src files are

var filterFilesByTime = exports.filterFilesByTime = function(files, previous,
callback) {
override, callback) {
async.map(files, function(obj, done) {

@@ -88,10 +110,11 @@ if (obj.dest) {

// when src and dest are same, compare to previous
return filterPathsByTime(obj.src, previous, function(err, src) {
if (err) {
return done(err);
}
done(null, {src: src, dest: obj.dest});
});
return filterPathsByTime(obj.src, previous, override,
function(err, src) {
if (err) {
return done(err);
}
done(null, {src: src, dest: obj.dest});
});
}
return anyNewer(obj.src, stats.mtime, function(err, any) {
return anyNewer(obj.src, stats.mtime, override, function(err, any) {
done(err, any && obj);

@@ -101,3 +124,3 @@ });

} else {
filterPathsByTime(obj.src, previous, function(err, src) {
filterPathsByTime(obj.src, previous, override, function(err, src) {
if (err) {

@@ -104,0 +127,0 @@ return done(err);

{
"name": "grunt-newer",
"description": "Run Grunt tasks with only those source files modified since the last successful run.",
"version": "0.6.1",
"version": "0.7.0",
"homepage": "https://github.com/tschaub/grunt-newer",

@@ -33,9 +33,9 @@ "author": {

"grunt": "0.4.2",
"grunt-cli": "0.1.11",
"grunt-cli": "0.1.13",
"grunt-contrib-watch": "0.5.3",
"grunt-contrib-jshint": "0.7.2",
"chai": "1.8.1",
"grunt-cafe-mocha": "0.1.10",
"wrench": "1.5.4",
"tmp": "0.0.21",
"grunt-contrib-jshint": "0.8.0",
"chai": "1.9.0",
"grunt-cafe-mocha": "0.1.11",
"wrench": "1.5.7",
"tmp": "0.0.23",
"grunt-contrib-clean": "0.5.0",

@@ -54,5 +54,5 @@ "mock-fs": "2.x"

"dependencies": {
"async": "0.2.9",
"rimraf": "2.2.4"
"async": "0.2.10",
"rimraf": "2.2.6"
}
}

@@ -105,3 +105,3 @@ # grunt-newer

In most cases, you shouldn't need to add any special configuration for the `newer` task. Just `grunt.loadNpmTasks('grunt-newer')` and you can use `newer` as a prefix to your other tasks. The single option below is available if you need a custom configuration.
In most cases, you shouldn't need to add any special configuration for the `newer` task. Just `grunt.loadNpmTasks('grunt-newer')` and you can use `newer` as a prefix to your other tasks. The options below are available for advanced usage.

@@ -126,2 +126,33 @@ #### <a id="optionscache">options.cache</a>

#### <a id="optionsoverride">options.override</a>
* type: `function(Object, function(boolean))`
* default: `null`
The `newer` task determines which files to include for a specific task based on file modification time. There are occassions where you may want to include a file even if it has not been modified. For example, if a LESS file imports some other files, you will want to include it if any of the imports have been modified. To support this, you can provide an `override` function that takes two arguments:
* **details** - `Object`
* **task** - `string` The currently running task name.
* **target** - `string` The currently running target name.
* **path** - `string` The path to a `src` file that appears to be "older" (not modified since the time below).
* **time** - `Date` The comparison time. For tasks with `dest` files, this is the modification time of the `dest` file. For tasks without `dest` files, this is the last successful run time of the same task.
* **include** - `function(boolean)` A callback that determines whether this `src` file should be included. Call with `true` to include or `false` to exclude the file.
Example use of the `override` option:
```js
grunt.initConfig({
newer: {
options: {
override: function(detail, include) {
if (detail.task === 'less') {
checkForModifiedImports(detail.path, detail.time, include);
} else {
include(false);
}
}
}
}
});
```
## That's it

@@ -128,0 +159,0 @@

@@ -27,10 +27,14 @@ var fs = require('fs');

function nullOverride(details, include) {
include(false);
}
function createTask(grunt) {
return function(name, target) {
return function(taskName, targetName) {
var tasks = [];
var prefix = this.name;
if (!target) {
Object.keys(grunt.config(name)).forEach(function(target) {
if (!/^_|^options$/.test(target)) {
tasks.push(prefix + ':' + name + ':' + target);
if (!targetName) {
Object.keys(grunt.config(taskName)).forEach(function(targetName) {
if (!/^_|^options$/.test(targetName)) {
tasks.push(prefix + ':' + taskName + ':' + targetName);
}

@@ -42,3 +46,4 @@ });

var options = this.options({
cache: path.join(__dirname, '..', '.cache')
cache: path.join(__dirname, '..', '.cache'),
override: nullOverride
});

@@ -52,8 +57,10 @@

var originalConfig = grunt.config.get([name, target]);
var done = this.async();
var originalConfig = grunt.config.get([taskName, targetName]);
var config = grunt.util._.clone(originalConfig);
/**
* Special handling for watch task. This is a multitask that expects
* the `files` config to be a string or array of string source paths.
* Special handling for tasks that expect the `files` config to be a string
* or array of string source paths.
*/

@@ -72,28 +79,25 @@ var srcFiles = true;

var qualified = name + ':' + target;
var stamp = util.getStampPath(options.cache, name, target);
var repeat = grunt.file.exists(stamp);
var stamp = util.getStampPath(options.cache, taskName, targetName);
var previous;
try {
previous = fs.statSync(stamp).mtime;
} catch (err) {
// task has never succeeded before
previous = new Date(0);
}
if (!repeat) {
/**
* This task has never succeeded before. Process everything. This is
* less efficient than it could be for cases where some dest files were
* created in previous runs that failed, but it makes things easier.
*/
grunt.task.run([
qualified + (args ? ':' + args : ''),
'newer-postrun:' + qualified + ':-1:' + options.cache
]);
return;
function override(filePath, time, include) {
var details = {
task: taskName,
target: targetName,
path: filePath,
time: time
};
options.override(details, include);
}
// This task has succeeded before. Filter src files.
var done = this.async();
var previous = fs.statSync(stamp).mtime;
var files = grunt.task.normalizeMultiTaskFiles(config, target);
util.filterFilesByTime(files, previous, function(err, newerFiles) {
if (err) {
return done(err);
var files = grunt.task.normalizeMultiTaskFiles(config, targetName);
util.filterFilesByTime(files, previous, override, function(e, newerFiles) {
if (e) {
return done(e);
} else if (newerFiles.length === 0) {

@@ -118,3 +122,4 @@ grunt.log.writeln('No newer files to process.');

delete config.dest;
grunt.config.set([name, target], config);
grunt.config.set([taskName, targetName], config);
// because we modified the task config, cache the original

@@ -124,2 +129,3 @@ var id = cacheConfig(originalConfig);

// run the task, and attend to postrun tasks
var qualified = taskName + ':' + targetName;
var tasks = [

@@ -153,18 +159,18 @@ qualified + (args ? ':' + args : ''),

var internal = 'Internal task.';
grunt.registerTask(
'newer-postrun', 'Internal task.', function(name, target, id, dir) {
'newer-postrun', internal, function(taskName, targetName, id, dir) {
// if dir includes a ':', grunt will split it among multiple args
dir = Array.prototype.slice.call(arguments, 3).join(':');
grunt.file.write(util.getStampPath(dir, name, target), '');
grunt.file.write(util.getStampPath(dir, taskName, targetName), '');
// reconfigure task if modified config was set
if (id !== '-1') {
grunt.config.set([name, target], pluckConfig(id));
}
// reconfigure task with original config
grunt.config.set([taskName, targetName], pluckConfig(id));
});
var clean = 'Remove cached timestamps.';
grunt.registerTask(
'newer-clean', 'Remove cached timestamps.', function(name, target) {
'newer-clean', clean, function(taskName, targetName) {
var done = this.async();

@@ -177,6 +183,6 @@

var cacheDir = path.join(__dirname, '..', '.cache');
if (name && target) {
cacheDir = util.getStampPath(cacheDir, name, target);
} else if (name) {
cacheDir = path.join(cacheDir, name);
if (taskName && targetName) {
cacheDir = util.getStampPath(cacheDir, taskName, targetName);
} else if (taskName) {
cacheDir = path.join(cacheDir, taskName);
}

@@ -183,0 +189,0 @@ if (grunt.file.exists(cacheDir)) {

@@ -39,5 +39,5 @@ var assert = require('assert');

if (expected.length === 0) {
assert.equal(log.length, 0, 'No log entries');
assert.equal(log.length, 0, 'Expected no log entries, got ' + log.length);
} else {
assert.equal(log.length, 1, 'One log entry');
assert.equal(log.length, 1, 'Expected one log entry, got ' + log.length);
var actual = log[0];

@@ -44,0 +44,0 @@ assert.deepEqual(actual, expected);

@@ -9,2 +9,6 @@ var mock = require('mock-fs');

function nullOverride(filePath, time, include) {
include(false);
}
describe('filterPathsByTime()', function() {

@@ -39,3 +43,4 @@

util.filterPathsByTime(paths, new Date(150), function(err, results) {
util.filterPathsByTime(paths, new Date(150), nullOverride,
function(err, results) {
if (err) {

@@ -51,2 +56,55 @@ return done(err);

it('calls override with older files and comparison time', function(done) {
var paths = [
'src/js/a.js',
'src/js/b.js',
'src/js/c.js'
];
function customOverride(filePath, time, include) {
assert.equal(filePath, 'src/js/a.js');
assert.equal(time.getTime(), 150);
include(false);
}
util.filterPathsByTime(paths, new Date(150), customOverride,
function(err, results) {
if (err) {
return done(err);
}
assert.equal(results.length, 2);
assert.deepEqual(results.sort(), ['src/js/b.js', 'src/js/c.js']);
done();
});
});
it('allows override to force inclusion of older files', function(done) {
var paths = [
'src/js/a.js',
'src/js/b.js',
'src/js/c.js'
];
function customOverride(filePath, time, include) {
assert.equal(filePath, 'src/js/a.js');
assert.equal(time.getTime(), 150);
include(true);
}
util.filterPathsByTime(paths, new Date(150), customOverride,
function(err, results) {
if (err) {
return done(err);
}
assert.equal(results.length, 3);
assert.deepEqual(results.sort(),
['src/js/a.js', 'src/js/b.js', 'src/js/c.js']);
done();
});
});
it('calls callback error if file not found', function(done) {

@@ -58,3 +116,4 @@

util.filterPathsByTime(paths, new Date(150), function(err, results) {
util.filterPathsByTime(paths, new Date(150), nullOverride,
function(err, results) {
assert.instanceOf(err, Error);

@@ -97,3 +156,3 @@ assert.equal(results, undefined);

it('calls callback with true if any file is newer', function(done) {
util.anyNewer(paths, new Date(250), function(err, newer) {
util.anyNewer(paths, new Date(250), nullOverride, function(err, newer) {
if (err) {

@@ -107,4 +166,18 @@ return done(err);

it('does not call override if all files are newer', function(done) {
function override(filePath, time, include) {
done(new Error('Override should not be called'));
}
util.anyNewer(paths, new Date(1), override, function(err, newer) {
if (err) {
return done(err);
}
assert.isTrue(newer);
done();
});
});
it('calls callback with false if no files are newer', function(done) {
util.anyNewer(paths, new Date(350), function(err, newer) {
util.anyNewer(paths, new Date(350), nullOverride, function(err, newer) {
if (err) {

@@ -118,4 +191,35 @@ return done(err);

it('calls override with older file and time', function(done) {
function override(filePath, time, include) {
assert.equal(filePath, 'src/js/a.js');
assert.equal(time.getTime(), 150);
include(false);
}
util.anyNewer(paths, new Date(150), override, function(err, newer) {
if (err) {
return done(err);
}
assert.isTrue(newer);
done();
});
});
it('allows override to force inclusion of older files', function(done) {
function override(filePath, time, include) {
include(true);
}
util.anyNewer(paths, new Date(1000), override, function(err, newer) {
if (err) {
return done(err);
}
assert.isTrue(newer);
done();
});
});
it('calls callback with error if file not found', function(done) {
util.anyNewer(['bogus/file.js'], new Date(350), function(err, newer) {
util.anyNewer(['bogus/file.js'], new Date(350), nullOverride,
function(err, newer) {
assert.instanceOf(err, Error);

@@ -170,3 +274,4 @@ assert.equal(newer, undefined);

}];
util.filterFilesByTime(files, new Date(1000), function(err, results) {
util.filterFilesByTime(files, new Date(1000), nullOverride,
function(err, results) {
assert.isNull(err);

@@ -187,3 +292,4 @@ assert.equal(results.length, 1);

}];
util.filterFilesByTime(files, new Date(1000), function(err, results) {
util.filterFilesByTime(files, new Date(1000), nullOverride,
function(err, results) {
assert.isNull(err);

@@ -210,3 +316,4 @@ assert.equal(results.length, 1);

}];
util.filterFilesByTime(files, new Date(150), function(err, results) {
util.filterFilesByTime(files, new Date(150), nullOverride,
function(err, results) {
assert.isNull(err);

@@ -230,3 +337,4 @@ assert.equal(results.length, 2);

}];
util.filterFilesByTime(files, new Date(200), function(err, results) {
util.filterFilesByTime(files, new Date(200), nullOverride,
function(err, results) {
assert.isNull(err);

@@ -249,3 +357,4 @@ assert.equal(results.length, 1);

}];
util.filterFilesByTime(files, new Date(1000), function(err, results) {
util.filterFilesByTime(files, new Date(1000), nullOverride,
function(err, results) {
assert.isNull(err);

@@ -265,3 +374,4 @@ assert.equal(results.length, 1);

}];
util.filterFilesByTime(files, new Date(1000), function(err, results) {
util.filterFilesByTime(files, new Date(1000), nullOverride,
function(err, results) {
assert.instanceOf(err, Error);

@@ -268,0 +378,0 @@ assert.isUndefined(results);

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