diff options
author | Rebecca Turner <me@re-becca.org> | 2016-01-28 18:11:35 -0800 |
---|---|---|
committer | Jeremiah Senkpiel <fishrock123@rocketmail.com> | 2016-02-01 10:43:34 -0500 |
commit | 76cb81b354de8447898427619c66c86c59b22b3d (patch) | |
tree | 0c0826bed77086fb38cda8dc680d4fb10d2cff25 /deps/npm/node_modules/fs-write-stream-atomic | |
parent | d5d301f3032a0723f5a29cfbe0d95ac4ad205d42 (diff) | |
download | android-node-v8-76cb81b354de8447898427619c66c86c59b22b3d.tar.gz android-node-v8-76cb81b354de8447898427619c66c86c59b22b3d.tar.bz2 android-node-v8-76cb81b354de8447898427619c66c86c59b22b3d.zip |
deps: upgrade npm to 3.6.0
PR-URL: https://github.com/nodejs/node/pull/4958
Reviewed-By: Myles Borins <mborins@us.ibm.com>
Reviewed-By: Kat Marchán <kzm@sykosomatic.org>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Diffstat (limited to 'deps/npm/node_modules/fs-write-stream-atomic')
9 files changed, 331 insertions, 132 deletions
diff --git a/deps/npm/node_modules/fs-write-stream-atomic/.npmignore b/deps/npm/node_modules/fs-write-stream-atomic/.npmignore new file mode 100644 index 0000000000..2f24c57c38 --- /dev/null +++ b/deps/npm/node_modules/fs-write-stream-atomic/.npmignore @@ -0,0 +1,3 @@ +node_modules/ +coverage/ +.nyc_output/ diff --git a/deps/npm/node_modules/fs-write-stream-atomic/.travis.yml b/deps/npm/node_modules/fs-write-stream-atomic/.travis.yml new file mode 100644 index 0000000000..6894662527 --- /dev/null +++ b/deps/npm/node_modules/fs-write-stream-atomic/.travis.yml @@ -0,0 +1,11 @@ +language: node_js +sudo: false +before_install: + - "npm -g install npm" +node_js: + - "0.8" + - "0.10" + - "0.12" + - "iojs" + - "4" + - "5" diff --git a/deps/npm/node_modules/fs-write-stream-atomic/index.js b/deps/npm/node_modules/fs-write-stream-atomic/index.js index d86b8c673f..59b50db6d7 100644 --- a/deps/npm/node_modules/fs-write-stream-atomic/index.js +++ b/deps/npm/node_modules/fs-write-stream-atomic/index.js @@ -1,96 +1,124 @@ var fs = require('graceful-fs') +var Writable = require('readable-stream').Writable var util = require('util') -var crypto = require('crypto') +var MurmurHash3 = require('imurmurhash') +var iferr = require('iferr') -function md5hex () { - var hash = crypto.createHash('md5') - for (var ii=0; ii<arguments.length; ++ii) { - hash.update(''+arguments[ii]) +function murmurhex () { + var hash = MurmurHash3('') + for (var ii = 0; ii < arguments.length; ++ii) { + hash.hash(hash + arguments[ii]) } - return hash.digest('hex') + return hash.result() } -var invocations = 0; +var invocations = 0 function getTmpname (filename) { - return filename + "." + md5hex(__filename, process.pid, ++invocations) + return filename + '.' + murmurhex(__filename, process.pid, ++invocations) } -module.exports = WriteStream +var setImmediate = global.setImmediate || setTimeout -util.inherits(WriteStream, fs.WriteStream) -function WriteStream (path, options) { - if (!options) - options = {} +module.exports = WriteStreamAtomic - if (!(this instanceof WriteStream)) - return new WriteStream(path, options) +// Requirements: +// 1. Write everything written to the stream to a temp file. +// 2. If there are no errors: +// a. moves the temp file into its final destination +// b. emits `finish` & `closed` ONLY after the file is +// fully flushed and renamed. +// 3. If there's an error, removes the temp file. + +util.inherits(WriteStreamAtomic, Writable) +function WriteStreamAtomic (path, options) { + if (!(this instanceof WriteStreamAtomic)) { + return new WriteStreamAtomic(path, options) + } + Writable.call(this, options) this.__atomicTarget = path - this.__atomicChown = options.chown - this.__atomicDidStuff = false this.__atomicTmp = getTmpname(path) - fs.WriteStream.call(this, this.__atomicTmp, options) + this.__atomicChown = options && options.chown + + this.__atomicClosed = false + + this.__atomicStream = fs.WriteStream(this.__atomicTmp, options) + + this.__atomicStream.once('open', handleOpen(this)) + this.__atomicStream.once('close', handleClose(this)) + this.__atomicStream.once('error', handleError(this)) +} + +// We have to suppress default finish emitting, because ordinarily it +// would happen as soon as `end` is called on us and all of the +// data has been written to our target stream. So we suppress +// finish from being emitted here, and only emit it after our +// target stream is closed and we've moved everything around. +WriteStreamAtomic.prototype.emit = function (event) { + if (event === 'finish') return this.__atomicStream.end() + return Writable.prototype.emit.apply(this, arguments) } -function cleanup (er) { - fs.unlink(this.__atomicTmp, function () { - fs.WriteStream.prototype.emit.call(this, 'error', er) - }.bind(this)) +WriteStreamAtomic.prototype._write = function (buffer, encoding, cb) { + var flushed = this.__atomicStream.write(buffer, encoding) + if (flushed) return cb() + this.__atomicStream.once('drain', cb) } -function cleanupSync () { - try { - fs.unlinkSync(this.__atomicTmp) - } finally { - return +function handleOpen (writeStream) { + return function (fd) { + writeStream.emit('open', fd) } } -// When we *would* emit 'close' or 'finish', instead do our stuff -WriteStream.prototype.emit = function (ev) { - if (ev === 'error') - cleanupSync.call(this) - - if (ev !== 'close' && ev !== 'finish') - return fs.WriteStream.prototype.emit.apply(this, arguments) - - // We handle emitting finish and close after the rename. - if (ev === 'close' || ev === 'finish') { - if (!this.__atomicDidStuff) { - atomicDoStuff.call(this, function (er) { - if (er) - cleanup.call(this, er) - }.bind(this)) +function handleClose (writeStream) { + return function () { + if (writeStream.__atomicClosed) return + writeStream.__atomicClosed = true + if (writeStream.__atomicChown) { + var uid = writeStream.__atomicChown.uid + var gid = writeStream.__atomicChown.gid + return fs.chown(writeStream.__atomicTmp, uid, gid, iferr(cleanup, moveIntoPlace)) + } else { + moveIntoPlace() } } -} + function cleanup (err) { + fs.unlink(writeStream.__atomicTmp, function () { + writeStream.emit('error', err) + writeStream.emit('close') + }) + } + function moveIntoPlace () { + fs.rename(writeStream.__atomicTmp, writeStream.__atomicTarget, iferr(cleanup, end)) + } + function end () { + // We have to use our parent class directly because we suppress `finish` + // events fired via our own emit method. + Writable.prototype.emit.call(writeStream, 'finish') -function atomicDoStuff(cb) { - if (this.__atomicDidStuff) - throw new Error('Already did atomic move-into-place') - - this.__atomicDidStuff = true - if (this.__atomicChown) { - var uid = this.__atomicChown.uid - var gid = this.__atomicChown.gid - return fs.chown(this.__atomicTmp, uid, gid, function (er) { - if (er) return cb(er) - moveIntoPlace.call(this, cb) - }.bind(this)) - } else { - moveIntoPlace.call(this, cb) + // Delay the close to provide the same temporal separation a physical + // file operation would have– that is, the close event is emitted only + // after the async close operation completes. + setImmediate(function () { + writeStream.emit('close') + }) } } -function moveIntoPlace (cb) { - fs.rename(this.__atomicTmp, this.__atomicTarget, function (er) { - cb(er) - // emit finish, and then close on the next tick - // This makes finish/close consistent across Node versions also. - fs.WriteStream.prototype.emit.call(this, 'finish') - process.nextTick(function() { - fs.WriteStream.prototype.emit.call(this, 'close') - }.bind(this)) - }.bind(this)) +function handleError (writeStream) { + return function (er) { + cleanupSync() + writeStream.emit('error', er) + writeStream.__atomicClosed = true + writeStream.emit('close') + } + function cleanupSync () { + try { + fs.unlinkSync(writeStream.__atomicTmp) + } finally { + return + } + } } diff --git a/deps/npm/node_modules/fs-write-stream-atomic/package.json b/deps/npm/node_modules/fs-write-stream-atomic/package.json index a226dbe48d..e65fa32c0e 100644 --- a/deps/npm/node_modules/fs-write-stream-atomic/package.json +++ b/deps/npm/node_modules/fs-write-stream-atomic/package.json @@ -1,48 +1,68 @@ { - "name": "fs-write-stream-atomic", - "version": "1.0.4", - "description": "Like `fs.createWriteStream(...)`, but atomic.", - "main": "index.js", - "directories": { - "test": "test" - }, - "dependencies": { - "graceful-fs": "^4.1.2" - }, - "devDependencies": { - "tap": "^1.2.0" - }, - "scripts": { - "test": "tap test/*.js" + "_args": [ + [ + "fs-write-stream-atomic@1.0.8", + "/Users/rebecca/code/npm" + ] + ], + "_from": "fs-write-stream-atomic@1.0.8", + "_id": "fs-write-stream-atomic@1.0.8", + "_inCache": true, + "_installable": true, + "_location": "/fs-write-stream-atomic", + "_nodeVersion": "4.2.2", + "_npmUser": { + "email": "me@re-becca.org", + "name": "iarna" }, - "repository": { - "type": "git", - "url": "git+https://github.com/npm/fs-write-stream-atomic.git" + "_npmVersion": "3.5.2", + "_phantomChildren": {}, + "_requested": { + "name": "fs-write-stream-atomic", + "raw": "fs-write-stream-atomic@1.0.8", + "rawSpec": "1.0.8", + "scope": null, + "spec": "1.0.8", + "type": "version" }, + "_requiredBy": [ + "/" + ], + "_shasum": "e49aaddf288f87d46ff9e882f216a13abc40778b", + "_shrinkwrap": null, + "_spec": "fs-write-stream-atomic@1.0.8", + "_where": "/Users/rebecca/code/npm", "author": { - "name": "Isaac Z. Schlueter", "email": "i@izs.me", + "name": "Isaac Z. Schlueter", "url": "http://blog.izs.me/" }, - "license": "ISC", "bugs": { "url": "https://github.com/npm/fs-write-stream-atomic/issues" }, - "homepage": "https://github.com/npm/fs-write-stream-atomic", - "gitHead": "6ca2651b913149543c5390c6c4f7d370bdca42b5", - "_id": "fs-write-stream-atomic@1.0.4", - "_shasum": "c1ea55889f036ceebdead7d1055edbad998fe5e9", - "_from": "fs-write-stream-atomic@>=1.0.4 <1.1.0", - "_npmVersion": "2.14.3", - "_nodeVersion": "2.2.2", - "_npmUser": { - "name": "zkat", - "email": "kat@sykosomatic.org" + "dependencies": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + }, + "description": "Like `fs.createWriteStream(...)`, but atomic.", + "devDependencies": { + "rimraf": "^2.4.4", + "standard": "^5.4.1", + "tap": "^2.3.1" + }, + "directories": { + "test": "test" }, "dist": { - "shasum": "c1ea55889f036ceebdead7d1055edbad998fe5e9", - "tarball": "http://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.4.tgz" + "shasum": "e49aaddf288f87d46ff9e882f216a13abc40778b", + "tarball": "http://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.8.tgz" }, + "gitHead": "b55824ee4de7f1ca23784929d68b1b8f5edbf4a4", + "homepage": "https://github.com/npm/fs-write-stream-atomic", + "license": "ISC", + "main": "index.js", "maintainers": [ { "name": "iarna", @@ -50,12 +70,26 @@ }, { "name": "isaacs", - "email": "isaacs@npmjs.com" + "email": "i@izs.me" + }, + { + "name": "othiym23", + "email": "ogd@aoaioxxysz.net" }, { "name": "zkat", "email": "kat@sykosomatic.org" } ], - "_resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.4.tgz" + "name": "fs-write-stream-atomic", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/fs-write-stream-atomic.git" + }, + "scripts": { + "test": "standard && tap --coverage test/*.js" + }, + "version": "1.0.8" } diff --git a/deps/npm/node_modules/fs-write-stream-atomic/test/basic.js b/deps/npm/node_modules/fs-write-stream-atomic/test/basic.js index 159c596ab0..d0205e15f4 100644 --- a/deps/npm/node_modules/fs-write-stream-atomic/test/basic.js +++ b/deps/npm/node_modules/fs-write-stream-atomic/test/basic.js @@ -1,7 +1,14 @@ +var fs = require('graceful-fs') var test = require('tap').test -var writeStream = require('../index.js') -var fs = require('fs') var path = require('path') +var writeStream = require('../index.js') + +var rename = fs.rename +fs.rename = function (from, to, cb) { + setTimeout(function () { + rename(from, to, cb) + }, 100) +} test('basic', function (t) { // open 10 write streams to the same file. @@ -10,40 +17,41 @@ test('basic', function (t) { var target = path.resolve(__dirname, 'test.txt') var n = 10 + // We run all of our assertions twice: + // once for finish, once for close + // There are 6 assertions, two fixed, plus 4 lines in the file. + t.plan(n * 2 * 6) + var streams = [] for (var i = 0; i < n; i++) { var s = writeStream(target) - s.on('finish', verifier('finish')) - s.on('close', verifier('close')) + s.on('finish', verifier('finish', i)) + s.on('close', verifier('close', i)) streams.push(s) } - var verifierCalled = 0 - function verifier (ev) { return function () { - if (ev === 'close') - t.equal(this.__emittedFinish, true) - else { - this.__emittedFinish = true - t.equal(ev, 'finish') - } - - // make sure that one of the atomic streams won. - var res = fs.readFileSync(target, 'utf8') - var lines = res.trim().split(/\n/) - lines.forEach(function (line) { - var first = lines[0].match(/\d+$/)[0] - var cur = line.match(/\d+$/)[0] - t.equal(cur, first) - }) + function verifier (ev, num) { + return function () { + if (ev === 'close') { + t.equal(this.__emittedFinish, true, num + '. closed only after finish') + } else { + this.__emittedFinish = true + t.equal(ev, 'finish', num + '. finished') + } - var resExpr = /^first write \d+\nsecond write \d+\nthird write \d+\nfinal write \d+\n$/ - t.similar(res, resExpr) + // make sure that one of the atomic streams won. + var res = fs.readFileSync(target, 'utf8') + var lines = res.trim().split(/\n/) + lines.forEach(function (line, lineno) { + var first = lines[0].match(/\d+$/)[0] + var cur = line.match(/\d+$/)[0] + t.equal(cur, first, num + '. line ' + lineno + ' matches') + }) - // should be called once for each close, and each finish - if (++verifierCalled === n * 2) { - t.end() + var resExpr = /^first write \d+\nsecond write \d+\nthird write \d+\nfinal write \d+\n$/ + t.similar(res, resExpr, num + '. content matches') } - }} + } // now write something to each stream. streams.forEach(function (stream, i) { diff --git a/deps/npm/node_modules/fs-write-stream-atomic/test/chown.js b/deps/npm/node_modules/fs-write-stream-atomic/test/chown.js new file mode 100644 index 0000000000..1733cf27ec --- /dev/null +++ b/deps/npm/node_modules/fs-write-stream-atomic/test/chown.js @@ -0,0 +1,44 @@ +'use strict' +var fs = require('graceful-fs') +var path = require('path') +var test = require('tap').test +var rimraf = require('rimraf') +var writeStream = require('../index.js') + +var target = path.resolve(__dirname, 'test-chown') + +test('chown works', function (t) { + t.plan(1) + var stream = writeStream(target, {chown: {uid: process.getuid(), gid: process.getgid()}}) + var hadError = false + stream.on('error', function (er) { + hadError = true + console.log('#', er) + }) + stream.on('close', function () { + t.is(hadError, false, 'no errors before close') + }) + stream.end() +}) + +test('chown fails', function (t) { + t.plan(1) + fs.chown = function (file, uid, gid, cb) { + cb(new Error('TEST BREAK')) + } + var stream = writeStream(target, {chown: {uid: process.getuid(), gid: process.getgid()}}) + var hadError = false + stream.on('error', function (er) { + hadError = true + console.log('#', er) + }) + stream.on('close', function () { + t.is(hadError, true, 'error before close') + }) + stream.end() +}) + +test('cleanup', function (t) { + rimraf.sync(target) + t.end() +}) diff --git a/deps/npm/node_modules/fs-write-stream-atomic/test/rename-fail.js b/deps/npm/node_modules/fs-write-stream-atomic/test/rename-fail.js new file mode 100644 index 0000000000..7e27f0bfb0 --- /dev/null +++ b/deps/npm/node_modules/fs-write-stream-atomic/test/rename-fail.js @@ -0,0 +1,30 @@ +'use strict' +var fs = require('graceful-fs') +var path = require('path') +var test = require('tap').test +var rimraf = require('rimraf') +var writeStream = require('../index.js') + +var target = path.resolve(__dirname, 'test-rename') + +test('rename fails', function (t) { + t.plan(1) + fs.rename = function (src, dest, cb) { + cb(new Error('TEST BREAK')) + } + var stream = writeStream(target) + var hadError = false + stream.on('error', function (er) { + hadError = true + console.log('#', er) + }) + stream.on('close', function () { + t.is(hadError, true, 'error before close') + }) + stream.end() +}) + +test('cleanup', function (t) { + rimraf.sync(target) + t.end() +}) diff --git a/deps/npm/node_modules/fs-write-stream-atomic/test/slow-close.js b/deps/npm/node_modules/fs-write-stream-atomic/test/slow-close.js new file mode 100644 index 0000000000..9840a6ef03 --- /dev/null +++ b/deps/npm/node_modules/fs-write-stream-atomic/test/slow-close.js @@ -0,0 +1,40 @@ +'use strict' +var fs = require('graceful-fs') +var path = require('path') +var test = require('tap').test +var rimraf = require('rimraf') +var writeStream = require('../index.js') + +var target = path.resolve(__dirname, 'test-chown') + +test('slow close', function (t) { + t.plan(2) + // The goal here is to simulate the "file close" step happening so slowly + // that the whole close/rename process could finish before the file is + // actually closed (and thus buffers truely flushed to the OS). In + // previous versions of this module, this would result in the module + // emitting finish & close before the file was fully written and in + // turn, could break other layers that tried to read the new file. + var realEmit = fs.WriteStream.prototype.emit + var reallyClosed = false + fs.WriteStream.prototype.emit = function (event) { + if (event !== 'close') return realEmit.apply(this, arguments) + setTimeout(function () { + reallyClosed = true + realEmit.call(this, 'close') + }.bind(this), 200) + } + var stream = writeStream(target) + stream.on('finish', function () { + t.is(reallyClosed, true, "didn't finish before target was closed") + }) + stream.on('close', function () { + t.is(reallyClosed, true, "didn't close before target was closed") + }) + stream.end() +}) + +test('cleanup', function (t) { + rimraf.sync(target) + t.end() +}) diff --git a/deps/npm/node_modules/fs-write-stream-atomic/test/toolong.js b/deps/npm/node_modules/fs-write-stream-atomic/test/toolong.js index a1e5b714a6..f146cc55b1 100644 --- a/deps/npm/node_modules/fs-write-stream-atomic/test/toolong.js +++ b/deps/npm/node_modules/fs-write-stream-atomic/test/toolong.js @@ -2,7 +2,7 @@ var path = require('path') var test = require('tap').test var writeStream = require('../index.js') -function repeat(times, string) { +function repeat (times, string) { var output = '' for (var ii = 0; ii < times; ++ii) { output += string @@ -10,19 +10,20 @@ function repeat(times, string) { return output } -var target = path.resolve(__dirname, repeat(1000,'test')) +var target = path.resolve(__dirname, repeat(1000, 'test')) test('name too long', function (t) { + t.plan(2) var stream = writeStream(target) var hadError = false stream.on('error', function (er) { if (!hadError) { - t.is(er.code, 'ENAMETOOLONG', target.length + " character name results in ENAMETOOLONG") + t.is(er.code, 'ENAMETOOLONG', target.length + ' character name results in ENAMETOOLONG') hadError = true } }) stream.on('close', function () { - t.end() + t.ok(hadError, 'got error before close') }) stream.end() }) |