Repository: gulpjs/vinyl-fs
Pull request #114 (2015-10-16 22:19:47)

[Fix] Ignore atime and mtime if they are invalid
Fixes issue #113


Patch:
diff --git a/lib/utimes.js b/lib/utimes.js
index a2c8f26..1a843ca 100644
--- a/lib/utimes.js
+++ b/lib/utimes.js
@@ -2,11 +2,20 @@
 
 var fs = require('graceful-fs');
 
+// http://stackoverflow.com/a/10589791/586382
+function validDate(date) {
+  return date instanceof Date && !isNaN(date.valueOf());
+}
+
 function utimes(writePath, stat, cb) {
-  if (stat.mtime) {
+  var mtime = stat.mtime;
+
+  if (validDate(mtime)) {
     var atime = stat.atime || new Date();
 
-    return fs.utimes(writePath, atime, stat.mtime, cb);
+    if(validDate(atime)) {
+      return fs.utimes(writePath, atime, mtime, cb);
+    }
   }
 
   cb();


Test patch:
diff --git a/test/dest.js b/test/dest.js
index 4e25056..9b7d0ae 100644
--- a/test/dest.js
+++ b/test/dest.js
@@ -659,6 +659,87 @@ describe('dest stream', function() {
     stream.end();
   });
 
+  it('should not modify file mtime and atime when provided mtime on the vinyl stat is invalid', function(done) {
+    var inputPath = path.join(__dirname, './fixtures/test.coffee');
+    var inputBase = path.join(__dirname, './fixtures/');
+    var expectedPath = path.join(__dirname, './out-fixtures/test.coffee');
+    var expectedContents = fs.readFileSync(inputPath);
+    var expectedCwd = __dirname;
+    var expectedBase = path.join(__dirname, './out-fixtures');
+    var expectedMtime = new Date('foo');
+
+    var expectedFile = new File({
+      base: inputBase,
+      cwd: __dirname,
+      path: inputPath,
+      contents: expectedContents,
+      stat: {
+        mtime: expectedMtime
+      }
+    });
+
+    var onEnd = function(){
+      buffered.length.should.equal(1);
+      buffered[0].should.equal(expectedFile);
+      fs.existsSync(expectedPath).should.equal(true);
+      expectedFile.stat.should.have.property('mtime');
+      expectedFile.stat.mtime.should.equal(expectedMtime);
+      expectedFile.stat.should.not.have.property('atime');
+      done();
+    };
+
+    var stream = vfs.dest('./out-fixtures/', {cwd: __dirname});
+
+    var buffered = [];
+    var bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
+
+    stream.pipe(bufferStream);
+    stream.write(expectedFile);
+    stream.end();
+  });
+
+  it('should not modify file mtime and atime when provided atime on the vinyl stat is invalid', function(done) {
+    var inputPath = path.join(__dirname, './fixtures/test.coffee');
+    var inputBase = path.join(__dirname, './fixtures/');
+    var expectedPath = path.join(__dirname, './out-fixtures/test.coffee');
+    var expectedContents = fs.readFileSync(inputPath);
+    var expectedCwd = __dirname;
+    var expectedBase = path.join(__dirname, './out-fixtures');
+    var expectedAtime = new Date('foo');
+    var expectedMtime = fs.lstatSync(inputPath).mtime;
+
+    var expectedFile = new File({
+      base: inputBase,
+      cwd: __dirname,
+      path: inputPath,
+      contents: expectedContents,
+      stat: {
+        atime: expectedAtime,
+        mtime: expectedMtime
+      }
+    });
+
+    var onEnd = function(){
+      buffered.length.should.equal(1);
+      buffered[0].should.equal(expectedFile);
+      fs.existsSync(expectedPath).should.equal(true);
+      expectedFile.stat.should.have.property('mtime');
+      expectedFile.stat.mtime.should.equal(expectedMtime);
+      expectedFile.stat.should.have.property('atime');
+      expectedFile.stat.atime.should.equal(expectedAtime);
+      done();
+    };
+
+    var stream = vfs.dest('./out-fixtures/', {cwd: __dirname});
+
+    var buffered = [];
+    var bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
+
+    stream.pipe(bufferStream);
+    stream.write(expectedFile);
+    stream.end();
+  });
+
   it('should write file atime and mtime using the vinyl stat', function(done) {
     var inputPath = path.join(__dirname, './fixtures/test.coffee');
     var inputBase = path.join(__dirname, './fixtures/');