Skip to content

Commit

Permalink
Add option to preserve timestamps
Browse files Browse the repository at this point in the history
Signed-off-by: Joern Bernhardt <[email protected]>
  • Loading branch information
McHunkyTrunk committed Jun 22, 2015
1 parent 5279a3b commit 5696fca
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 4 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ Methods


Copy a file or directory. The directory can have contents. Like `cp -r`.

Options:
clobber (boolean): overwrite existing file or directory
preserveTimestamps (boolean): will set last modification and access times to the ones of the original source files, default is `false`.

Sync: `copySync()`

Expand Down
9 changes: 8 additions & 1 deletion lib/copy/copy-file-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ var fs = require('graceful-fs')
var BUF_LENGTH = 64 * 1024
var _buff = new Buffer(BUF_LENGTH)

function copyFileSync (srcFile, destFile, clobber) {
function copyFileSync (srcFile, destFile, options) {
var clobber = options.clobber
var preserveTimestamps = options.preserveTimestamps

if (fs.existsSync(destFile) && !clobber) {
throw Error('EEXIST')
}
Expand All @@ -22,6 +25,10 @@ function copyFileSync (srcFile, destFile, clobber) {

fs.closeSync(fdr)
fs.closeSync(fdw)

if (preserveTimestamps) {
fs.utimesSync(destFile, stat.atime, stat.mtime)
}
}

module.exports = copyFileSync
7 changes: 5 additions & 2 deletions lib/copy/copy-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ function copySync (src, dest, options) {

// default to true for now
options.clobber = 'clobber' in options ? !!options.clobber : true
options.preserveTimestamps = 'preserveTimestamps' in options ? !!options.preserveTimestamps : true

options.filter = options.filter || function () { return true }

Expand All @@ -27,13 +28,15 @@ function copySync (src, dest, options) {

if (performCopy) {
if (!destFolderExists) mkdir.mkdirsSync(destFolder)
copyFileSync(src, dest, options.clobber)
copyFileSync(src, dest, {clobber: options.clobber, preserveTimestamps: options.preserveTimestamps})
}
} else if (stats.isDirectory()) {
if (!fs.existsSync(dest)) mkdir.mkdirsSync(dest)
var contents = fs.readdirSync(src)
contents.forEach(function (content) {
copySync(path.join(src, content), path.join(dest, content), {filter: options.filter, recursive: true})
var opts = options
opts.recursive = true
copySync(path.join(src, content), path.join(dest, content), opts)
})
} else if (options.recursive && stats.isSymbolicLink()) {
var srcPath = fs.readlinkSync(src)
Expand Down
10 changes: 9 additions & 1 deletion lib/copy/ncp.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function ncp (source, dest, options, callback) {
var transform = options.transform
var clobber = options.clobber !== false
var dereference = options.dereference
var preserveTimestamps = options.preserveTimestamps === true

var errs = null

Expand Down Expand Up @@ -106,7 +107,14 @@ function ncp (source, dest, options, callback) {
}

writeStream.once('finish', function () {
doneOne()
if (preserveTimestamps) {
fs.utimes(target, file.atime, file.mtime, function (err) {
if (err) return onError(err)
return doneOne()
})
} else {
doneOne()
}
})
}

Expand Down
91 changes: 91 additions & 0 deletions test/copy/copy.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
var assert = require('assert')
var fs = require('fs')
var path = require('path')
var os = require('os')
var fse = require(process.cwd())

/* global afterEach, beforeEach, describe, it */

describe('fs-extra', function () {
var TEST_DIR
var SRC_FIXTURES_DIR = path.join(__dirname, './fixtures')
var FILES = ['a-file', path.join('a-folder', 'another-file'), path.join('a-folder', 'another-folder', 'file3')]

beforeEach(function (done) {
TEST_DIR = path.join(os.tmpdir(), 'fs-extra', 'copy')
fse.emptyDir(TEST_DIR, done)
})

afterEach(function (done) {
fse.remove(TEST_DIR, done)
})

describe('+ copySync', function () {
describe('> when modified option is turned off', function () {
it('should have different timestamps on copy', function (done) {
var from = path.join(SRC_FIXTURES_DIR)

fse.copySync(from, TEST_DIR, {preserveTimestamps: false})

FILES.forEach(testFile({preserveTimestamps: false}))
done()
})
})

describe('> when modified option is turned on', function () {
it('should have the same timestamps on copy', function (done) {
var from = path.join(SRC_FIXTURES_DIR)

fse.copySync(from, TEST_DIR, {preserveTimestamps: true})

FILES.forEach(testFile({preserveTimestamps: true}))

done()
})
})

})

describe('+ copy', function () {
describe('> when modified option is turned off', function () {
it('should have different timestamps on copy', function (done) {
var from = path.join(SRC_FIXTURES_DIR)
var to = path.join(TEST_DIR)

fse.copy(from, to, {preserveTimestamps: false}, function () {
FILES.forEach(testFile({preserveTimestamps: false}))
done()
})
})
})

describe('> when modified option is turned on', function () {
it('should have the same timestamps on copy', function (done) {
var from = path.join(SRC_FIXTURES_DIR)
var to = path.join(TEST_DIR)

fse.copy(from, to, {preserveTimestamps: true}, function () {
FILES.forEach(testFile({preserveTimestamps: true}))
done()
})
})
})

})

function testFile (options) {
return function (file) {
var a = path.join(SRC_FIXTURES_DIR, file)
var b = path.join(TEST_DIR, file)
var fromStat = fs.statSync(a)
var toStat = fs.statSync(b)
if (options.preserveTimestamps) {
assert.deepEqual(toStat.mtime, fromStat.mtime)
assert.deepEqual(toStat.atime, fromStat.atime)
} else {
assert.notEqual(toStat.mtime, fromStat.mtime)
assert.notEqual(toStat.atime, fromStat.atime)
}
}
}
})
1 change: 1 addition & 0 deletions test/copy/fixtures/a-file
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sonic the hedgehog
1 change: 1 addition & 0 deletions test/copy/fixtures/a-folder/another-file
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tails
1 change: 1 addition & 0 deletions test/copy/fixtures/a-folder/another-folder/file3
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
knuckles

0 comments on commit 5696fca

Please sign in to comment.