Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKat Marchán <kzm@sykosomatic.org>2017-03-10 00:37:13 +0300
committerKat Marchán <kzm@sykosomatic.org>2017-03-10 03:08:26 +0300
commit0e105d9fb46bb00e2bcc32b13a23f018af5f7af8 (patch)
tree3ef4c24b18dde799c6d4fc84836c38f39f743c8e
parent91dd09de11db15050215ab3094ef75ebf4da9848 (diff)
fs-write-stream-atomic@1.0.10
-rw-r--r--node_modules/fs-write-stream-atomic/index.js64
-rw-r--r--node_modules/fs-write-stream-atomic/package.json62
-rw-r--r--node_modules/fs-write-stream-atomic/test/rename-eperm.js154
-rw-r--r--npm-shrinkwrap.json5
-rw-r--r--package.json2
5 files changed, 255 insertions, 32 deletions
diff --git a/node_modules/fs-write-stream-atomic/index.js b/node_modules/fs-write-stream-atomic/index.js
index 59b50db6d..1690ff5ae 100644
--- a/node_modules/fs-write-stream-atomic/index.js
+++ b/node_modules/fs-write-stream-atomic/index.js
@@ -3,11 +3,12 @@ var Writable = require('readable-stream').Writable
var util = require('util')
var MurmurHash3 = require('imurmurhash')
var iferr = require('iferr')
+var crypto = require('crypto')
function murmurhex () {
var hash = MurmurHash3('')
for (var ii = 0; ii < arguments.length; ++ii) {
- hash.hash(hash + arguments[ii])
+ hash.hash('' + arguments[ii])
}
return hash.result()
}
@@ -36,6 +37,8 @@ function WriteStreamAtomic (path, options) {
}
Writable.call(this, options)
+ this.__isWin = options && options.hasOwnProperty('isWin') ? options.isWin : process.platform === 'win32'
+
this.__atomicTarget = path
this.__atomicTmp = getTmpname(path)
@@ -84,15 +87,64 @@ function handleClose (writeStream) {
moveIntoPlace()
}
}
+
+ function moveIntoPlace () {
+ fs.rename(writeStream.__atomicTmp, writeStream.__atomicTarget, iferr(trapWindowsEPERM, end))
+ }
+
+ function trapWindowsEPERM (err) {
+ if (writeStream.__isWin &&
+ err.syscall && err.syscall === 'rename' &&
+ err.code && err.code === 'EPERM'
+ ) {
+ checkFileHashes(err)
+ } else {
+ cleanup(err)
+ }
+ }
+
+ function checkFileHashes (eperm) {
+ var inprocess = 2
+ var tmpFileHash = crypto.createHash('sha512')
+ var targetFileHash = crypto.createHash('sha512')
+
+ fs.createReadStream(writeStream.__atomicTmp)
+ .on('data', function (data, enc) { tmpFileHash.update(data, enc) })
+ .on('error', fileHashError)
+ .on('end', fileHashComplete)
+ fs.createReadStream(writeStream.__atomicTarget)
+ .on('data', function (data, enc) { targetFileHash.update(data, enc) })
+ .on('error', fileHashError)
+ .on('end', fileHashComplete)
+
+ function fileHashError () {
+ if (inprocess === 0) return
+ inprocess = 0
+ cleanup(eperm)
+ }
+
+ function fileHashComplete () {
+ if (inprocess === 0) return
+ if (--inprocess) return
+ if (tmpFileHash.digest('hex') === targetFileHash.digest('hex')) {
+ return cleanup()
+ } else {
+ return cleanup(eperm)
+ }
+ }
+ }
+
function cleanup (err) {
fs.unlink(writeStream.__atomicTmp, function () {
- writeStream.emit('error', err)
- writeStream.emit('close')
+ if (err) {
+ writeStream.emit('error', err)
+ writeStream.emit('close')
+ } else {
+ end()
+ }
})
}
- 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.
diff --git a/node_modules/fs-write-stream-atomic/package.json b/node_modules/fs-write-stream-atomic/package.json
index e65fa32c0..f1526baa1 100644
--- a/node_modules/fs-write-stream-atomic/package.json
+++ b/node_modules/fs-write-stream-atomic/package.json
@@ -1,40 +1,56 @@
{
"_args": [
[
- "fs-write-stream-atomic@1.0.8",
- "/Users/rebecca/code/npm"
+ {
+ "raw": "fs-write-stream-atomic@latest",
+ "scope": null,
+ "escapedName": "fs-write-stream-atomic",
+ "name": "fs-write-stream-atomic",
+ "rawSpec": "latest",
+ "spec": "latest",
+ "type": "tag"
+ },
+ "/Users/zkat/Documents/code/npm"
]
],
- "_from": "fs-write-stream-atomic@1.0.8",
- "_id": "fs-write-stream-atomic@1.0.8",
+ "_from": "fs-write-stream-atomic@latest",
+ "_id": "fs-write-stream-atomic@1.0.10",
"_inCache": true,
- "_installable": true,
"_location": "/fs-write-stream-atomic",
- "_nodeVersion": "4.2.2",
+ "_nodeVersion": "7.7.1",
+ "_npmOperationalInternal": {
+ "host": "packages-12-west.internal.npmjs.com",
+ "tmp": "tmp/fs-write-stream-atomic-1.0.10.tgz_1488925398888_0.6416559314820915"
+ },
"_npmUser": {
- "email": "me@re-becca.org",
- "name": "iarna"
+ "name": "iarna",
+ "email": "me@re-becca.org"
},
- "_npmVersion": "3.5.2",
+ "_npmVersion": "4.4.1",
"_phantomChildren": {},
"_requested": {
- "name": "fs-write-stream-atomic",
- "raw": "fs-write-stream-atomic@1.0.8",
- "rawSpec": "1.0.8",
+ "raw": "fs-write-stream-atomic@latest",
"scope": null,
- "spec": "1.0.8",
- "type": "version"
+ "escapedName": "fs-write-stream-atomic",
+ "name": "fs-write-stream-atomic",
+ "rawSpec": "latest",
+ "spec": "latest",
+ "type": "tag"
},
"_requiredBy": [
- "/"
+ "#USER",
+ "/",
+ "/@npmcorp/move",
+ "/@npmcorp/move/@npmcorp/copy"
],
- "_shasum": "e49aaddf288f87d46ff9e882f216a13abc40778b",
+ "_resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+ "_shasum": "b47df53493ef911df75731e70a9ded0189db40c9",
"_shrinkwrap": null,
- "_spec": "fs-write-stream-atomic@1.0.8",
- "_where": "/Users/rebecca/code/npm",
+ "_spec": "fs-write-stream-atomic@latest",
+ "_where": "/Users/zkat/Documents/code/npm",
"author": {
- "email": "i@izs.me",
"name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
"url": "http://blog.izs.me/"
},
"bugs": {
@@ -56,10 +72,10 @@
"test": "test"
},
"dist": {
- "shasum": "e49aaddf288f87d46ff9e882f216a13abc40778b",
- "tarball": "http://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.8.tgz"
+ "shasum": "b47df53493ef911df75731e70a9ded0189db40c9",
+ "tarball": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz"
},
- "gitHead": "b55824ee4de7f1ca23784929d68b1b8f5edbf4a4",
+ "gitHead": "de157c0373a40fb5539640923cab9671cef08b12",
"homepage": "https://github.com/npm/fs-write-stream-atomic",
"license": "ISC",
"main": "index.js",
@@ -91,5 +107,5 @@
"scripts": {
"test": "standard && tap --coverage test/*.js"
},
- "version": "1.0.8"
+ "version": "1.0.10"
}
diff --git a/node_modules/fs-write-stream-atomic/test/rename-eperm.js b/node_modules/fs-write-stream-atomic/test/rename-eperm.js
new file mode 100644
index 000000000..b1be0f318
--- /dev/null
+++ b/node_modules/fs-write-stream-atomic/test/rename-eperm.js
@@ -0,0 +1,154 @@
+'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-eperm1')
+var target2 = path.resolve(__dirname, 'test-rename-eperm2')
+var target3 = path.resolve(__dirname, 'test-rename-eperm3')
+
+test('rename eperm none existing file', function (t) {
+ t.plan(2)
+
+ var _rename = fs.rename
+ fs.existsSync = function (src) {
+ return true
+ }
+ fs.rename = function (src, dest, cb) {
+ // simulate a failure during rename where the file
+ // is renamed successfully but the process encounters
+ // an EPERM error and the target file does not exist
+ _rename(src, dest, function (e) {
+ var err = new Error('TEST BREAK')
+ err.syscall = 'rename'
+ err.code = 'EPERM'
+ cb(err)
+ })
+ }
+
+ var stream = writeStream(target, { isWin: true })
+ var hadError = false
+ var calledFinish = false
+ stream.on('error', function (er) {
+ hadError = true
+ console.log('#', er)
+ })
+ stream.on('finish', function () {
+ calledFinish = true
+ })
+ stream.on('close', function () {
+ t.is(hadError, true, 'error was caught')
+ t.is(calledFinish, false, 'finish was called before close')
+ })
+ stream.end()
+})
+
+// test existing file with diff. content
+test('rename eperm existing file different content', function (t) {
+ t.plan(2)
+
+ var _rename = fs.rename
+ fs.existsSync = function (src) {
+ return true
+ }
+ fs.rename = function (src, dest, cb) {
+ // simulate a failure during rename where the file
+ // is renamed successfully but the process encounters
+ // an EPERM error and the target file that has another content than the
+ // destination
+ _rename(src, dest, function (e) {
+ fs.writeFile(src, 'dest', function (writeErr) {
+ if (writeErr) {
+ return console.log('WRITEERR: ' + writeErr)
+ }
+
+ fs.writeFile(target2, 'target', function (writeErr) {
+ if (writeErr) {
+ return console.log('WRITEERR: ' + writeErr)
+ }
+
+ var err = new Error('TEST BREAK')
+ err.syscall = 'rename'
+ err.code = 'EPERM'
+ cb(err)
+ })
+ })
+ })
+ }
+
+ var stream = writeStream(target2, { isWin: true })
+ var hadError = false
+ var calledFinish = false
+ stream.on('error', function (er) {
+ hadError = true
+ console.log('#', er)
+ })
+ stream.on('finish', function () {
+ calledFinish = true
+ })
+ stream.on('close', function () {
+ t.is(hadError, true, 'error was caught')
+ t.is(calledFinish, false, 'finish was called before close')
+ })
+ stream.end()
+})
+
+// test existing file with the same content
+// test existing file with diff. content
+test('rename eperm existing file different content', function (t) {
+ t.plan(2)
+
+ var _rename = fs.rename
+ fs.existsSync = function (src) {
+ return true
+ }
+ fs.rename = function (src, dest, cb) {
+ // simulate a failure during rename where the file
+ // is renamed successfully but the process encounters
+ // an EPERM error and the target file that has the same content than the
+ // destination
+ _rename(src, dest, function (e) {
+ fs.writeFile(src, 'target2', function (writeErr) {
+ if (writeErr) {
+ return console.log('WRITEERR: ' + writeErr)
+ }
+
+ fs.writeFile(target3, 'target2', function (writeErr) {
+ if (writeErr) {
+ return console.log('WRITEERR: ' + writeErr)
+ }
+
+ var err = new Error('TEST BREAK')
+ err.syscall = 'rename'
+ err.code = 'EPERM'
+ cb(err)
+ })
+ })
+ })
+ }
+
+ var stream = writeStream(target3, { isWin: true })
+ var hadError = false
+ var calledFinish = false
+ stream.on('error', function (er) {
+ hadError = true
+ console.log('#', er)
+ })
+ stream.on('finish', function () {
+ calledFinish = true
+ })
+ stream.on('close', function () {
+ t.is(hadError, false, 'error was caught')
+ t.is(calledFinish, true, 'finish was called before close')
+ })
+ stream.end()
+})
+
+test('cleanup', function (t) {
+ rimraf.sync(target)
+ rimraf.sync(target2)
+ rimraf.sync(target3)
+ t.end()
+})
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index 56bcf04d7..0d6e4757a 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -132,8 +132,9 @@
"resolved": "https://registry.npmjs.org/fs-vacuum/-/fs-vacuum-1.2.9.tgz"
},
"fs-write-stream-atomic": {
- "version": "1.0.8",
- "from": "fs-write-stream-atomic@1.0.8"
+ "version": "1.0.10",
+ "from": "fs-write-stream-atomic@latest",
+ "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz"
},
"fstream": {
"version": "1.0.10",
diff --git a/package.json b/package.json
index c10cf8ddf..af2e3b9e9 100644
--- a/package.json
+++ b/package.json
@@ -48,7 +48,7 @@
"dezalgo": "~1.0.3",
"editor": "~1.0.0",
"fs-vacuum": "~1.2.9",
- "fs-write-stream-atomic": "~1.0.8",
+ "fs-write-stream-atomic": "~1.0.10",
"fstream": "~1.0.10",
"fstream-npm": "~1.2.0",
"glob": "~7.1.1",