Skip to content
This repository has been archived by the owner on Apr 1, 2022. It is now read-only.

Commit

Permalink
Support zero mtime
Browse files Browse the repository at this point in the history
`npm pack` [briefly published packages with all files set to the Unix
epoch](npm/npm#19968 (comment)).
This plugin was incorrectly seeing such files as modified.
  • Loading branch information
sentience committed Jun 8, 2018
1 parent 00aa7b6 commit babf46e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 21 deletions.
2 changes: 1 addition & 1 deletion mtime.js
Expand Up @@ -32,7 +32,7 @@ function getFilesChanges(filesMtimes, concurrencyLimit, done) {
}

var mtimeNew = stat.mtime.getTime();
if (!(filesMtimes[file] && mtimeNew && mtimeNew <= filesMtimes[file])) {
if (mtimeNew > Number(filesMtimes[file])) {
changed.push(file);
}
fileDone();
Expand Down
6 changes: 5 additions & 1 deletion support/testUtils.js
Expand Up @@ -54,8 +54,12 @@ function readFile(filepath) {
return contents;
}

function writeFile(filepath, content) {
function writeFile(filepath, content, unixtime) {
fs.writeFileSync(filepath, content, {encoding: 'utf8'});

if (typeof unixtime !== 'undefined') {
fs.utimesSync(filepath, unixtime, unixtime);
}
}

module.exports = {
Expand Down
78 changes: 59 additions & 19 deletions test/plugin-test.js
Expand Up @@ -84,37 +84,77 @@ test('it rebuilds when output files change', (t) => {
});
});

test('it does not rebuild when input and output files do not change', (t) => {
var bundleFile1 = 'bundle-1.js';
var dependency1 = path.join(testOutputDir, 'stuff.js');
var inputContent1 = 'console.log("123")';
test('when input and output files do not change', (t) => {
var test = t.test;

cleanupTestOutputDir((cleanupErr) => {
t.notOk(cleanupErr, 'clean up test output dir');
test('it does not rebuild', (t) => {
var bundleFile1 = 'bundle-1.js';
var dependency1 = path.join(testOutputDir, 'stuff.js');
var inputContent1 = 'console.log("123")';

writeFile(entry, `require('${dependency1}');`);
writeFile(dependency1, inputContent1);
var bundleOutputFile = path.join(testOutputDir, bundleFile1);
doBuild(bundleFile1, (build1Err) => {
t.notOk(build1Err, 'built first time');
cleanupTestOutputDir((cleanupErr) => {
t.notOk(cleanupErr, 'clean up test output dir');

var output1 = readFile(bundleOutputFile);
t.match(output1, inputContent1, 'built bundle containing initial content');
writeFile(entry, `require('${dependency1}');`);
writeFile(dependency1, inputContent1);
var bundleOutputFile = path.join(testOutputDir, bundleFile1);
doBuild(bundleFile1, (build1Err) => {
t.notOk(build1Err, 'built first time');

var mtime1 = fs.statSync(bundleOutputFile).mtime.getTime();
var output1 = readFile(bundleOutputFile);
t.match(output1, inputContent1, 'built bundle containing initial content');

doBuild(bundleFile1, build2Err => {
t.notOk(build2Err, 'built second time');
var mtime1 = fs.statSync(bundleOutputFile).mtime.getTime();

var mtime2 = fs.statSync(bundleOutputFile).mtime.getTime();
t.ok(mtime1 === mtime2, 'does not rebuild files');
doBuild(bundleFile1, build2Err => {
t.notOk(build2Err, 'built second time');

t.end();
var mtime2 = fs.statSync(bundleOutputFile).mtime.getTime();
t.ok(mtime1 === mtime2, 'does not rebuild files');

t.end();
});
});
});
});

test('it does not rebuild when a file has Epoch timestamp', (t) => {
// see https://github.com/npm/npm/issues/19968#issuecomment-372799983 for why we need to support this

var bundleFile1 = 'bundle-1.js';
var dependency1 = path.join(testOutputDir, 'stuff.js');
var inputContent1 = 'console.log("123")';

cleanupTestOutputDir((cleanupErr) => {
t.notOk(cleanupErr, 'clean up test output dir');

writeFile(entry, `require('${dependency1}');`);
writeFile(dependency1, inputContent1, 0); // zero timestamp
var bundleOutputFile = path.join(testOutputDir, bundleFile1);
doBuild(bundleFile1, (build1Err) => {
t.notOk(build1Err, 'built first time');

var output1 = readFile(bundleOutputFile);
t.match(output1, inputContent1, 'built bundle containing initial content');

var mtime1 = fs.statSync(bundleOutputFile).mtime.getTime();

doBuild(bundleFile1, build2Err => {
t.notOk(build2Err, 'built second time');

var mtime2 = fs.statSync(bundleOutputFile).mtime.getTime();
t.ok(mtime1 === mtime2, 'does not rebuild files');

t.end();
});
});
});
});

t.end();
});


function doBuild(filename, done) {
webpackConfig.entry = entry;

Expand Down

0 comments on commit babf46e

Please sign in to comment.