diff options
author | Rebecca Turner <me@re-becca.org> | 2017-08-19 04:21:29 +0300 |
---|---|---|
committer | Rebecca Turner <me@re-becca.org> | 2017-08-23 02:17:29 +0300 |
commit | 7ef0d282018cb82c8d4ebd5eeafd2a2be289d6f7 (patch) | |
tree | e8968b9523574caf0749d25b7cd1e45d4a0b820a /node_modules/node-gyp | |
parent | c7e10f28c0438923d35407ae7c011dd5b6af788a (diff) |
fstream@REMOVE
Credit: @isaacs
Reviewed-By: @iarna
PR-URL: https://github.com/npm/npm/pull/16804
Diffstat (limited to 'node_modules/node-gyp')
24 files changed, 2455 insertions, 0 deletions
diff --git a/node_modules/node-gyp/node_modules/fstream/.npmignore b/node_modules/node-gyp/node_modules/fstream/.npmignore new file mode 100644 index 000000000..494272a81 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/.npmignore @@ -0,0 +1,5 @@ +.*.swp +node_modules/ +examples/deep-copy/ +examples/path/ +examples/filter-copy/ diff --git a/node_modules/node-gyp/node_modules/fstream/.travis.yml b/node_modules/node-gyp/node_modules/fstream/.travis.yml new file mode 100644 index 000000000..9f5972ab5 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/.travis.yml @@ -0,0 +1,9 @@ +language: node_js +node_js: + - "6" + - "4" + - "0.10" + - "0.12" +before_install: + - "npm config set spin false" + - "npm install -g npm/npm" diff --git a/node_modules/node-gyp/node_modules/fstream/LICENSE b/node_modules/node-gyp/node_modules/fstream/LICENSE new file mode 100644 index 000000000..19129e315 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/node-gyp/node_modules/fstream/README.md b/node_modules/node-gyp/node_modules/fstream/README.md new file mode 100644 index 000000000..9d8cb77e5 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/README.md @@ -0,0 +1,76 @@ +Like FS streams, but with stat on them, and supporting directories and +symbolic links, as well as normal files. Also, you can use this to set +the stats on a file, even if you don't change its contents, or to create +a symlink, etc. + +So, for example, you can "write" a directory, and it'll call `mkdir`. You +can specify a uid and gid, and it'll call `chown`. You can specify a +`mtime` and `atime`, and it'll call `utimes`. You can call it a symlink +and provide a `linkpath` and it'll call `symlink`. + +Note that it won't automatically resolve symbolic links. So, if you +call `fstream.Reader('/some/symlink')` then you'll get an object +that stats and then ends immediately (since it has no data). To follow +symbolic links, do this: `fstream.Reader({path:'/some/symlink', follow: +true })`. + +There are various checks to make sure that the bytes emitted are the +same as the intended size, if the size is set. + +## Examples + +```javascript +fstream + .Writer({ path: "path/to/file" + , mode: 0755 + , size: 6 + }) + .write("hello\n") + .end() +``` + +This will create the directories if they're missing, and then write +`hello\n` into the file, chmod it to 0755, and assert that 6 bytes have +been written when it's done. + +```javascript +fstream + .Writer({ path: "path/to/file" + , mode: 0755 + , size: 6 + , flags: "a" + }) + .write("hello\n") + .end() +``` + +You can pass flags in, if you want to append to a file. + +```javascript +fstream + .Writer({ path: "path/to/symlink" + , linkpath: "./file" + , SymbolicLink: true + , mode: "0755" // octal strings supported + }) + .end() +``` + +If isSymbolicLink is a function, it'll be called, and if it returns +true, then it'll treat it as a symlink. If it's not a function, then +any truish value will make a symlink, or you can set `type: +'SymbolicLink'`, which does the same thing. + +Note that the linkpath is relative to the symbolic link location, not +the parent dir or cwd. + +```javascript +fstream + .Reader("path/to/dir") + .pipe(fstream.Writer("path/to/other/dir")) +``` + +This will do like `cp -Rp path/to/dir path/to/other/dir`. If the other +dir exists and isn't a directory, then it'll emit an error. It'll also +set the uid, gid, mode, etc. to be identical. In this way, it's more +like `rsync -a` than simply a copy. diff --git a/node_modules/node-gyp/node_modules/fstream/examples/filter-pipe.js b/node_modules/node-gyp/node_modules/fstream/examples/filter-pipe.js new file mode 100644 index 000000000..83dadef8a --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/examples/filter-pipe.js @@ -0,0 +1,134 @@ +var fstream = require('../fstream.js') +var path = require('path') + +var r = fstream.Reader({ + path: path.dirname(__dirname), + filter: function () { + return !this.basename.match(/^\./) && + !this.basename.match(/^node_modules$/) && + !this.basename.match(/^deep-copy$/) && + !this.basename.match(/^filter-copy$/) + } +}) + +// this writer will only write directories +var w = fstream.Writer({ + path: path.resolve(__dirname, 'filter-copy'), + type: 'Directory', + filter: function () { + return this.type === 'Directory' + } +}) + +var indent = '' + +r.on('entry', appears) +r.on('ready', function () { + console.error('ready to begin!', r.path) +}) + +function appears (entry) { + console.error(indent + 'a %s appears!', entry.type, entry.basename, typeof entry.basename) + if (foggy) { + console.error('FOGGY!') + var p = entry + do { + console.error(p.depth, p.path, p._paused) + p = p.parent + } while (p) + + throw new Error('\u001b[mshould not have entries while foggy') + } + indent += '\t' + entry.on('data', missile(entry)) + entry.on('end', runaway(entry)) + entry.on('entry', appears) +} + +var foggy +function missile (entry) { + function liftFog (who) { + if (!foggy) return + if (who) { + console.error('%s breaks the spell!', who && who.path) + } else { + console.error('the spell expires!') + } + console.error('\u001b[mthe fog lifts!\n') + clearTimeout(foggy) + foggy = null + if (entry._paused) entry.resume() + } + + if (entry.type === 'Directory') { + var ended = false + entry.once('end', function () { ended = true }) + return function (c) { + // throw in some pathological pause()/resume() behavior + // just for extra fun. + process.nextTick(function () { + if (!foggy && !ended) { // && Math.random() < 0.3) { + console.error(indent + '%s casts a spell', entry.basename) + console.error('\na slowing fog comes over the battlefield...\n\u001b[32m') + entry.pause() + entry.once('resume', liftFog) + foggy = setTimeout(liftFog, 1000) + } + }) + } + } + + return function (c) { + var e = Math.random() < 0.5 + console.error(indent + '%s %s for %d damage!', + entry.basename, + e ? 'is struck' : 'fires a chunk', + c.length) + } +} + +function runaway (entry) { + return function () { + var e = Math.random() < 0.5 + console.error(indent + '%s %s', + entry.basename, + e ? 'turns to flee' : 'is vanquished!') + indent = indent.slice(0, -1) + } +} + +w.on('entry', attacks) +// w.on('ready', function () { attacks(w) }) +function attacks (entry) { + console.error(indent + '%s %s!', entry.basename, + entry.type === 'Directory' ? 'calls for backup' : 'attacks') + entry.on('entry', attacks) +} + +var ended = false +var i = 1 +r.on('end', function () { + if (foggy) clearTimeout(foggy) + console.error("\u001b[mIT'S OVER!!") + console.error('A WINNAR IS YOU!') + + console.log('ok ' + (i++) + ' A WINNAR IS YOU') + ended = true + // now go through and verify that everything in there is a dir. + var p = path.resolve(__dirname, 'filter-copy') + var checker = fstream.Reader({ path: p }) + checker.checker = true + checker.on('child', function (e) { + var ok = e.type === 'Directory' + console.log((ok ? '' : 'not ') + 'ok ' + (i++) + + ' should be a dir: ' + + e.path.substr(checker.path.length + 1)) + }) +}) + +process.on('exit', function () { + console.log((ended ? '' : 'not ') + 'ok ' + (i) + ' ended') + console.log('1..' + i) +}) + +r.pipe(w) diff --git a/node_modules/node-gyp/node_modules/fstream/examples/pipe.js b/node_modules/node-gyp/node_modules/fstream/examples/pipe.js new file mode 100644 index 000000000..3de42ef32 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/examples/pipe.js @@ -0,0 +1,118 @@ +var fstream = require('../fstream.js') +var path = require('path') + +var r = fstream.Reader({ + path: path.dirname(__dirname), + filter: function () { + return !this.basename.match(/^\./) && + !this.basename.match(/^node_modules$/) && + !this.basename.match(/^deep-copy$/) + } +}) + +var w = fstream.Writer({ + path: path.resolve(__dirname, 'deep-copy'), + type: 'Directory' +}) + +var indent = '' + +r.on('entry', appears) +r.on('ready', function () { + console.error('ready to begin!', r.path) +}) + +function appears (entry) { + console.error(indent + 'a %s appears!', entry.type, entry.basename, typeof entry.basename, entry) + if (foggy) { + console.error('FOGGY!') + var p = entry + do { + console.error(p.depth, p.path, p._paused) + p = p.parent + } while (p) + + throw new Error('\u001b[mshould not have entries while foggy') + } + indent += '\t' + entry.on('data', missile(entry)) + entry.on('end', runaway(entry)) + entry.on('entry', appears) +} + +var foggy +function missile (entry) { + function liftFog (who) { + if (!foggy) return + if (who) { + console.error('%s breaks the spell!', who && who.path) + } else { + console.error('the spell expires!') + } + console.error('\u001b[mthe fog lifts!\n') + clearTimeout(foggy) + foggy = null + if (entry._paused) entry.resume() + } + + if (entry.type === 'Directory') { + var ended = false + entry.once('end', function () { ended = true }) + return function (c) { + // throw in some pathological pause()/resume() behavior + // just for extra fun. + process.nextTick(function () { + if (!foggy && !ended) { // && Math.random() < 0.3) { + console.error(indent + '%s casts a spell', entry.basename) + console.error('\na slowing fog comes over the battlefield...\n\u001b[32m') + entry.pause() + entry.once('resume', liftFog) + foggy = setTimeout(liftFog, 10) + } + }) + } + } + + return function (c) { + var e = Math.random() < 0.5 + console.error(indent + '%s %s for %d damage!', + entry.basename, + e ? 'is struck' : 'fires a chunk', + c.length) + } +} + +function runaway (entry) { + return function () { + var e = Math.random() < 0.5 + console.error(indent + '%s %s', + entry.basename, + e ? 'turns to flee' : 'is vanquished!') + indent = indent.slice(0, -1) + } +} + +w.on('entry', attacks) +// w.on('ready', function () { attacks(w) }) +function attacks (entry) { + console.error(indent + '%s %s!', entry.basename, + entry.type === 'Directory' ? 'calls for backup' : 'attacks') + entry.on('entry', attacks) +} + +var ended = false +r.on('end', function () { + if (foggy) clearTimeout(foggy) + console.error("\u001b[mIT'S OVER!!") + console.error('A WINNAR IS YOU!') + + console.log('ok 1 A WINNAR IS YOU') + ended = true +}) + +process.on('exit', function () { + console.log((ended ? '' : 'not ') + 'ok 2 ended') + console.log('1..2') +}) + +r.pipe(w) diff --git a/node_modules/node-gyp/node_modules/fstream/examples/reader.js b/node_modules/node-gyp/node_modules/fstream/examples/reader.js new file mode 100644 index 000000000..19affbe7e --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/examples/reader.js @@ -0,0 +1,68 @@ +var fstream = require('../fstream.js') +var tap = require('tap') +var fs = require('fs') +var path = require('path') +var dir = path.dirname(__dirname) + +tap.test('reader test', function (t) { + var children = -1 + var gotReady = false + var ended = false + + var r = fstream.Reader({ + path: dir, + filter: function () { + // return this.parent === r + return this.parent === r || this === r + } + }) + + r.on('ready', function () { + gotReady = true + children = fs.readdirSync(dir).length + console.error('Setting expected children to ' + children) + t.equal(r.type, 'Directory', 'should be a directory') + }) + + r.on('entry', function (entry) { + children-- + if (!gotReady) { + t.fail('children before ready!') + } + t.equal(entry.dirname, r.path, 'basename is parent dir') + }) + + r.on('error', function (er) { + t.fail(er) + t.end() + process.exit(1) + }) + + r.on('end', function () { + t.equal(children, 0, 'should have seen all children') + ended = true + }) + + var closed = false + r.on('close', function () { + t.ok(ended, 'saw end before close') + t.notOk(closed, 'close should only happen once') + closed = true + t.end() + }) +}) + +tap.test('reader error test', function (t) { + // assumes non-root on a *nix system + var r = fstream.Reader({ path: '/etc/shadow' }) + + r.once('error', function (er) { + t.ok(true) + t.end() + }) + + r.on('end', function () { + t.fail('reader ended without error') + t.end() + }) +}) diff --git a/node_modules/node-gyp/node_modules/fstream/examples/symlink-write.js b/node_modules/node-gyp/node_modules/fstream/examples/symlink-write.js new file mode 100644 index 000000000..19e81eea9 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/examples/symlink-write.js @@ -0,0 +1,27 @@ +var fstream = require('../fstream.js') +var notOpen = false +process.chdir(__dirname) + +fstream + .Writer({ + path: 'path/to/symlink', + linkpath: './file', + isSymbolicLink: true, + mode: '0755' // octal strings supported + }) + .on('close', function () { + notOpen = true + var fs = require('fs') + var s = fs.lstatSync('path/to/symlink') + var isSym = s.isSymbolicLink() + console.log((isSym ? '' : 'not ') + 'ok 1 should be symlink') + var t = fs.readlinkSync('path/to/symlink') + var isTarget = t === './file' + console.log((isTarget ? '' : 'not ') + 'ok 2 should link to ./file') + }) + .end() + +process.on('exit', function () { + console.log((notOpen ? '' : 'not ') + 'ok 3 should be closed') + console.log('1..3') +}) diff --git a/node_modules/node-gyp/node_modules/fstream/fstream.js b/node_modules/node-gyp/node_modules/fstream/fstream.js new file mode 100644 index 000000000..c0eb3bea7 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/fstream.js @@ -0,0 +1,35 @@ +exports.Abstract = require('./lib/abstract.js') +exports.Reader = require('./lib/reader.js') +exports.Writer = require('./lib/writer.js') + +exports.File = { + Reader: require('./lib/file-reader.js'), + Writer: require('./lib/file-writer.js') +} + +exports.Dir = { + Reader: require('./lib/dir-reader.js'), + Writer: require('./lib/dir-writer.js') +} + +exports.Link = { + Reader: require('./lib/link-reader.js'), + Writer: require('./lib/link-writer.js') +} + +exports.Proxy = { + Reader: require('./lib/proxy-reader.js'), + Writer: require('./lib/proxy-writer.js') +} + +exports.Reader.Dir = exports.DirReader = exports.Dir.Reader +exports.Reader.File = exports.FileReader = exports.File.Reader +exports.Reader.Link = exports.LinkReader = exports.Link.Reader +exports.Reader.Proxy = exports.ProxyReader = exports.Proxy.Reader + +exports.Writer.Dir = exports.DirWriter = exports.Dir.Writer +exports.Writer.File = exports.FileWriter = exports.File.Writer +exports.Writer.Link = exports.LinkWriter = exports.Link.Writer +exports.Writer.Proxy = exports.ProxyWriter = exports.Proxy.Writer + +exports.collect = require('./lib/collect.js') diff --git a/node_modules/node-gyp/node_modules/fstream/lib/abstract.js b/node_modules/node-gyp/node_modules/fstream/lib/abstract.js new file mode 100644 index 000000000..97c120e1d --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/abstract.js @@ -0,0 +1,85 @@ +// the parent class for all fstreams. + +module.exports = Abstract + +var Stream = require('stream').Stream +var inherits = require('inherits') + +function Abstract () { + Stream.call(this) +} + +inherits(Abstract, Stream) + +Abstract.prototype.on = function (ev, fn) { + if (ev === 'ready' && this.ready) { + process.nextTick(fn.bind(this)) + } else { + Stream.prototype.on.call(this, ev, fn) + } + return this +} + +Abstract.prototype.abort = function () { + this._aborted = true + this.emit('abort') +} + +Abstract.prototype.destroy = function () {} + +Abstract.prototype.warn = function (msg, code) { + var self = this + var er = decorate(msg, code, self) + if (!self.listeners('warn')) { + console.error('%s %s\n' + + 'path = %s\n' + + 'syscall = %s\n' + + 'fstream_type = %s\n' + + 'fstream_path = %s\n' + + 'fstream_unc_path = %s\n' + + 'fstream_class = %s\n' + + 'fstream_stack =\n%s\n', + code || 'UNKNOWN', + er.stack, + er.path, + er.syscall, + er.fstream_type, + er.fstream_path, + er.fstream_unc_path, + er.fstream_class, + er.fstream_stack.join('\n')) + } else { + self.emit('warn', er) + } +} + +Abstract.prototype.info = function (msg, code) { + this.emit('info', msg, code) +} + +Abstract.prototype.error = function (msg, code, th) { + var er = decorate(msg, code, this) + if (th) throw er + else this.emit('error', er) +} + +function decorate (er, code, self) { + if (!(er instanceof Error)) er = new Error(er) + er.code = er.code || code + er.path = er.path || self.path + er.fstream_type = er.fstream_type || self.type + er.fstream_path = er.fstream_path || self.path + if (self._path !== self.path) { + er.fstream_unc_path = er.fstream_unc_path || self._path + } + if (self.linkpath) { + er.fstream_linkpath = er.fstream_linkpath || self.linkpath + } + er.fstream_class = er.fstream_class || self.constructor.name + er.fstream_stack = er.fstream_stack || + new Error().stack.split(/\n/).slice(3).map(function (s) { + return s.replace(/^ {4}at /, '') + }) + + return er +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/collect.js b/node_modules/node-gyp/node_modules/fstream/lib/collect.js new file mode 100644 index 000000000..e5d4f3583 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/collect.js @@ -0,0 +1,70 @@ +module.exports = collect + +function collect (stream) { + if (stream._collected) return + + if (stream._paused) return stream.on('resume', collect.bind(null, stream)) + + stream._collected = true + stream.pause() + + stream.on('data', save) + stream.on('end', save) + var buf = [] + function save (b) { + if (typeof b === 'string') b = new Buffer(b) + if (Buffer.isBuffer(b) && !b.length) return + buf.push(b) + } + + stream.on('entry', saveEntry) + var entryBuffer = [] + function saveEntry (e) { + collect(e) + entryBuffer.push(e) + } + + stream.on('proxy', proxyPause) + function proxyPause (p) { + p.pause() + } + + // replace the pipe method with a new version that will + // unlock the buffered stuff. if you just call .pipe() + // without a destination, then it'll re-play the events. + stream.pipe = (function (orig) { + return function (dest) { + // console.error(' === open the pipes', dest && dest.path) + + // let the entries flow through one at a time. + // Once they're all done, then we can resume completely. + var e = 0 + ;(function unblockEntry () { + var entry = entryBuffer[e++] + // console.error(" ==== unblock entry", entry && entry.path) + if (!entry) return resume() + entry.on('end', unblockEntry) + if (dest) dest.add(entry) + else stream.emit('entry', entry) + })() + + function resume () { + stream.removeListener('entry', saveEntry) + stream.removeListener('data', save) + stream.removeListener('end', save) + + stream.pipe = orig + if (dest) stream.pipe(dest) + + buf.forEach(function (b) { + if (b) stream.emit('data', b) + else stream.emit('end') + }) + + stream.resume() + } + + return dest + } + })(stream.pipe) +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/dir-reader.js b/node_modules/node-gyp/node_modules/fstream/lib/dir-reader.js new file mode 100644 index 000000000..820cdc85a --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/dir-reader.js @@ -0,0 +1,252 @@ +// A thing that emits "entry" events with Reader objects +// Pausing it causes it to stop emitting entry events, and also +// pauses the current entry if there is one. + +module.exports = DirReader + +var fs = require('graceful-fs') +var inherits = require('inherits') +var path = require('path') +var Reader = require('./reader.js') +var assert = require('assert').ok + +inherits(DirReader, Reader) + +function DirReader (props) { + var self = this + if (!(self instanceof DirReader)) { + throw new Error('DirReader must be called as constructor.') + } + + // should already be established as a Directory type + if (props.type !== 'Directory' || !props.Directory) { + throw new Error('Non-directory type ' + props.type) + } + + self.entries = null + self._index = -1 + self._paused = false + self._length = -1 + + if (props.sort) { + this.sort = props.sort + } + + Reader.call(this, props) +} + +DirReader.prototype._getEntries = function () { + var self = this + + // race condition. might pause() before calling _getEntries, + // and then resume, and try to get them a second time. + if (self._gotEntries) return + self._gotEntries = true + + fs.readdir(self._path, function (er, entries) { + if (er) return self.error(er) + + self.entries = entries + + self.emit('entries', entries) + if (self._paused) self.once('resume', processEntries) + else processEntries() + + function processEntries () { + self._length = self.entries.length + if (typeof self.sort === 'function') { + self.entries = self.entries.sort(self.sort.bind(self)) + } + self._read() + } + }) +} + +// start walking the dir, and emit an "entry" event for each one. +DirReader.prototype._read = function () { + var self = this + + if (!self.entries) return self._getEntries() + + if (self._paused || self._currentEntry || self._aborted) { + // console.error('DR paused=%j, current=%j, aborted=%j', self._paused, !!self._currentEntry, self._aborted) + return + } + + self._index++ + if (self._index >= self.entries.length) { + if (!self._ended) { + self._ended = true + self.emit('end') + self.emit('close') + } + return + } + + // ok, handle this one, then. + + // save creating a proxy, by stat'ing the thing now. + var p = path.resolve(self._path, self.entries[self._index]) + assert(p !== self._path) + assert(self.entries[self._index]) + + // set this to prevent trying to _read() again in the stat time. + self._currentEntry = p + fs[ self.props.follow ? 'stat' : 'lstat' ](p, function (er, stat) { + if (er) return self.error(er) + + var who = self._proxy || self + + stat.path = p + stat.basename = path.basename(p) + stat.dirname = path.dirname(p) + var childProps = self.getChildProps.call(who, stat) + childProps.path = p + childProps.basename = path.basename(p) + childProps.dirname = path.dirname(p) + + var entry = Reader(childProps, stat) + + // console.error("DR Entry", p, stat.size) + + self._currentEntry = entry + + // "entry" events are for direct entries in a specific dir. + // "child" events are for any and all children at all levels. + // This nomenclature is not completely final. + + entry.on('pause', function (who) { + if (!self._paused && !entry._disowned) { + self.pause(who) + } + }) + + entry.on('resume', function (who) { + if (self._paused && !entry._disowned) { + self.resume(who) + } + }) + + entry.on('stat', function (props) { + self.emit('_entryStat', entry, props) + if (entry._aborted) return + if (entry._paused) { + entry.once('resume', function () { + self.emit('entryStat', entry, props) + }) + } else self.emit('entryStat', entry, props) + }) + + entry.on('ready', function EMITCHILD () { + // console.error("DR emit child", entry._path) + if (self._paused) { + // console.error(" DR emit child - try again later") + // pause the child, and emit the "entry" event once we drain. + // console.error("DR pausing child entry") + entry.pause(self) + return self.once('resume', EMITCHILD) + } + + // skip over sockets. they can't be piped around properly, + // so there's really no sense even acknowledging them. + // if someone really wants to see them, they can listen to + // the "socket" events. + if (entry.type === 'Socket') { + self.emit('socket', entry) + } else { + self.emitEntry(entry) + } + }) + + var ended = false + entry.on('close', onend) + entry.on('disown', onend) + function onend () { + if (ended) return + ended = true + self.emit('childEnd', entry) + self.emit('entryEnd', entry) + self._currentEntry = null + if (!self._paused) { + self._read() + } + } + + // XXX Remove this. Works in node as of 0.6.2 or so. + // Long filenames should not break stuff. + entry.on('error', function (er) { + if (entry._swallowErrors) { + self.warn(er) + entry.emit('end') + entry.emit('close') + } else { + self.emit('error', er) + } + }) + + // proxy up some events. + ;[ + 'child', + 'childEnd', + 'warn' + ].forEach(function (ev) { + entry.on(ev, self.emit.bind(self, ev)) + }) + }) +} + +DirReader.prototype.disown = function (entry) { + entry.emit('beforeDisown') + entry._disowned = true + entry.parent = entry.root = null + if (entry === this._currentEntry) { + this._currentEntry = null + } + entry.emit('disown') +} + +DirReader.prototype.getChildProps = function () { + return { + depth: this.depth + 1, + root: this.root || this, + parent: this, + follow: this.follow, + filter: this.filter, + sort: this.props.sort, + hardlinks: this.props.hardlinks + } +} + +DirReader.prototype.pause = function (who) { + var self = this + if (self._paused) return + who = who || self + self._paused = true + if (self._currentEntry && self._currentEntry.pause) { + self._currentEntry.pause(who) + } + self.emit('pause', who) +} + +DirReader.prototype.resume = function (who) { + var self = this + if (!self._paused) return + who = who || self + + self._paused = false + // console.error('DR Emit Resume', self._path) + self.emit('resume', who) + if (self._paused) { + // console.error('DR Re-paused', self._path) + return + } + + if (self._currentEntry) { + if (self._currentEntry.resume) self._currentEntry.resume(who) + } else self._read() +} + +DirReader.prototype.emitEntry = function (entry) { + this.emit('entry', entry) + this.emit('child', entry) +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/dir-writer.js b/node_modules/node-gyp/node_modules/fstream/lib/dir-writer.js new file mode 100644 index 000000000..ec50dca90 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/dir-writer.js @@ -0,0 +1,174 @@ +// It is expected that, when .add() returns false, the consumer +// of the DirWriter will pause until a "drain" event occurs. Note +// that this is *almost always going to be the case*, unless the +// thing being written is some sort of unsupported type, and thus +// skipped over. + +module.exports = DirWriter + +var Writer = require('./writer.js') +var inherits = require('inherits') +var mkdir = require('mkdirp') +var path = require('path') +var collect = require('./collect.js') + +inherits(DirWriter, Writer) + +function DirWriter (props) { + var self = this + if (!(self instanceof DirWriter)) { + self.error('DirWriter must be called as constructor.', null, true) + } + + // should already be established as a Directory type + if (props.type !== 'Directory' || !props.Directory) { + self.error('Non-directory type ' + props.type + ' ' + + JSON.stringify(props), null, true) + } + + Writer.call(this, props) +} + +DirWriter.prototype._create = function () { + var self = this + mkdir(self._path, Writer.dirmode, function (er) { + if (er) return self.error(er) + // ready to start getting entries! + self.ready = true + self.emit('ready') + self._process() + }) +} + +// a DirWriter has an add(entry) method, but its .write() doesn't +// do anything. Why a no-op rather than a throw? Because this +// leaves open the door for writing directory metadata for +// gnu/solaris style dumpdirs. +DirWriter.prototype.write = function () { + return true +} + +DirWriter.prototype.end = function () { + this._ended = true + this._process() +} + +DirWriter.prototype.add = function (entry) { + var self = this + + // console.error('\tadd', entry._path, '->', self._path) + collect(entry) + if (!self.ready || self._currentEntry) { + self._buffer.push(entry) + return false + } + + // create a new writer, and pipe the incoming entry into it. + if (self._ended) { + return self.error('add after end') + } + + self._buffer.push(entry) + self._process() + + return this._buffer.length === 0 +} + +DirWriter.prototype._process = function () { + var self = this + + // console.error('DW Process p=%j', self._processing, self.basename) + + if (self._processing) return + + var entry = self._buffer.shift() + if (!entry) { + // console.error("DW Drain") + self.emit('drain') + if (self._ended) self._finish() + return + } + + self._processing = true + // console.error("DW Entry", entry._path) + + self.emit('entry', entry) + + // ok, add this entry + // + // don't allow recursive copying + var p = entry + var pp + do { + pp = p._path || p.path + if (pp === self.root._path || pp === self._path || + (pp && pp.indexOf(self._path) === 0)) { + // console.error('DW Exit (recursive)', entry.basename, self._path) + self._processing = false + if (entry._collected) entry.pipe() + return self._process() + } + p = p.parent + } while (p) + + // console.error("DW not recursive") + + // chop off the entry's root dir, replace with ours + var props = { + parent: self, + root: self.root || self, + type: entry.type, + depth: self.depth + 1 + } + + pp = entry._path || entry.path || entry.props.path + if (entry.parent) { + pp = pp.substr(entry.parent._path.length + 1) + } + // get rid of any ../../ shenanigans + props.path = path.join(self.path, path.join('/', pp)) + + // if i have a filter, the child should inherit it. + props.filter = self.filter + + // all the rest of the stuff, copy over from the source. + Object.keys(entry.props).forEach(function (k) { + if (!props.hasOwnProperty(k)) { + props[k] = entry.props[k] + } + }) + + // not sure at this point what kind of writer this is. + var child = self._currentChild = new Writer(props) + child.on('ready', function () { + // console.error("DW Child Ready", child.type, child._path) + // console.error(" resuming", entry._path) + entry.pipe(child) + entry.resume() + }) + + // XXX Make this work in node. + // Long filenames should not break stuff. + child.on('error', function (er) { + if (child._swallowErrors) { + self.warn(er) + child.emit('end') + child.emit('close') + } else { + self.emit('error', er) + } + }) + + // we fire _end internally *after* end, so that we don't move on + // until any "end" listeners have had their chance to do stuff. + child.on('close', onend) + var ended = false + function onend () { + if (ended) return + ended = true + // console.error("* DW Child end", child.basename) + self._currentChild = null + self._processing = false + self._process() + } +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/file-reader.js b/node_modules/node-gyp/node_modules/fstream/lib/file-reader.js new file mode 100644 index 000000000..baa01f4b3 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/file-reader.js @@ -0,0 +1,150 @@ +// Basically just a wrapper around an fs.ReadStream + +module.exports = FileReader + +var fs = require('graceful-fs') +var inherits = require('inherits') +var Reader = require('./reader.js') +var EOF = {EOF: true} +var CLOSE = {CLOSE: true} + +inherits(FileReader, Reader) + +function FileReader (props) { + // console.error(" FR create", props.path, props.size, new Error().stack) + var self = this + if (!(self instanceof FileReader)) { + throw new Error('FileReader must be called as constructor.') + } + + // should already be established as a File type + // XXX Todo: preserve hardlinks by tracking dev+inode+nlink, + // with a HardLinkReader class. + if (!((props.type === 'Link' && props.Link) || + (props.type === 'File' && props.File))) { + throw new Error('Non-file type ' + props.type) + } + + self._buffer = [] + self._bytesEmitted = 0 + Reader.call(self, props) +} + +FileReader.prototype._getStream = function () { + var self = this + var stream = self._stream = fs.createReadStream(self._path, self.props) + + if (self.props.blksize) { + stream.bufferSize = self.props.blksize + } + + stream.on('open', self.emit.bind(self, 'open')) + + stream.on('data', function (c) { + // console.error('\t\t%d %s', c.length, self.basename) + self._bytesEmitted += c.length + // no point saving empty chunks + if (!c.length) { + return + } else if (self._paused || self._buffer.length) { + self._buffer.push(c) + self._read() + } else self.emit('data', c) + }) + + stream.on('end', function () { + if (self._paused || self._buffer.length) { + // console.error('FR Buffering End', self._path) + self._buffer.push(EOF) + self._read() + } else { + self.emit('end') + } + + if (self._bytesEmitted !== self.props.size) { + self.error("Didn't get expected byte count\n" + + 'expect: ' + self.props.size + '\n' + + 'actual: ' + self._bytesEmitted) + } + }) + + stream.on('close', function () { + if (self._paused || self._buffer.length) { + // console.error('FR Buffering Close', self._path) + self._buffer.push(CLOSE) + self._read() + } else { + // console.error('FR close 1', self._path) + self.emit('close') + } + }) + + stream.on('error', function (e) { + self.emit('error', e) + }) + + self._read() +} + +FileReader.prototype._read = function () { + var self = this + // console.error('FR _read', self._path) + if (self._paused) { + // console.error('FR _read paused', self._path) + return + } + + if (!self._stream) { + // console.error('FR _getStream calling', self._path) + return self._getStream() + } + + // clear out the buffer, if there is one. + if (self._buffer.length) { + // console.error('FR _read has buffer', self._buffer.length, self._path) + var buf = self._buffer + for (var i = 0, l = buf.length; i < l; i++) { + var c = buf[i] + if (c === EOF) { + // console.error('FR Read emitting buffered end', self._path) + self.emit('end') + } else if (c === CLOSE) { + // console.error('FR Read emitting buffered close', self._path) + self.emit('close') + } else { + // console.error('FR Read emitting buffered data', self._path) + self.emit('data', c) + } + + if (self._paused) { + // console.error('FR Read Re-pausing at '+i, self._path) + self._buffer = buf.slice(i) + return + } + } + self._buffer.length = 0 + } +// console.error("FR _read done") +// that's about all there is to it. +} + +FileReader.prototype.pause = function (who) { + var self = this + // console.error('FR Pause', self._path) + if (self._paused) return + who = who || self + self._paused = true + if (self._stream) self._stream.pause() + self.emit('pause', who) +} + +FileReader.prototype.resume = function (who) { + var self = this + // console.error('FR Resume', self._path) + if (!self._paused) return + who = who || self + self.emit('resume', who) + self._paused = false + if (self._stream) self._stream.resume() + self._read() +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/file-writer.js b/node_modules/node-gyp/node_modules/fstream/lib/file-writer.js new file mode 100644 index 000000000..4c803d8d6 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/file-writer.js @@ -0,0 +1,107 @@ +module.exports = FileWriter + +var fs = require('graceful-fs') +var Writer = require('./writer.js') +var inherits = require('inherits') +var EOF = {} + +inherits(FileWriter, Writer) + +function FileWriter (props) { + var self = this + if (!(self instanceof FileWriter)) { + throw new Error('FileWriter must be called as constructor.') + } + + // should already be established as a File type + if (props.type !== 'File' || !props.File) { + throw new Error('Non-file type ' + props.type) + } + + self._buffer = [] + self._bytesWritten = 0 + + Writer.call(this, props) +} + +FileWriter.prototype._create = function () { + var self = this + if (self._stream) return + + var so = {} + if (self.props.flags) so.flags = self.props.flags + so.mode = Writer.filemode + if (self._old && self._old.blksize) so.bufferSize = self._old.blksize + + self._stream = fs.createWriteStream(self._path, so) + + self._stream.on('open', function () { + // console.error("FW open", self._buffer, self._path) + self.ready = true + self._buffer.forEach(function (c) { + if (c === EOF) self._stream.end() + else self._stream.write(c) + }) + self.emit('ready') + // give this a kick just in case it needs it. + self.emit('drain') + }) + + self._stream.on('error', function (er) { self.emit('error', er) }) + + self._stream.on('drain', function () { self.emit('drain') }) + + self._stream.on('close', function () { + // console.error('\n\nFW Stream Close', self._path, self.size) + self._finish() + }) +} + +FileWriter.prototype.write = function (c) { + var self = this + + self._bytesWritten += c.length + + if (!self.ready) { + if (!Buffer.isBuffer(c) && typeof c !== 'string') { + throw new Error('invalid write data') + } + self._buffer.push(c) + return false + } + + var ret = self._stream.write(c) + // console.error('\t-- fw wrote, _stream says', ret, self._stream._queue.length) + + // allow 2 buffered writes, because otherwise there's just too + // much stop and go bs. + if (ret === false && self._stream._queue) { + return self._stream._queue.length <= 2 + } else { + return ret + } +} + +FileWriter.prototype.end = function (c) { + var self = this + + if (c) self.write(c) + + if (!self.ready) { + self._buffer.push(EOF) + return false + } + + return self._stream.end() +} + +FileWriter.prototype._finish = function () { + var self = this + if (typeof self.size === 'number' && self._bytesWritten !== self.size) { + self.error( + 'Did not get expected byte count.\n' + + 'expect: ' + self.size + '\n' + + 'actual: ' + self._bytesWritten) + } + Writer.prototype._finish.call(self) +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/get-type.js b/node_modules/node-gyp/node_modules/fstream/lib/get-type.js new file mode 100644 index 000000000..19f6a657d --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/get-type.js @@ -0,0 +1,33 @@ +module.exports = getType + +function getType (st) { + var types = [ + 'Directory', + 'File', + 'SymbolicLink', + 'Link', // special for hardlinks from tarballs + 'BlockDevice', + 'CharacterDevice', + 'FIFO', + 'Socket' + ] + var type + + if (st.type && types.indexOf(st.type) !== -1) { + st[st.type] = true + return st.type + } + + for (var i = 0, l = types.length; i < l; i++) { + type = types[i] + var is = st[type] || st['is' + type] + if (typeof is === 'function') is = is.call(st) + if (is) { + st[type] = true + st.type = type + return type + } + } + + return null +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/link-reader.js b/node_modules/node-gyp/node_modules/fstream/lib/link-reader.js new file mode 100644 index 000000000..fb4cc67a9 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/link-reader.js @@ -0,0 +1,53 @@ +// Basically just a wrapper around an fs.readlink +// +// XXX: Enhance this to support the Link type, by keeping +// a lookup table of {<dev+inode>:<path>}, so that hardlinks +// can be preserved in tarballs. + +module.exports = LinkReader + +var fs = require('graceful-fs') +var inherits = require('inherits') +var Reader = require('./reader.js') + +inherits(LinkReader, Reader) + +function LinkReader (props) { + var self = this + if (!(self instanceof LinkReader)) { + throw new Error('LinkReader must be called as constructor.') + } + + if (!((props.type === 'Link' && props.Link) || + (props.type === 'SymbolicLink' && props.SymbolicLink))) { + throw new Error('Non-link type ' + props.type) + } + + Reader.call(self, props) +} + +// When piping a LinkReader into a LinkWriter, we have to +// already have the linkpath property set, so that has to +// happen *before* the "ready" event, which means we need to +// override the _stat method. +LinkReader.prototype._stat = function (currentStat) { + var self = this + fs.readlink(self._path, function (er, linkpath) { + if (er) return self.error(er) + self.linkpath = self.props.linkpath = linkpath + self.emit('linkpath', linkpath) + Reader.prototype._stat.call(self, currentStat) + }) +} + +LinkReader.prototype._read = function () { + var self = this + if (self._paused) return + // basically just a no-op, since we got all the info we need + // from the _stat method + if (!self._ended) { + self.emit('end') + self.emit('close') + self._ended = true + } +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/link-writer.js b/node_modules/node-gyp/node_modules/fstream/lib/link-writer.js new file mode 100644 index 000000000..af5428400 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/link-writer.js @@ -0,0 +1,95 @@ +module.exports = LinkWriter + +var fs = require('graceful-fs') +var Writer = require('./writer.js') +var inherits = require('inherits') +var path = require('path') +var rimraf = require('rimraf') + +inherits(LinkWriter, Writer) + +function LinkWriter (props) { + var self = this + if (!(self instanceof LinkWriter)) { + throw new Error('LinkWriter must be called as constructor.') + } + + // should already be established as a Link type + if (!((props.type === 'Link' && props.Link) || + (props.type === 'SymbolicLink' && props.SymbolicLink))) { + throw new Error('Non-link type ' + props.type) + } + + if (props.linkpath === '') props.linkpath = '.' + if (!props.linkpath) { + self.error('Need linkpath property to create ' + props.type) + } + + Writer.call(this, props) +} + +LinkWriter.prototype._create = function () { + // console.error(" LW _create") + var self = this + var hard = self.type === 'Link' || process.platform === 'win32' + var link = hard ? 'link' : 'symlink' + var lp = hard ? path.resolve(self.dirname, self.linkpath) : self.linkpath + + // can only change the link path by clobbering + // For hard links, let's just assume that's always the case, since + // there's no good way to read them if we don't already know. + if (hard) return clobber(self, lp, link) + + fs.readlink(self._path, function (er, p) { + // only skip creation if it's exactly the same link + if (p && p === lp) return finish(self) + clobber(self, lp, link) + }) +} + +function clobber (self, lp, link) { + rimraf(self._path, function (er) { + if (er) return self.error(er) + create(self, lp, link) + }) +} + +function create (self, lp, link) { + fs[link](lp, self._path, function (er) { + // if this is a hard link, and we're in the process of writing out a + // directory, it's very possible that the thing we're linking to + // doesn't exist yet (especially if it was intended as a symlink), + // so swallow ENOENT errors here and just soldier in. + // Additionally, an EPERM or EACCES can happen on win32 if it's trying + // to make a link to a directory. Again, just skip it. + // A better solution would be to have fs.symlink be supported on + // windows in some nice fashion. + if (er) { + if ((er.code === 'ENOENT' || + er.code === 'EACCES' || + er.code === 'EPERM') && process.platform === 'win32') { + self.ready = true + self.emit('ready') + self.emit('end') + self.emit('close') + self.end = self._finish = function () {} + } else return self.error(er) + } + finish(self) + }) +} + +function finish (self) { + self.ready = true + self.emit('ready') + if (self._ended && !self._finished) self._finish() +} + +LinkWriter.prototype.end = function () { + // console.error("LW finish in end") + this._ended = true + if (this.ready) { + this._finished = true + this._finish() + } +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/proxy-reader.js b/node_modules/node-gyp/node_modules/fstream/lib/proxy-reader.js new file mode 100644 index 000000000..4f431c9d9 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/proxy-reader.js @@ -0,0 +1,95 @@ +// A reader for when we don't yet know what kind of thing +// the thing is. + +module.exports = ProxyReader + +var Reader = require('./reader.js') +var getType = require('./get-type.js') +var inherits = require('inherits') +var fs = require('graceful-fs') + +inherits(ProxyReader, Reader) + +function ProxyReader (props) { + var self = this + if (!(self instanceof ProxyReader)) { + throw new Error('ProxyReader must be called as constructor.') + } + + self.props = props + self._buffer = [] + self.ready = false + + Reader.call(self, props) +} + +ProxyReader.prototype._stat = function () { + var self = this + var props = self.props + // stat the thing to see what the proxy should be. + var stat = props.follow ? 'stat' : 'lstat' + + fs[stat](props.path, function (er, current) { + var type + if (er || !current) { + type = 'File' + } else { + type = getType(current) + } + + props[type] = true + props.type = self.type = type + + self._old = current + self._addProxy(Reader(props, current)) + }) +} + +ProxyReader.prototype._addProxy = function (proxy) { + var self = this + if (self._proxyTarget) { + return self.error('proxy already set') + } + + self._proxyTarget = proxy + proxy._proxy = self + + ;[ + 'error', + 'data', + 'end', + 'close', + 'linkpath', + 'entry', + 'entryEnd', + 'child', + 'childEnd', + 'warn', + 'stat' + ].forEach(function (ev) { + // console.error('~~ proxy event', ev, self.path) + proxy.on(ev, self.emit.bind(self, ev)) + }) + + self.emit('proxy', proxy) + + proxy.on('ready', function () { + // console.error("~~ proxy is ready!", self.path) + self.ready = true + self.emit('ready') + }) + + var calls = self._buffer + self._buffer.length = 0 + calls.forEach(function (c) { + proxy[c[0]].apply(proxy, c[1]) + }) +} + +ProxyReader.prototype.pause = function () { + return this._proxyTarget ? this._proxyTarget.pause() : false +} + +ProxyReader.prototype.resume = function () { + return this._proxyTarget ? this._proxyTarget.resume() : false +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/proxy-writer.js b/node_modules/node-gyp/node_modules/fstream/lib/proxy-writer.js new file mode 100644 index 000000000..a6544621b --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/proxy-writer.js @@ -0,0 +1,111 @@ +// A writer for when we don't know what kind of thing +// the thing is. That is, it's not explicitly set, +// so we're going to make it whatever the thing already +// is, or "File" +// +// Until then, collect all events. + +module.exports = ProxyWriter + +var Writer = require('./writer.js') +var getType = require('./get-type.js') +var inherits = require('inherits') +var collect = require('./collect.js') +var fs = require('fs') + +inherits(ProxyWriter, Writer) + +function ProxyWriter (props) { + var self = this + if (!(self instanceof ProxyWriter)) { + throw new Error('ProxyWriter must be called as constructor.') + } + + self.props = props + self._needDrain = false + + Writer.call(self, props) +} + +ProxyWriter.prototype._stat = function () { + var self = this + var props = self.props + // stat the thing to see what the proxy should be. + var stat = props.follow ? 'stat' : 'lstat' + + fs[stat](props.path, function (er, current) { + var type + if (er || !current) { + type = 'File' + } else { + type = getType(current) + } + + props[type] = true + props.type = self.type = type + + self._old = current + self._addProxy(Writer(props, current)) + }) +} + +ProxyWriter.prototype._addProxy = function (proxy) { + // console.error("~~ set proxy", this.path) + var self = this + if (self._proxy) { + return self.error('proxy already set') + } + + self._proxy = proxy + ;[ + 'ready', + 'error', + 'close', + 'pipe', + 'drain', + 'warn' + ].forEach(function (ev) { + proxy.on(ev, self.emit.bind(self, ev)) + }) + + self.emit('proxy', proxy) + + var calls = self._buffer + calls.forEach(function (c) { + // console.error("~~ ~~ proxy buffered call", c[0], c[1]) + proxy[c[0]].apply(proxy, c[1]) + }) + self._buffer.length = 0 + if (self._needsDrain) self.emit('drain') +} + +ProxyWriter.prototype.add = function (entry) { + // console.error("~~ proxy add") + collect(entry) + + if (!this._proxy) { + this._buffer.push(['add', [entry]]) + this._needDrain = true + return false + } + return this._proxy.add(entry) +} + +ProxyWriter.prototype.write = function (c) { + // console.error('~~ proxy write') + if (!this._proxy) { + this._buffer.push(['write', [c]]) + this._needDrain = true + return false + } + return this._proxy.write(c) +} + +ProxyWriter.prototype.end = function (c) { + // console.error('~~ proxy end') + if (!this._proxy) { + this._buffer.push(['end', [c]]) + return false + } + return this._proxy.end(c) +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/reader.js b/node_modules/node-gyp/node_modules/fstream/lib/reader.js new file mode 100644 index 000000000..be4f570ee --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/reader.js @@ -0,0 +1,255 @@ +module.exports = Reader + +var fs = require('graceful-fs') +var Stream = require('stream').Stream +var inherits = require('inherits') +var path = require('path') +var getType = require('./get-type.js') +var hardLinks = Reader.hardLinks = {} +var Abstract = require('./abstract.js') + +// Must do this *before* loading the child classes +inherits(Reader, Abstract) + +var LinkReader = require('./link-reader.js') + +function Reader (props, currentStat) { + var self = this + if (!(self instanceof Reader)) return new Reader(props, currentStat) + + if (typeof props === 'string') { + props = { path: props } + } + + // polymorphism. + // call fstream.Reader(dir) to get a DirReader object, etc. + // Note that, unlike in the Writer case, ProxyReader is going + // to be the *normal* state of affairs, since we rarely know + // the type of a file prior to reading it. + + var type + var ClassType + + if (props.type && typeof props.type === 'function') { + type = props.type + ClassType = type + } else { + type = getType(props) + ClassType = Reader + } + + if (currentStat && !type) { + type = getType(currentStat) + props[type] = true + props.type = type + } + + switch (type) { + case 'Directory': + ClassType = require('./dir-reader.js') + break + + case 'Link': + // XXX hard links are just files. + // However, it would be good to keep track of files' dev+inode + // and nlink values, and create a HardLinkReader that emits + // a linkpath value of the original copy, so that the tar + // writer can preserve them. + // ClassType = HardLinkReader + // break + + case 'File': + ClassType = require('./file-reader.js') + break + + case 'SymbolicLink': + ClassType = LinkReader + break + + case 'Socket': + ClassType = require('./socket-reader.js') + break + + case null: + ClassType = require('./proxy-reader.js') + break + } + + if (!(self instanceof ClassType)) { + return new ClassType(props) + } + + Abstract.call(self) + + if (!props.path) { + self.error('Must provide a path', null, true) + } + + self.readable = true + self.writable = false + + self.type = type + self.props = props + self.depth = props.depth = props.depth || 0 + self.parent = props.parent || null + self.root = props.root || (props.parent && props.parent.root) || self + + self._path = self.path = path.resolve(props.path) + if (process.platform === 'win32') { + self.path = self._path = self.path.replace(/\?/g, '_') + if (self._path.length >= 260) { + // how DOES one create files on the moon? + // if the path has spaces in it, then UNC will fail. + self._swallowErrors = true + // if (self._path.indexOf(" ") === -1) { + self._path = '\\\\?\\' + self.path.replace(/\//g, '\\') + // } + } + } + self.basename = props.basename = path.basename(self.path) + self.dirname = props.dirname = path.dirname(self.path) + + // these have served their purpose, and are now just noisy clutter + props.parent = props.root = null + + // console.error("\n\n\n%s setting size to", props.path, props.size) + self.size = props.size + self.filter = typeof props.filter === 'function' ? props.filter : null + if (props.sort === 'alpha') props.sort = alphasort + + // start the ball rolling. + // this will stat the thing, and then call self._read() + // to start reading whatever it is. + // console.error("calling stat", props.path, currentStat) + self._stat(currentStat) +} + +function alphasort (a, b) { + return a === b ? 0 + : a.toLowerCase() > b.toLowerCase() ? 1 + : a.toLowerCase() < b.toLowerCase() ? -1 + : a > b ? 1 + : -1 +} + +Reader.prototype._stat = function (currentStat) { + var self = this + var props = self.props + var stat = props.follow ? 'stat' : 'lstat' + // console.error("Reader._stat", self._path, currentStat) + if (currentStat) process.nextTick(statCb.bind(null, null, currentStat)) + else fs[stat](self._path, statCb) + + function statCb (er, props_) { + // console.error("Reader._stat, statCb", self._path, props_, props_.nlink) + if (er) return self.error(er) + + Object.keys(props_).forEach(function (k) { + props[k] = props_[k] + }) + + // if it's not the expected size, then abort here. + if (undefined !== self.size && props.size !== self.size) { + return self.error('incorrect size') + } + self.size = props.size + + var type = getType(props) + var handleHardlinks = props.hardlinks !== false + + // special little thing for handling hardlinks. + if (handleHardlinks && type !== 'Directory' && props.nlink && props.nlink > 1) { + var k = props.dev + ':' + props.ino + // console.error("Reader has nlink", self._path, k) + if (hardLinks[k] === self._path || !hardLinks[k]) { + hardLinks[k] = self._path + } else { + // switch into hardlink mode. + type = self.type = self.props.type = 'Link' + self.Link = self.props.Link = true + self.linkpath = self.props.linkpath = hardLinks[k] + // console.error("Hardlink detected, switching mode", self._path, self.linkpath) + // Setting __proto__ would arguably be the "correct" + // approach here, but that just seems too wrong. + self._stat = self._read = LinkReader.prototype._read + } + } + + if (self.type && self.type !== type) { + self.error('Unexpected type: ' + type) + } + + // if the filter doesn't pass, then just skip over this one. + // still have to emit end so that dir-walking can move on. + if (self.filter) { + var who = self._proxy || self + // special handling for ProxyReaders + if (!self.filter.call(who, who, props)) { + if (!self._disowned) { + self.abort() + self.emit('end') + self.emit('close') + } + return + } + } + + // last chance to abort or disown before the flow starts! + var events = ['_stat', 'stat', 'ready'] + var e = 0 + ;(function go () { + if (self._aborted) { + self.emit('end') + self.emit('close') + return + } + + if (self._paused && self.type !== 'Directory') { + self.once('resume', go) + return + } + + var ev = events[e++] + if (!ev) { + return self._read() + } + self.emit(ev, props) + go() + })() + } +} + +Reader.prototype.pipe = function (dest) { + var self = this + if (typeof dest.add === 'function') { + // piping to a multi-compatible, and we've got directory entries. + self.on('entry', function (entry) { + var ret = dest.add(entry) + if (ret === false) { + self.pause() + } + }) + } + + // console.error("R Pipe apply Stream Pipe") + return Stream.prototype.pipe.apply(this, arguments) +} + +Reader.prototype.pause = function (who) { + this._paused = true + who = who || this + this.emit('pause', who) + if (this._stream) this._stream.pause(who) +} + +Reader.prototype.resume = function (who) { + this._paused = false + who = who || this + this.emit('resume', who) + if (this._stream) this._stream.resume(who) + this._read() +} + +Reader.prototype._read = function () { + this.error('Cannot read unknown type: ' + this.type) +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/socket-reader.js b/node_modules/node-gyp/node_modules/fstream/lib/socket-reader.js new file mode 100644 index 000000000..e0456ba89 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/socket-reader.js @@ -0,0 +1,36 @@ +// Just get the stats, and then don't do anything. +// You can't really "read" from a socket. You "connect" to it. +// Mostly, this is here so that reading a dir with a socket in it +// doesn't blow up. + +module.exports = SocketReader + +var inherits = require('inherits') +var Reader = require('./reader.js') + +inherits(SocketReader, Reader) + +function SocketReader (props) { + var self = this + if (!(self instanceof SocketReader)) { + throw new Error('SocketReader must be called as constructor.') + } + + if (!(props.type === 'Socket' && props.Socket)) { + throw new Error('Non-socket type ' + props.type) + } + + Reader.call(self, props) +} + +SocketReader.prototype._read = function () { + var self = this + if (self._paused) return + // basically just a no-op, since we got all the info we have + // from the _stat method + if (!self._ended) { + self.emit('end') + self.emit('close') + self._ended = true + } +} diff --git a/node_modules/node-gyp/node_modules/fstream/lib/writer.js b/node_modules/node-gyp/node_modules/fstream/lib/writer.js new file mode 100644 index 000000000..140e449e0 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/lib/writer.js @@ -0,0 +1,390 @@ +module.exports = Writer + +var fs = require('graceful-fs') +var inherits = require('inherits') +var rimraf = require('rimraf') +var mkdir = require('mkdirp') +var path = require('path') +var umask = process.platform === 'win32' ? 0 : process.umask() +var getType = require('./get-type.js') +var Abstract = require('./abstract.js') + +// Must do this *before* loading the child classes +inherits(Writer, Abstract) + +Writer.dirmode = parseInt('0777', 8) & (~umask) +Writer.filemode = parseInt('0666', 8) & (~umask) + +var DirWriter = require('./dir-writer.js') +var LinkWriter = require('./link-writer.js') +var FileWriter = require('./file-writer.js') +var ProxyWriter = require('./proxy-writer.js') + +// props is the desired state. current is optionally the current stat, +// provided here so that subclasses can avoid statting the target +// more than necessary. +function Writer (props, current) { + var self = this + + if (typeof props === 'string') { + props = { path: props } + } + + // polymorphism. + // call fstream.Writer(dir) to get a DirWriter object, etc. + var type = getType(props) + var ClassType = Writer + + switch (type) { + case 'Directory': + ClassType = DirWriter + break + case 'File': + ClassType = FileWriter + break + case 'Link': + case 'SymbolicLink': + ClassType = LinkWriter + break + case null: + default: + // Don't know yet what type to create, so we wrap in a proxy. + ClassType = ProxyWriter + break + } + + if (!(self instanceof ClassType)) return new ClassType(props) + + // now get down to business. + + Abstract.call(self) + + if (!props.path) self.error('Must provide a path', null, true) + + // props is what we want to set. + // set some convenience properties as well. + self.type = props.type + self.props = props + self.depth = props.depth || 0 + self.clobber = props.clobber === false ? props.clobber : true + self.parent = props.parent || null + self.root = props.root || (props.parent && props.parent.root) || self + + self._path = self.path = path.resolve(props.path) + if (process.platform === 'win32') { + self.path = self._path = self.path.replace(/\?/g, '_') + if (self._path.length >= 260) { + self._swallowErrors = true + self._path = '\\\\?\\' + self.path.replace(/\//g, '\\') + } + } + self.basename = path.basename(props.path) + self.dirname = path.dirname(props.path) + self.linkpath = props.linkpath || null + + props.parent = props.root = null + + // console.error("\n\n\n%s setting size to", props.path, props.size) + self.size = props.size + + if (typeof props.mode === 'string') { + props.mode = parseInt(props.mode, 8) + } + + self.readable = false + self.writable = true + + // buffer until ready, or while handling another entry + self._buffer = [] + self.ready = false + + self.filter = typeof props.filter === 'function' ? props.filter : null + + // start the ball rolling. + // this checks what's there already, and then calls + // self._create() to call the impl-specific creation stuff. + self._stat(current) +} + +// Calling this means that it's something we can't create. +// Just assert that it's already there, otherwise raise a warning. +Writer.prototype._create = function () { + var self = this + fs[self.props.follow ? 'stat' : 'lstat'](self._path, function (er) { + if (er) { + return self.warn('Cannot create ' + self._path + '\n' + + 'Unsupported type: ' + self.type, 'ENOTSUP') + } + self._finish() + }) +} + +Writer.prototype._stat = function (current) { + var self = this + var props = self.props + var stat = props.follow ? 'stat' : 'lstat' + var who = self._proxy || self + + if (current) statCb(null, current) + else fs[stat](self._path, statCb) + + function statCb (er, current) { + if (self.filter && !self.filter.call(who, who, current)) { + self._aborted = true + self.emit('end') + self.emit('close') + return + } + + // if it's not there, great. We'll just create it. + // if it is there, then we'll need to change whatever differs + if (er || !current) { + return create(self) + } + + self._old = current + var currentType = getType(current) + + // if it's a type change, then we need to clobber or error. + // if it's not a type change, then let the impl take care of it. + if (currentType !== self.type) { + return rimraf(self._path, function (er) { + if (er) return self.error(er) + self._old = null + create(self) + }) + } + + // otherwise, just handle in the app-specific way + // this creates a fs.WriteStream, or mkdir's, or whatever + create(self) + } +} + +function create (self) { + // console.error("W create", self._path, Writer.dirmode) + + // XXX Need to clobber non-dirs that are in the way, + // unless { clobber: false } in the props. + mkdir(path.dirname(self._path), Writer.dirmode, function (er, made) { + // console.error("W created", path.dirname(self._path), er) + if (er) return self.error(er) + + // later on, we have to set the mode and owner for these + self._madeDir = made + return self._create() + }) +} + +function endChmod (self, want, current, path, cb) { + var wantMode = want.mode + var chmod = want.follow || self.type !== 'SymbolicLink' + ? 'chmod' : 'lchmod' + + if (!fs[chmod]) return cb() + if (typeof wantMode !== 'number') return cb() + + var curMode = current.mode & parseInt('0777', 8) + wantMode = wantMode & parseInt('0777', 8) + if (wantMode === curMode) return cb() + + fs[chmod](path, wantMode, cb) +} + +function endChown (self, want, current, path, cb) { + // Don't even try it unless root. Too easy to EPERM. + if (process.platform === 'win32') return cb() + if (!process.getuid || process.getuid() !== 0) return cb() + if (typeof want.uid !== 'number' && + typeof want.gid !== 'number') return cb() + + if (current.uid === want.uid && + current.gid === want.gid) return cb() + + var chown = (self.props.follow || self.type !== 'SymbolicLink') + ? 'chown' : 'lchown' + if (!fs[chown]) return cb() + + if (typeof want.uid !== 'number') want.uid = current.uid + if (typeof want.gid !== 'number') want.gid = current.gid + + fs[chown](path, want.uid, want.gid, cb) +} + +function endUtimes (self, want, current, path, cb) { + if (!fs.utimes || process.platform === 'win32') return cb() + + var utimes = (want.follow || self.type !== 'SymbolicLink') + ? 'utimes' : 'lutimes' + + if (utimes === 'lutimes' && !fs[utimes]) { + utimes = 'utimes' + } + + if (!fs[utimes]) return cb() + + var curA = current.atime + var curM = current.mtime + var meA = want.atime + var meM = want.mtime + + if (meA === undefined) meA = curA + if (meM === undefined) meM = curM + + if (!isDate(meA)) meA = new Date(meA) + if (!isDate(meM)) meA = new Date(meM) + + if (meA.getTime() === curA.getTime() && + meM.getTime() === curM.getTime()) return cb() + + fs[utimes](path, meA, meM, cb) +} + +// XXX This function is beastly. Break it up! +Writer.prototype._finish = function () { + var self = this + + if (self._finishing) return + self._finishing = true + + // console.error(" W Finish", self._path, self.size) + + // set up all the things. + // At this point, we're already done writing whatever we've gotta write, + // adding files to the dir, etc. + var todo = 0 + var errState = null + var done = false + + if (self._old) { + // the times will almost *certainly* have changed. + // adds the utimes syscall, but remove another stat. + self._old.atime = new Date(0) + self._old.mtime = new Date(0) + // console.error(" W Finish Stale Stat", self._path, self.size) + setProps(self._old) + } else { + var stat = self.props.follow ? 'stat' : 'lstat' + // console.error(" W Finish Stating", self._path, self.size) + fs[stat](self._path, function (er, current) { + // console.error(" W Finish Stated", self._path, self.size, current) + if (er) { + // if we're in the process of writing out a + // directory, it's very possible that the thing we're linking to + // doesn't exist yet (especially if it was intended as a symlink), + // so swallow ENOENT errors here and just soldier on. + if (er.code === 'ENOENT' && + (self.type === 'Link' || self.type === 'SymbolicLink') && + process.platform === 'win32') { + self.ready = true + self.emit('ready') + self.emit('end') + self.emit('close') + self.end = self._finish = function () {} + return + } else return self.error(er) + } + setProps(self._old = current) + }) + } + + return + + function setProps (current) { + todo += 3 + endChmod(self, self.props, current, self._path, next('chmod')) + endChown(self, self.props, current, self._path, next('chown')) + endUtimes(self, self.props, current, self._path, next('utimes')) + } + + function next (what) { + return function (er) { + // console.error(" W Finish", what, todo) + if (errState) return + if (er) { + er.fstream_finish_call = what + return self.error(errState = er) + } + if (--todo > 0) return + if (done) return + done = true + + // we may still need to set the mode/etc. on some parent dirs + // that were created previously. delay end/close until then. + if (!self._madeDir) return end() + else endMadeDir(self, self._path, end) + + function end (er) { + if (er) { + er.fstream_finish_call = 'setupMadeDir' + return self.error(er) + } + // all the props have been set, so we're completely done. + self.emit('end') + self.emit('close') + } + } + } +} + +function endMadeDir (self, p, cb) { + var made = self._madeDir + // everything *between* made and path.dirname(self._path) + // needs to be set up. Note that this may just be one dir. + var d = path.dirname(p) + + endMadeDir_(self, d, function (er) { + if (er) return cb(er) + if (d === made) { + return cb() + } + endMadeDir(self, d, cb) + }) +} + +function endMadeDir_ (self, p, cb) { + var dirProps = {} + Object.keys(self.props).forEach(function (k) { + dirProps[k] = self.props[k] + + // only make non-readable dirs if explicitly requested. + if (k === 'mode' && self.type !== 'Directory') { + dirProps[k] = dirProps[k] | parseInt('0111', 8) + } + }) + + var todo = 3 + var errState = null + fs.stat(p, function (er, current) { + if (er) return cb(errState = er) + endChmod(self, dirProps, current, p, next) + endChown(self, dirProps, current, p, next) + endUtimes(self, dirProps, current, p, next) + }) + + function next (er) { + if (errState) return + if (er) return cb(errState = er) + if (--todo === 0) return cb() + } +} + +Writer.prototype.pipe = function () { + this.error("Can't pipe from writable stream") +} + +Writer.prototype.add = function () { + this.error("Can't add to non-Directory type") +} + +Writer.prototype.write = function () { + return true +} + +function objectToString (d) { + return Object.prototype.toString.call(d) +} + +function isDate (d) { + return typeof d === 'object' && objectToString(d) === '[object Date]' +} diff --git a/node_modules/node-gyp/node_modules/fstream/package.json b/node_modules/node-gyp/node_modules/fstream/package.json new file mode 100644 index 000000000..5ac16f546 --- /dev/null +++ b/node_modules/node-gyp/node_modules/fstream/package.json @@ -0,0 +1,62 @@ +{ + "_from": "fstream@^1.0.0", + "_id": "fstream@1.0.11", + "_inBundle": false, + "_integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "_location": "/node-gyp/fstream", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "fstream@^1.0.0", + "name": "fstream", + "escapedName": "fstream", + "rawSpec": "^1.0.0", + "saveSpec": null, + "fetchSpec": "^1.0.0" + }, + "_requiredBy": [ + "/node-gyp", + "/node-gyp/tar" + ], + "_resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "_shasum": "5c1fb1f117477114f0632a0eb4b71b3cb0fd3171", + "_spec": "fstream@^1.0.0", + "_where": "/Users/rebecca/code/npm/node_modules/node-gyp", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/npm/fstream/issues" + }, + "bundleDependencies": false, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "deprecated": false, + "description": "Advanced file system stream things", + "devDependencies": { + "standard": "^4.0.0", + "tap": "^1.2.0" + }, + "engines": { + "node": ">=0.6" + }, + "homepage": "https://github.com/npm/fstream#readme", + "license": "ISC", + "main": "fstream.js", + "name": "fstream", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/fstream.git" + }, + "scripts": { + "test": "standard && tap examples/*.js" + }, + "version": "1.0.11" +} |