diff --git a/index.js b/index.js index 8367535..df4e9b4 100644 --- a/index.js +++ b/index.js @@ -7,6 +7,7 @@ var debug = require('debug')('extract-zip') module.exports = function (zipPath, opts, cb) { debug('creating target directory', opts.dir) + opts.overwrite = (typeof opts.overwrite === 'undefined') ? true : opts.overwrite mkdirp(opts.dir, function (err) { if (err) return cb(err) @@ -122,11 +123,15 @@ module.exports = function (zipPath, opts, cb) { console.log('read err', err) }) - if (symlink) writeSymlink() + if (symlink) { + if (opts.overwrite) overwriteExistingSymlink() + else writeSymlink() + } else writeStream() function writeStream () { - var writeStream = fs.createWriteStream(dest, {mode: procMode}) + var writeFlag = opts.overwrite ? 'w' : 'wx' + var writeStream = fs.createWriteStream(dest, {mode: procMode, flags: writeFlag}) readStream.pipe(writeStream) writeStream.on('finish', function () { @@ -139,6 +144,17 @@ module.exports = function (zipPath, opts, cb) { return done(err) }) } + // Attempt to delete an existing symlink before attempting to write + function overwriteExistingSymlink () { + fs.unlink(dest, function (err) { + if (err) { + if (err.code === 'ENOENT') return writeSymlink() + cancelled = true + done(err) + } + writeSymlink() + }) + } // AFAICT the content of the symlink file itself is the symlink target filename string function writeSymlink () { diff --git a/test/test.js b/test/test.js index 4d8032d..3a32d75 100644 --- a/test/test.js +++ b/test/test.js @@ -28,6 +28,25 @@ test('extract cat zip', function (t) { }) }) +test('extract cat zip to same dir without overwrite', function (t) { + console.log('extracting again to', targetA) + + extract(sourceA, {dir: targetA, overwrite: false}, function (err) { + if (err) t.ok(true, 'error passed') + t.end() + }) +}) + +test('extract cat zip to same dir with overwrite', function (t) { + console.log('extracting again to', targetA) + + extract(sourceA, {dir: targetA, overwrite: true}, function (err) { + if (err) throw err + t.false(err, 'no error') + t.end() + }) +}) + test('files', function (t) { t.plan(1) @@ -95,6 +114,16 @@ test('verify extraction worked', function (t) { }) }) +test('extract github zip again without overwrite', function (t) { + console.log('extracting again to', targetB) + t.plan(1) + + extract(sourceB, {dir: targetB, overwrite: false}, function (err) { + if (err) t.ok(true, 'error passed') + t.end() + }) +}) + test('callback called once', function (t) { rimraf.sync(targetC) @@ -106,9 +135,8 @@ test('callback called once', function (t) { if (err) throw err // this triggers an error due to symlink creation - extract(sourceC, {dir: targetC}, function (err) { + extract(sourceC, {dir: targetC, overwrite: false}, function (err) { if (err) t.ok(true, 'error passed') - t.ok(true, 'callback called') }) })