fstream
Advanced tools
Comparing version 1.0.4 to 1.0.5
@@ -1,44 +0,46 @@ | ||
var fstream = require("../fstream.js") | ||
var path = require("path") | ||
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$/) | ||
} | ||
}) | ||
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 w = fstream.Writer({ | ||
path: path.resolve(__dirname, 'filter-copy'), | ||
type: 'Directory', | ||
filter: function () { | ||
return this.type === 'Directory' | ||
} | ||
}) | ||
var indent = "" | ||
var escape = {} | ||
var indent = '' | ||
r.on("entry", appears) | ||
r.on("ready", function () { | ||
console.error("ready to begin!", r.path) | ||
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) | ||
console.error(indent + 'a %s appears!', entry.type, entry.basename, typeof entry.basename) | ||
if (foggy) { | ||
console.error("FOGGY!") | ||
console.error('FOGGY!') | ||
var p = entry | ||
do { | ||
console.error(p.depth, p.path, p._paused) | ||
} while (p = p.parent) | ||
p = p.parent | ||
} while (p) | ||
throw new Error("\033[mshould not have entries while foggy") | ||
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) | ||
indent += '\t' | ||
entry.on('data', missile(entry)) | ||
entry.on('end', runaway(entry)) | ||
entry.on('entry', appears) | ||
} | ||
@@ -48,5 +50,18 @@ | ||
function missile (entry) { | ||
if (entry.type === "Directory") { | ||
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 }) | ||
entry.once('end', function () { ended = true }) | ||
return function (c) { | ||
@@ -57,21 +72,7 @@ // throw in some pathological pause()/resume() behavior | ||
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\033[32m") | ||
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) | ||
entry.once('resume', liftFog) | ||
foggy = setTimeout(liftFog, 1000) | ||
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("\033[mthe fog lifts!\n") | ||
clearTimeout(foggy) | ||
foggy = null | ||
if (entry._paused) entry.resume() | ||
} | ||
} | ||
@@ -84,5 +85,5 @@ }) | ||
var e = Math.random() < 0.5 | ||
console.error(indent + "%s %s for %d damage!", | ||
console.error(indent + '%s %s for %d damage!', | ||
entry.basename, | ||
e ? "is struck" : "fires a chunk", | ||
e ? 'is struck' : 'fires a chunk', | ||
c.length) | ||
@@ -92,36 +93,37 @@ } | ||
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) | ||
}} | ||
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) }) | ||
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) | ||
console.error(indent + '%s %s!', entry.basename, | ||
entry.type === 'Directory' ? 'calls for backup' : 'attacks') | ||
entry.on('entry', attacks) | ||
} | ||
ended = false | ||
var ended = false | ||
var i = 1 | ||
r.on("end", function () { | ||
r.on('end', function () { | ||
if (foggy) clearTimeout(foggy) | ||
console.error("\033[mIT'S OVER!!") | ||
console.error("A WINNAR IS YOU!") | ||
console.error("\u001b[mIT'S OVER!!") | ||
console.error('A WINNAR IS YOU!') | ||
console.log("ok " + (i ++) + " 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 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: " + | ||
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)) | ||
@@ -131,6 +133,6 @@ }) | ||
process.on("exit", function () { | ||
console.log((ended ? "" : "not ") + "ok " + (i ++) + " ended") | ||
process.on('exit', function () { | ||
console.log((ended ? '' : 'not ') + 'ok ' + (i++) + ' ended') | ||
}) | ||
r.pipe(w) |
@@ -1,39 +0,41 @@ | ||
var fstream = require("../fstream.js") | ||
var path = require("path") | ||
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 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 w = fstream.Writer({ | ||
path: path.resolve(__dirname, 'deep-copy'), | ||
type: 'Directory' | ||
}) | ||
var indent = "" | ||
var escape = {} | ||
var indent = '' | ||
r.on("entry", appears) | ||
r.on("ready", function () { | ||
console.error("ready to begin!", r.path) | ||
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) | ||
console.error(indent + 'a %s appears!', entry.type, entry.basename, typeof entry.basename, entry) | ||
if (foggy) { | ||
console.error("FOGGY!") | ||
console.error('FOGGY!') | ||
var p = entry | ||
do { | ||
console.error(p.depth, p.path, p._paused) | ||
} while (p = p.parent) | ||
p = p.parent | ||
} while (p) | ||
throw new Error("\033[mshould not have entries while foggy") | ||
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) | ||
indent += '\t' | ||
entry.on('data', missile(entry)) | ||
entry.on('end', runaway(entry)) | ||
entry.on('entry', appears) | ||
} | ||
@@ -43,5 +45,18 @@ | ||
function missile (entry) { | ||
if (entry.type === "Directory") { | ||
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 }) | ||
entry.once('end', function () { ended = true }) | ||
return function (c) { | ||
@@ -52,21 +67,7 @@ // throw in some pathological pause()/resume() behavior | ||
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\033[32m") | ||
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) | ||
entry.once('resume', liftFog) | ||
foggy = setTimeout(liftFog, 10) | ||
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("\033[mthe fog lifts!\n") | ||
clearTimeout(foggy) | ||
foggy = null | ||
if (entry._paused) entry.resume() | ||
} | ||
} | ||
@@ -79,5 +80,5 @@ }) | ||
var e = Math.random() < 0.5 | ||
console.error(indent + "%s %s for %d damage!", | ||
console.error(indent + '%s %s for %d damage!', | ||
entry.basename, | ||
e ? "is struck" : "fires a chunk", | ||
e ? 'is struck' : 'fires a chunk', | ||
c.length) | ||
@@ -87,33 +88,34 @@ } | ||
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) | ||
}} | ||
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) }) | ||
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) | ||
console.error(indent + '%s %s!', entry.basename, | ||
entry.type === 'Directory' ? 'calls for backup' : 'attacks') | ||
entry.on('entry', attacks) | ||
} | ||
ended = false | ||
r.on("end", function () { | ||
var ended = false | ||
r.on('end', function () { | ||
if (foggy) clearTimeout(foggy) | ||
console.error("\033[mIT'S OVER!!") | ||
console.error("A WINNAR IS YOU!") | ||
console.error("\u001b[mIT'S OVER!!") | ||
console.error('A WINNAR IS YOU!') | ||
console.log("ok 1 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") | ||
process.on('exit', function () { | ||
console.log((ended ? '' : 'not ') + 'ok 2 ended') | ||
}) | ||
r.pipe(w) |
@@ -1,8 +0,8 @@ | ||
var fstream = require("../fstream.js") | ||
var tap = require("tap") | ||
var fs = require("fs") | ||
var path = require("path") | ||
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) { | ||
tap.test('reader test', function (t) { | ||
var children = -1 | ||
@@ -12,25 +12,26 @@ var gotReady = false | ||
var r = fstream.Reader({ path: dir | ||
, filter: function () { | ||
// return this.parent === r | ||
return this.parent === r || this === r | ||
} | ||
}) | ||
var r = fstream.Reader({ | ||
path: dir, | ||
filter: function () { | ||
// return this.parent === r | ||
return this.parent === r || this === r | ||
} | ||
}) | ||
r.on("ready", function () { | ||
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") | ||
console.error('Setting expected children to ' + children) | ||
t.equal(r.type, 'Directory', 'should be a directory') | ||
}) | ||
r.on("entry", function (entry) { | ||
children -- | ||
r.on('entry', function (entry) { | ||
children-- | ||
if (!gotReady) { | ||
t.fail("children before ready!") | ||
t.fail('children before ready!') | ||
} | ||
t.equal(entry.dirname, r.path, "basename is parent dir") | ||
t.equal(entry.dirname, r.path, 'basename is parent dir') | ||
}) | ||
r.on("error", function (er) { | ||
r.on('error', function (er) { | ||
t.fail(er) | ||
@@ -41,4 +42,4 @@ t.end() | ||
r.on("end", function () { | ||
t.equal(children, 0, "should have seen all children") | ||
r.on('end', function () { | ||
t.equal(children, 0, 'should have seen all children') | ||
ended = true | ||
@@ -48,24 +49,23 @@ }) | ||
var closed = false | ||
r.on("close", function () { | ||
t.ok(ended, "saw end before close") | ||
t.notOk(closed, "close should only happen once") | ||
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) { | ||
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); | ||
r.once('error', function (er) { | ||
t.ok(true) | ||
t.end() | ||
}) | ||
r.on("end", function () { | ||
t.fail("reader ended without error"); | ||
r.on('end', function () { | ||
t.fail('reader ended without error') | ||
t.end() | ||
}) | ||
}) |
@@ -1,24 +0,25 @@ | ||
var fstream = require("../fstream.js") | ||
, closed = false | ||
var fstream = require('../fstream.js') | ||
var notOpen = false | ||
fstream | ||
.Writer({ path: "path/to/symlink" | ||
, linkpath: "./file" | ||
, isSymbolicLink: true | ||
, mode: "0755" // octal strings supported | ||
}) | ||
.on("close", function () { | ||
closed = true | ||
var fs = require("fs") | ||
var s = fs.lstatSync("path/to/symlink") | ||
.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") | ||
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((closed?"":"not ")+"ok 3 should be closed") | ||
process.on('exit', function () { | ||
console.log((notOpen ? '' : 'not ') + 'ok 3 should be closed') | ||
}) |
@@ -1,20 +0,24 @@ | ||
exports.Abstract = require("./lib/abstract.js") | ||
exports.Reader = require("./lib/reader.js") | ||
exports.Writer = require("./lib/writer.js") | ||
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.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.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.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.Proxy = { | ||
Reader: require('./lib/proxy-reader.js'), | ||
Writer: require('./lib/proxy-writer.js') | ||
} | ||
@@ -31,2 +35,2 @@ exports.Reader.Dir = exports.DirReader = exports.Dir.Reader | ||
exports.collect = require("./lib/collect.js") | ||
exports.collect = require('./lib/collect.js') |
@@ -5,4 +5,4 @@ // the parent class for all fstreams. | ||
var Stream = require("stream").Stream | ||
, inherits = require("inherits") | ||
var Stream = require('stream').Stream | ||
var inherits = require('inherits') | ||
@@ -16,3 +16,3 @@ function Abstract () { | ||
Abstract.prototype.on = function (ev, fn) { | ||
if (ev === "ready" && this.ready) { | ||
if (ev === 'ready' && this.ready) { | ||
process.nextTick(fn.bind(this)) | ||
@@ -27,3 +27,3 @@ } else { | ||
this._aborted = true | ||
this.emit("abort") | ||
this.emit('abort') | ||
} | ||
@@ -34,14 +34,14 @@ | ||
Abstract.prototype.warn = function (msg, code) { | ||
var me = this | ||
, er = decorate(msg, code, me) | ||
if (!me.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", | ||
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, | ||
@@ -54,5 +54,5 @@ er.path, | ||
er.fstream_class, | ||
er.fstream_stack.join("\n")) | ||
er.fstream_stack.join('\n')) | ||
} else { | ||
me.emit("warn", er) | ||
self.emit('warn', er) | ||
} | ||
@@ -62,3 +62,3 @@ } | ||
Abstract.prototype.info = function (msg, code) { | ||
this.emit("info", msg, code) | ||
this.emit('info', msg, code) | ||
} | ||
@@ -69,21 +69,21 @@ | ||
if (th) throw er | ||
else this.emit("error", er) | ||
else this.emit('error', er) | ||
} | ||
function decorate (er, code, me) { | ||
function decorate (er, code, self) { | ||
if (!(er instanceof Error)) er = new Error(er) | ||
er.code = er.code || code | ||
er.path = er.path || me.path | ||
er.fstream_type = er.fstream_type || me.type | ||
er.fstream_path = er.fstream_path || me.path | ||
if (me._path !== me.path) { | ||
er.fstream_unc_path = er.fstream_unc_path || me._path | ||
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 (me.linkpath) { | ||
er.fstream_linkpath = er.fstream_linkpath || me.linkpath | ||
if (self.linkpath) { | ||
er.fstream_linkpath = er.fstream_linkpath || self.linkpath | ||
} | ||
er.fstream_class = er.fstream_class || me.constructor.name | ||
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(/^ at /, "") | ||
return s.replace(/^ {4}at /, '') | ||
}) | ||
@@ -90,0 +90,0 @@ |
@@ -9,7 +9,7 @@ module.exports = collect | ||
stream.on("data", save) | ||
stream.on("end", save) | ||
stream.on('data', save) | ||
stream.on('end', save) | ||
var buf = [] | ||
function save (b) { | ||
if (typeof b === "string") b = new Buffer(b) | ||
if (typeof b === 'string') b = new Buffer(b) | ||
if (Buffer.isBuffer(b) && !b.length) return | ||
@@ -19,3 +19,3 @@ buf.push(b) | ||
stream.on("entry", saveEntry) | ||
stream.on('entry', saveEntry) | ||
var entryBuffer = [] | ||
@@ -27,3 +27,3 @@ function saveEntry (e) { | ||
stream.on("proxy", proxyPause) | ||
stream.on('proxy', proxyPause) | ||
function proxyPause (p) { | ||
@@ -33,39 +33,40 @@ 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) | ||
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) | ||
})() | ||
// 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) | ||
function resume () { | ||
stream.removeListener('entry', saveEntry) | ||
stream.removeListener('data', save) | ||
stream.removeListener('end', save) | ||
stream.pipe = orig | ||
if (dest) stream.pipe(dest) | ||
stream.pipe = orig | ||
if (dest) stream.pipe(dest) | ||
buf.forEach(function (b) { | ||
if (b) stream.emit("data", b) | ||
else stream.emit("end") | ||
}) | ||
buf.forEach(function (b) { | ||
if (b) stream.emit('data', b) | ||
else stream.emit('end') | ||
}) | ||
stream.resume() | ||
stream.resume() | ||
} | ||
return dest | ||
} | ||
return dest | ||
}})(stream.pipe) | ||
})(stream.pipe) | ||
} |
@@ -7,10 +7,7 @@ // A thing that emits "entry" events with Reader objects | ||
var fs = require("graceful-fs") | ||
, fstream = require("../fstream.js") | ||
, Reader = fstream.Reader | ||
, inherits = require("inherits") | ||
, mkdir = require("mkdirp") | ||
, path = require("path") | ||
, Reader = require("./reader.js") | ||
, assert = require("assert").ok | ||
var fs = require('graceful-fs') | ||
var inherits = require('inherits') | ||
var path = require('path') | ||
var Reader = require('./reader.js') | ||
var assert = require('assert').ok | ||
@@ -20,15 +17,16 @@ inherits(DirReader, Reader) | ||
function DirReader (props) { | ||
var me = this | ||
if (!(me instanceof DirReader)) throw new Error( | ||
"DirReader must be called as constructor.") | ||
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) | ||
if (props.type !== 'Directory' || !props.Directory) { | ||
throw new Error('Non-directory type ' + props.type) | ||
} | ||
me.entries = null | ||
me._index = -1 | ||
me._paused = false | ||
me._length = -1 | ||
self.entries = null | ||
self._index = -1 | ||
self._paused = false | ||
self._length = -1 | ||
@@ -43,24 +41,24 @@ if (props.sort) { | ||
DirReader.prototype._getEntries = function () { | ||
var me = this | ||
var self = this | ||
// race condition. might pause() before calling _getEntries, | ||
// and then resume, and try to get them a second time. | ||
if (me._gotEntries) return | ||
me._gotEntries = true | ||
if (self._gotEntries) return | ||
self._gotEntries = true | ||
fs.readdir(me._path, function (er, entries) { | ||
if (er) return me.error(er) | ||
fs.readdir(self._path, function (er, entries) { | ||
if (er) return self.error(er) | ||
me.entries = entries | ||
self.entries = entries | ||
me.emit("entries", entries) | ||
if (me._paused) me.once("resume", processEntries) | ||
self.emit('entries', entries) | ||
if (self._paused) self.once('resume', processEntries) | ||
else processEntries() | ||
function processEntries () { | ||
me._length = me.entries.length | ||
if (typeof me.sort === "function") { | ||
me.entries = me.entries.sort(me.sort.bind(me)) | ||
self._length = self.entries.length | ||
if (typeof self.sort === 'function') { | ||
self.entries = self.entries.sort(self.sort.bind(self)) | ||
} | ||
me._read() | ||
self._read() | ||
} | ||
@@ -72,17 +70,17 @@ }) | ||
DirReader.prototype._read = function () { | ||
var me = this | ||
var self = this | ||
if (!me.entries) return me._getEntries() | ||
if (!self.entries) return self._getEntries() | ||
if (me._paused || me._currentEntry || me._aborted) { | ||
// console.error("DR paused=%j, current=%j, aborted=%j", me._paused, !!me._currentEntry, me._aborted) | ||
if (self._paused || self._currentEntry || self._aborted) { | ||
// console.error('DR paused=%j, current=%j, aborted=%j', self._paused, !!self._currentEntry, self._aborted) | ||
return | ||
} | ||
me._index ++ | ||
if (me._index >= me.entries.length) { | ||
if (!me._ended) { | ||
me._ended = true | ||
me.emit("end") | ||
me.emit("close") | ||
self._index++ | ||
if (self._index >= self.entries.length) { | ||
if (!self._ended) { | ||
self._ended = true | ||
self.emit('end') | ||
self.emit('close') | ||
} | ||
@@ -95,12 +93,12 @@ return | ||
// save creating a proxy, by stat'ing the thing now. | ||
var p = path.resolve(me._path, me.entries[me._index]) | ||
assert(p !== me._path) | ||
assert(me.entries[me._index]) | ||
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. | ||
me._currentEntry = p | ||
fs[ me.props.follow ? "stat" : "lstat" ](p, function (er, stat) { | ||
if (er) return me.error(er) | ||
self._currentEntry = p | ||
fs[ self.props.follow ? 'stat' : 'lstat' ](p, function (er, stat) { | ||
if (er) return self.error(er) | ||
var who = me._proxy || me | ||
var who = self._proxy || self | ||
@@ -110,3 +108,3 @@ stat.path = p | ||
stat.dirname = path.dirname(p) | ||
var childProps = me.getChildProps.call(who, stat) | ||
var childProps = self.getChildProps.call(who, stat) | ||
childProps.path = p | ||
@@ -120,3 +118,3 @@ childProps.basename = path.basename(p) | ||
me._currentEntry = entry | ||
self._currentEntry = entry | ||
@@ -127,31 +125,32 @@ // "entry" events are for direct entries in a specific dir. | ||
entry.on("pause", function (who) { | ||
if (!me._paused && !entry._disowned) { | ||
me.pause(who) | ||
entry.on('pause', function (who) { | ||
if (!self._paused && !entry._disowned) { | ||
self.pause(who) | ||
} | ||
}) | ||
entry.on("resume", function (who) { | ||
if (me._paused && !entry._disowned) { | ||
me.resume(who) | ||
entry.on('resume', function (who) { | ||
if (self._paused && !entry._disowned) { | ||
self.resume(who) | ||
} | ||
}) | ||
entry.on("stat", function (props) { | ||
me.emit("_entryStat", entry, props) | ||
entry.on('stat', function (props) { | ||
self.emit('_entryStat', entry, props) | ||
if (entry._aborted) return | ||
if (entry._paused) entry.once("resume", function () { | ||
me.emit("entryStat", entry, props) | ||
}) | ||
else me.emit("entryStat", entry, props) | ||
if (entry._paused) { | ||
entry.once('resume', function () { | ||
self.emit('entryStat', entry, props) | ||
}) | ||
} else self.emit('entryStat', entry, props) | ||
}) | ||
entry.on("ready", function EMITCHILD () { | ||
entry.on('ready', function EMITCHILD () { | ||
// console.error("DR emit child", entry._path) | ||
if (me._paused) { | ||
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(me) | ||
return me.once("resume", EMITCHILD) | ||
entry.pause(self) | ||
return self.once('resume', EMITCHILD) | ||
} | ||
@@ -163,6 +162,6 @@ | ||
// the "socket" events. | ||
if (entry.type === "Socket") { | ||
me.emit("socket", entry) | ||
if (entry.type === 'Socket') { | ||
self.emit('socket', entry) | ||
} else { | ||
me.emitEntry(entry) | ||
self.emitEntry(entry) | ||
} | ||
@@ -172,12 +171,12 @@ }) | ||
var ended = false | ||
entry.on("close", onend) | ||
entry.on("disown", onend) | ||
entry.on('close', onend) | ||
entry.on('disown', onend) | ||
function onend () { | ||
if (ended) return | ||
ended = true | ||
me.emit("childEnd", entry) | ||
me.emit("entryEnd", entry) | ||
me._currentEntry = null | ||
if (!me._paused) { | ||
me._read() | ||
self.emit('childEnd', entry) | ||
self.emit('entryEnd', entry) | ||
self._currentEntry = null | ||
if (!self._paused) { | ||
self._read() | ||
} | ||
@@ -188,9 +187,9 @@ } | ||
// Long filenames should not break stuff. | ||
entry.on("error", function (er) { | ||
entry.on('error', function (er) { | ||
if (entry._swallowErrors) { | ||
me.warn(er) | ||
entry.emit("end") | ||
entry.emit("close") | ||
self.warn(er) | ||
entry.emit('end') | ||
entry.emit('close') | ||
} else { | ||
me.emit("error", er) | ||
self.emit('error', er) | ||
} | ||
@@ -200,8 +199,9 @@ }) | ||
// proxy up some events. | ||
; [ "child" | ||
, "childEnd" | ||
, "warn" | ||
].forEach(function (ev) { | ||
entry.on(ev, me.emit.bind(me, ev)) | ||
}) | ||
;[ | ||
'child', | ||
'childEnd', | ||
'warn' | ||
].forEach(function (ev) { | ||
entry.on(ev, self.emit.bind(self, ev)) | ||
}) | ||
}) | ||
@@ -211,3 +211,3 @@ } | ||
DirReader.prototype.disown = function (entry) { | ||
entry.emit("beforeDisown") | ||
entry.emit('beforeDisown') | ||
entry._disowned = true | ||
@@ -218,48 +218,49 @@ entry.parent = entry.root = null | ||
} | ||
entry.emit("disown") | ||
entry.emit('disown') | ||
} | ||
DirReader.prototype.getChildProps = function (stat) { | ||
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.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 me = this | ||
if (me._paused) return | ||
who = who || me | ||
me._paused = true | ||
if (me._currentEntry && me._currentEntry.pause) { | ||
me._currentEntry.pause(who) | ||
var self = this | ||
if (self._paused) return | ||
who = who || self | ||
self._paused = true | ||
if (self._currentEntry && self._currentEntry.pause) { | ||
self._currentEntry.pause(who) | ||
} | ||
me.emit("pause", who) | ||
self.emit('pause', who) | ||
} | ||
DirReader.prototype.resume = function (who) { | ||
var me = this | ||
if (!me._paused) return | ||
who = who || me | ||
var self = this | ||
if (!self._paused) return | ||
who = who || self | ||
me._paused = false | ||
// console.error("DR Emit Resume", me._path) | ||
me.emit("resume", who) | ||
if (me._paused) { | ||
// console.error("DR Re-paused", me._path) | ||
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 (me._currentEntry) { | ||
if (me._currentEntry.resume) me._currentEntry.resume(who) | ||
} else me._read() | ||
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) | ||
this.emit('entry', entry) | ||
this.emit('child', entry) | ||
} |
@@ -9,9 +9,7 @@ // It is expected that, when .add() returns false, the consumer | ||
var fs = require("graceful-fs") | ||
, fstream = require("../fstream.js") | ||
, Writer = require("./writer.js") | ||
, inherits = require("inherits") | ||
, mkdir = require("mkdirp") | ||
, path = require("path") | ||
, collect = require("./collect.js") | ||
var Writer = require('./writer.js') | ||
var inherits = require('inherits') | ||
var mkdir = require('mkdirp') | ||
var path = require('path') | ||
var collect = require('./collect.js') | ||
@@ -21,10 +19,11 @@ inherits(DirWriter, Writer) | ||
function DirWriter (props) { | ||
var me = this | ||
if (!(me instanceof DirWriter)) me.error( | ||
"DirWriter must be called as constructor.", null, true) | ||
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) { | ||
me.error("Non-directory type "+ props.type + " " + | ||
JSON.stringify(props), null, true) | ||
if (props.type !== 'Directory' || !props.Directory) { | ||
self.error('Non-directory type ' + props.type + ' ' + | ||
JSON.stringify(props), null, true) | ||
} | ||
@@ -36,9 +35,9 @@ | ||
DirWriter.prototype._create = function () { | ||
var me = this | ||
mkdir(me._path, Writer.dirmode, function (er) { | ||
if (er) return me.error(er) | ||
var self = this | ||
mkdir(self._path, Writer.dirmode, function (er) { | ||
if (er) return self.error(er) | ||
// ready to start getting entries! | ||
me.ready = true | ||
me.emit("ready") | ||
me._process() | ||
self.ready = true | ||
self.emit('ready') | ||
self._process() | ||
}) | ||
@@ -61,8 +60,8 @@ } | ||
DirWriter.prototype.add = function (entry) { | ||
var me = this | ||
var self = this | ||
// console.error("\tadd", entry._path, "->", me._path) | ||
// console.error('\tadd', entry._path, '->', self._path) | ||
collect(entry) | ||
if (!me.ready || me._currentEntry) { | ||
me._buffer.push(entry) | ||
if (!self.ready || self._currentEntry) { | ||
self._buffer.push(entry) | ||
return false | ||
@@ -72,31 +71,31 @@ } | ||
// create a new writer, and pipe the incoming entry into it. | ||
if (me._ended) { | ||
return me.error("add after end") | ||
if (self._ended) { | ||
return self.error('add after end') | ||
} | ||
me._buffer.push(entry) | ||
me._process() | ||
self._buffer.push(entry) | ||
self._process() | ||
return 0 === this._buffer.length | ||
return this._buffer.length === 0 | ||
} | ||
DirWriter.prototype._process = function () { | ||
var me = this | ||
var self = this | ||
// console.error("DW Process p=%j", me._processing, me.basename) | ||
// console.error('DW Process p=%j', self._processing, self.basename) | ||
if (me._processing) return | ||
if (self._processing) return | ||
var entry = me._buffer.shift() | ||
var entry = self._buffer.shift() | ||
if (!entry) { | ||
// console.error("DW Drain") | ||
me.emit("drain") | ||
if (me._ended) me._finish() | ||
self.emit('drain') | ||
if (self._ended) self._finish() | ||
return | ||
} | ||
me._processing = true | ||
self._processing = true | ||
// console.error("DW Entry", entry._path) | ||
me.emit("entry", entry) | ||
self.emit('entry', entry) | ||
@@ -107,12 +106,14 @@ // ok, add this entry | ||
var p = entry | ||
var pp | ||
do { | ||
var pp = p._path || p.path | ||
if (pp === me.root._path || pp === me._path || | ||
(pp && pp.indexOf(me._path) === 0)) { | ||
// console.error("DW Exit (recursive)", entry.basename, me._path) | ||
me._processing = false | ||
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 me._process() | ||
return self._process() | ||
} | ||
} while (p = p.parent) | ||
p = p.parent | ||
} while (p) | ||
@@ -122,16 +123,18 @@ // console.error("DW not recursive") | ||
// chop off the entry's root dir, replace with ours | ||
var props = { parent: me | ||
, root: me.root || me | ||
, type: entry.type | ||
, depth: me.depth + 1 } | ||
var props = { | ||
parent: self, | ||
root: self.root || self, | ||
type: entry.type, | ||
depth: self.depth + 1 | ||
} | ||
var p = entry._path || entry.path || entry.props.path | ||
pp = entry._path || entry.path || entry.props.path | ||
if (entry.parent) { | ||
p = p.substr(entry.parent._path.length + 1) | ||
pp = pp.substr(entry.parent._path.length + 1) | ||
} | ||
// get rid of any ../../ shenanigans | ||
props.path = path.join(me.path, path.join("/", p)) | ||
props.path = path.join(self.path, path.join('/', pp)) | ||
// if i have a filter, the child should inherit it. | ||
props.filter = me.filter | ||
props.filter = self.filter | ||
@@ -146,4 +149,4 @@ // all the rest of the stuff, copy over from the source. | ||
// not sure at this point what kind of writer this is. | ||
var child = me._currentChild = new Writer(props) | ||
child.on("ready", function () { | ||
var child = self._currentChild = new Writer(props) | ||
child.on('ready', function () { | ||
// console.error("DW Child Ready", child.type, child._path) | ||
@@ -157,9 +160,9 @@ // console.error(" resuming", entry._path) | ||
// Long filenames should not break stuff. | ||
child.on("error", function (er) { | ||
child.on('error', function (er) { | ||
if (child._swallowErrors) { | ||
me.warn(er) | ||
child.emit("end") | ||
child.emit("close") | ||
self.warn(er) | ||
child.emit('end') | ||
child.emit('close') | ||
} else { | ||
me.emit("error", er) | ||
self.emit('error', er) | ||
} | ||
@@ -170,3 +173,3 @@ }) | ||
// until any "end" listeners have had their chance to do stuff. | ||
child.on("close", onend) | ||
child.on('close', onend) | ||
var ended = false | ||
@@ -177,6 +180,6 @@ function onend () { | ||
// console.error("* DW Child end", child.basename) | ||
me._currentChild = null | ||
me._processing = false | ||
me._process() | ||
self._currentChild = null | ||
self._processing = false | ||
self._process() | ||
} | ||
} |
@@ -5,10 +5,7 @@ // Basically just a wrapper around an fs.ReadStream | ||
var fs = require("graceful-fs") | ||
, fstream = require("../fstream.js") | ||
, Reader = fstream.Reader | ||
, inherits = require("inherits") | ||
, mkdir = require("mkdirp") | ||
, Reader = require("./reader.js") | ||
, EOF = {EOF: true} | ||
, CLOSE = {CLOSE: true} | ||
var fs = require('graceful-fs') | ||
var inherits = require('inherits') | ||
var Reader = require('./reader.js') | ||
var EOF = {EOF: true} | ||
var CLOSE = {CLOSE: true} | ||
@@ -19,5 +16,6 @@ inherits(FileReader, Reader) | ||
// console.error(" FR create", props.path, props.size, new Error().stack) | ||
var me = this | ||
if (!(me instanceof FileReader)) throw new Error( | ||
"FileReader must be called as constructor.") | ||
var self = this | ||
if (!(self instanceof FileReader)) { | ||
throw new Error('FileReader must be called as constructor.') | ||
} | ||
@@ -27,104 +25,105 @@ // should already be established as a File type | ||
// with a HardLinkReader class. | ||
if (!((props.type === "Link" && props.Link) || | ||
(props.type === "File" && props.File))) { | ||
throw new Error("Non-file type "+ props.type) | ||
if (!((props.type === 'Link' && props.Link) || | ||
(props.type === 'File' && props.File))) { | ||
throw new Error('Non-file type ' + props.type) | ||
} | ||
me._buffer = [] | ||
me._bytesEmitted = 0 | ||
Reader.call(me, props) | ||
self._buffer = [] | ||
self._bytesEmitted = 0 | ||
Reader.call(self, props) | ||
} | ||
FileReader.prototype._getStream = function () { | ||
var me = this | ||
, stream = me._stream = fs.createReadStream(me._path, me.props) | ||
var self = this | ||
var stream = self._stream = fs.createReadStream(self._path, self.props) | ||
if (me.props.blksize) { | ||
stream.bufferSize = me.props.blksize | ||
if (self.props.blksize) { | ||
stream.bufferSize = self.props.blksize | ||
} | ||
stream.on("open", me.emit.bind(me, "open")) | ||
stream.on('open', self.emit.bind(self, 'open')) | ||
stream.on("data", function (c) { | ||
// console.error("\t\t%d %s", c.length, me.basename) | ||
me._bytesEmitted += c.length | ||
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 (me._paused || me._buffer.length) { | ||
me._buffer.push(c) | ||
me._read() | ||
} else me.emit("data", c) | ||
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 (me._paused || me._buffer.length) { | ||
// console.error("FR Buffering End", me._path) | ||
me._buffer.push(EOF) | ||
me._read() | ||
stream.on('end', function () { | ||
if (self._paused || self._buffer.length) { | ||
// console.error('FR Buffering End', self._path) | ||
self._buffer.push(EOF) | ||
self._read() | ||
} else { | ||
me.emit("end") | ||
self.emit('end') | ||
} | ||
if (me._bytesEmitted !== me.props.size) { | ||
me.error("Didn't get expected byte count\n"+ | ||
"expect: "+me.props.size + "\n" + | ||
"actual: "+me._bytesEmitted) | ||
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 (me._paused || me._buffer.length) { | ||
// console.error("FR Buffering Close", me._path) | ||
me._buffer.push(CLOSE) | ||
me._read() | ||
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", me._path) | ||
me.emit("close") | ||
// console.error('FR close 1', self._path) | ||
self.emit('close') | ||
} | ||
}) | ||
stream.on("error", function (e) { | ||
me.emit("error", e); | ||
}); | ||
stream.on('error', function (e) { | ||
self.emit('error', e) | ||
}) | ||
me._read() | ||
self._read() | ||
} | ||
FileReader.prototype._read = function () { | ||
var me = this | ||
// console.error("FR _read", me._path) | ||
if (me._paused) { | ||
// console.error("FR _read paused", me._path) | ||
var self = this | ||
// console.error('FR _read', self._path) | ||
if (self._paused) { | ||
// console.error('FR _read paused', self._path) | ||
return | ||
} | ||
if (!me._stream) { | ||
// console.error("FR _getStream calling", me._path) | ||
return me._getStream() | ||
if (!self._stream) { | ||
// console.error('FR _getStream calling', self._path) | ||
return self._getStream() | ||
} | ||
// clear out the buffer, if there is one. | ||
if (me._buffer.length) { | ||
// console.error("FR _read has buffer", me._buffer.length, me._path) | ||
var buf = me._buffer | ||
for (var i = 0, l = buf.length; i < l; i ++) { | ||
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", me._path) | ||
me.emit("end") | ||
// console.error('FR Read emitting buffered end', self._path) | ||
self.emit('end') | ||
} else if (c === CLOSE) { | ||
// console.error("FR Read emitting buffered close", me._path) | ||
me.emit("close") | ||
// console.error('FR Read emitting buffered close', self._path) | ||
self.emit('close') | ||
} else { | ||
// console.error("FR Read emitting buffered data", me._path) | ||
me.emit("data", c) | ||
// console.error('FR Read emitting buffered data', self._path) | ||
self.emit('data', c) | ||
} | ||
if (me._paused) { | ||
// console.error("FR Read Re-pausing at "+i, me._path) | ||
me._buffer = buf.slice(i) | ||
if (self._paused) { | ||
// console.error('FR Read Re-pausing at '+i, self._path) | ||
self._buffer = buf.slice(i) | ||
return | ||
} | ||
} | ||
me._buffer.length = 0 | ||
self._buffer.length = 0 | ||
} | ||
@@ -136,20 +135,20 @@ // console.error("FR _read done") | ||
FileReader.prototype.pause = function (who) { | ||
var me = this | ||
// console.error("FR Pause", me._path) | ||
if (me._paused) return | ||
who = who || me | ||
me._paused = true | ||
if (me._stream) me._stream.pause() | ||
me.emit("pause", 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 me = this | ||
// console.error("FR Resume", me._path) | ||
if (!me._paused) return | ||
who = who || me | ||
me.emit("resume", who) | ||
me._paused = false | ||
if (me._stream) me._stream.resume() | ||
me._read() | ||
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() | ||
} |
module.exports = FileWriter | ||
var fs = require("graceful-fs") | ||
, mkdir = require("mkdirp") | ||
, Writer = require("./writer.js") | ||
, inherits = require("inherits") | ||
, EOF = {} | ||
var fs = require('graceful-fs') | ||
var Writer = require('./writer.js') | ||
var inherits = require('inherits') | ||
var EOF = {} | ||
@@ -12,13 +11,14 @@ inherits(FileWriter, Writer) | ||
function FileWriter (props) { | ||
var me = this | ||
if (!(me instanceof FileWriter)) throw new Error( | ||
"FileWriter must be called as constructor.") | ||
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) | ||
if (props.type !== 'File' || !props.File) { | ||
throw new Error('Non-file type ' + props.type) | ||
} | ||
me._buffer = [] | ||
me._bytesWritten = 0 | ||
self._buffer = [] | ||
self._bytesWritten = 0 | ||
@@ -29,29 +29,31 @@ Writer.call(this, props) | ||
FileWriter.prototype._create = function () { | ||
var me = this | ||
if (me._stream) return | ||
var self = this | ||
if (self._stream) return | ||
var so = {} | ||
if (me.props.flags) so.flags = me.props.flags | ||
if (self.props.flags) so.flags = self.props.flags | ||
so.mode = Writer.filemode | ||
if (me._old && me._old.blksize) so.bufferSize = me._old.blksize | ||
if (self._old && self._old.blksize) so.bufferSize = self._old.blksize | ||
me._stream = fs.createWriteStream(me._path, so) | ||
self._stream = fs.createWriteStream(self._path, so) | ||
me._stream.on("open", function (fd) { | ||
// console.error("FW open", me._buffer, me._path) | ||
me.ready = true | ||
me._buffer.forEach(function (c) { | ||
if (c === EOF) me._stream.end() | ||
else me._stream.write(c) | ||
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) | ||
}) | ||
me.emit("ready") | ||
self.emit('ready') | ||
// give this a kick just in case it needs it. | ||
me.emit("drain") | ||
self.emit('drain') | ||
}) | ||
me._stream.on("drain", function () { me.emit("drain") }) | ||
self._stream.on('error', function () { self.emit('error') }) | ||
me._stream.on("close", function () { | ||
// console.error("\n\nFW Stream Close", me._path, me.size) | ||
me._finish() | ||
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() | ||
}) | ||
@@ -61,22 +63,23 @@ } | ||
FileWriter.prototype.write = function (c) { | ||
var me = this | ||
var self = this | ||
me._bytesWritten += c.length | ||
self._bytesWritten += c.length | ||
if (!me.ready) { | ||
if (!Buffer.isBuffer(c) && typeof c !== 'string') | ||
if (!self.ready) { | ||
if (!Buffer.isBuffer(c) && typeof c !== 'string') { | ||
throw new Error('invalid write data') | ||
me._buffer.push(c) | ||
} | ||
self._buffer.push(c) | ||
return false | ||
} | ||
var ret = me._stream.write(c) | ||
// console.error("\t-- fw wrote, _stream says", ret, me._stream._queue.length) | ||
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 && me._stream._queue) { | ||
return me._stream._queue.length <= 2; | ||
if (ret === false && self._stream._queue) { | ||
return self._stream._queue.length <= 2 | ||
} else { | ||
return ret; | ||
return ret | ||
} | ||
@@ -86,23 +89,23 @@ } | ||
FileWriter.prototype.end = function (c) { | ||
var me = this | ||
var self = this | ||
if (c) me.write(c) | ||
if (c) self.write(c) | ||
if (!me.ready) { | ||
me._buffer.push(EOF) | ||
if (!self.ready) { | ||
self._buffer.push(EOF) | ||
return false | ||
} | ||
return me._stream.end() | ||
return self._stream.end() | ||
} | ||
FileWriter.prototype._finish = function () { | ||
var me = this | ||
if (typeof me.size === "number" && me._bytesWritten != me.size) { | ||
me.error( | ||
"Did not get expected byte count.\n" + | ||
"expect: " + me.size + "\n" + | ||
"actual: " + me._bytesWritten) | ||
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(me) | ||
Writer.prototype._finish.call(self) | ||
} |
module.exports = getType | ||
function getType (st) { | ||
var types = | ||
[ "Directory" | ||
, "File" | ||
, "SymbolicLink" | ||
, "Link" // special for hardlinks from tarballs | ||
, "BlockDevice" | ||
, "CharacterDevice" | ||
, "FIFO" | ||
, "Socket" ] | ||
, type | ||
var types = [ | ||
'Directory', | ||
'File', | ||
'SymbolicLink', | ||
'Link', // special for hardlinks from tarballs | ||
'BlockDevice', | ||
'CharacterDevice', | ||
'FIFO', | ||
'Socket' | ||
] | ||
var type | ||
if (st.type && -1 !== types.indexOf(st.type)) { | ||
if (st.type && types.indexOf(st.type) !== -1) { | ||
st[st.type] = true | ||
@@ -20,6 +21,6 @@ return st.type | ||
for (var i = 0, l = types.length; i < l; i ++) { | ||
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) | ||
var is = st[type] || st['is' + type] | ||
if (typeof is === 'function') is = is.call(st) | ||
if (is) { | ||
@@ -26,0 +27,0 @@ st[type] = true |
@@ -9,7 +9,5 @@ // Basically just a wrapper around an fs.readlink | ||
var fs = require("graceful-fs") | ||
, fstream = require("../fstream.js") | ||
, inherits = require("inherits") | ||
, mkdir = require("mkdirp") | ||
, Reader = require("./reader.js") | ||
var fs = require('graceful-fs') | ||
var inherits = require('inherits') | ||
var Reader = require('./reader.js') | ||
@@ -19,12 +17,13 @@ inherits(LinkReader, Reader) | ||
function LinkReader (props) { | ||
var me = this | ||
if (!(me instanceof LinkReader)) throw new Error( | ||
"LinkReader must be called as constructor.") | ||
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) | ||
if (!((props.type === 'Link' && props.Link) || | ||
(props.type === 'SymbolicLink' && props.SymbolicLink))) { | ||
throw new Error('Non-link type ' + props.type) | ||
} | ||
Reader.call(me, props) | ||
Reader.call(self, props) | ||
} | ||
@@ -37,8 +36,8 @@ | ||
LinkReader.prototype._stat = function (currentStat) { | ||
var me = this | ||
fs.readlink(me._path, function (er, linkpath) { | ||
if (er) return me.error(er) | ||
me.linkpath = me.props.linkpath = linkpath | ||
me.emit("linkpath", linkpath) | ||
Reader.prototype._stat.call(me, 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) | ||
}) | ||
@@ -48,11 +47,11 @@ } | ||
LinkReader.prototype._read = function () { | ||
var me = this | ||
if (me._paused) return | ||
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 (!me._ended) { | ||
me.emit("end") | ||
me.emit("close") | ||
me._ended = true | ||
if (!self._ended) { | ||
self.emit('end') | ||
self.emit('close') | ||
self._ended = true | ||
} | ||
} |
@@ -1,9 +0,8 @@ | ||
module.exports = LinkWriter | ||
var fs = require("graceful-fs") | ||
, Writer = require("./writer.js") | ||
, inherits = require("inherits") | ||
, path = require("path") | ||
, rimraf = require("rimraf") | ||
var fs = require('graceful-fs') | ||
var Writer = require('./writer.js') | ||
var inherits = require('inherits') | ||
var path = require('path') | ||
var rimraf = require('rimraf') | ||
@@ -13,15 +12,16 @@ inherits(LinkWriter, Writer) | ||
function LinkWriter (props) { | ||
var me = this | ||
if (!(me instanceof LinkWriter)) throw new Error( | ||
"LinkWriter must be called as constructor.") | ||
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.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 === '') props.linkpath = '.' | ||
if (!props.linkpath) { | ||
me.error("Need linkpath property to create " + props.type) | ||
self.error('Need linkpath property to create ' + props.type) | ||
} | ||
@@ -34,6 +34,6 @@ | ||
// console.error(" LW _create") | ||
var me = this | ||
, hard = me.type === "Link" || process.platform === "win32" | ||
, link = hard ? "link" : "symlink" | ||
, lp = hard ? path.resolve(me.dirname, me.linkpath) : me.linkpath | ||
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 | ||
@@ -43,20 +43,20 @@ // can only change the link path by clobbering | ||
// there's no good way to read them if we don't already know. | ||
if (hard) return clobber(me, lp, link) | ||
if (hard) return clobber(self, lp, link) | ||
fs.readlink(me._path, function (er, p) { | ||
fs.readlink(self._path, function (er, p) { | ||
// only skip creation if it's exactly the same link | ||
if (p && p === lp) return finish(me) | ||
clobber(me, lp, link) | ||
if (p && p === lp) return finish(self) | ||
clobber(self, lp, link) | ||
}) | ||
} | ||
function clobber (me, lp, link) { | ||
rimraf(me._path, function (er) { | ||
if (er) return me.error(er) | ||
create(me, lp, link) | ||
function clobber (self, lp, link) { | ||
rimraf(self._path, function (er) { | ||
if (er) return self.error(er) | ||
create(self, lp, link) | ||
}) | ||
} | ||
function create (me, lp, link) { | ||
fs[link](lp, me._path, function (er) { | ||
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 | ||
@@ -71,20 +71,20 @@ // directory, it's very possible that the thing we're linking to | ||
if (er) { | ||
if ((er.code === "ENOENT" || | ||
er.code === "EACCES" || | ||
er.code === "EPERM" ) && process.platform === "win32") { | ||
me.ready = true | ||
me.emit("ready") | ||
me.emit("end") | ||
me.emit("close") | ||
me.end = me._finish = function () {} | ||
} else return me.error(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(me) | ||
finish(self) | ||
}) | ||
} | ||
function finish (me) { | ||
me.ready = true | ||
me.emit("ready") | ||
if (me._ended && !me._finished) me._finish() | ||
function finish (self) { | ||
self.ready = true | ||
self.emit('ready') | ||
if (self._ended && !self._finished) self._finish() | ||
} | ||
@@ -91,0 +91,0 @@ |
@@ -6,6 +6,6 @@ // A reader for when we don't yet know what kind of thing | ||
var Reader = require("./reader.js") | ||
, getType = require("./get-type.js") | ||
, inherits = require("inherits") | ||
, fs = require("graceful-fs") | ||
var Reader = require('./reader.js') | ||
var getType = require('./get-type.js') | ||
var inherits = require('inherits') | ||
var fs = require('graceful-fs') | ||
@@ -15,18 +15,19 @@ inherits(ProxyReader, Reader) | ||
function ProxyReader (props) { | ||
var me = this | ||
if (!(me instanceof ProxyReader)) throw new Error( | ||
"ProxyReader must be called as constructor.") | ||
var self = this | ||
if (!(self instanceof ProxyReader)) { | ||
throw new Error('ProxyReader must be called as constructor.') | ||
} | ||
me.props = props | ||
me._buffer = [] | ||
me.ready = false | ||
self.props = props | ||
self._buffer = [] | ||
self.ready = false | ||
Reader.call(me, props) | ||
Reader.call(self, props) | ||
} | ||
ProxyReader.prototype._stat = function () { | ||
var me = this | ||
, props = me.props | ||
// stat the thing to see what the proxy should be. | ||
, stat = props.follow ? "stat" : "lstat" | ||
var self = this | ||
var props = self.props | ||
// stat the thing to see what the proxy should be. | ||
var stat = props.follow ? 'stat' : 'lstat' | ||
@@ -36,3 +37,3 @@ fs[stat](props.path, function (er, current) { | ||
if (er || !current) { | ||
type = "File" | ||
type = 'File' | ||
} else { | ||
@@ -43,6 +44,6 @@ type = getType(current) | ||
props[type] = true | ||
props.type = me.type = type | ||
props.type = self.type = type | ||
me._old = current | ||
me._addProxy(Reader(props, current)) | ||
self._old = current | ||
self._addProxy(Reader(props, current)) | ||
}) | ||
@@ -52,36 +53,37 @@ } | ||
ProxyReader.prototype._addProxy = function (proxy) { | ||
var me = this | ||
if (me._proxyTarget) { | ||
return me.error("proxy already set") | ||
var self = this | ||
if (self._proxyTarget) { | ||
return self.error('proxy already set') | ||
} | ||
me._proxyTarget = proxy | ||
proxy._proxy = me | ||
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, me.path) | ||
proxy.on(ev, me.emit.bind(me, ev)) | ||
}) | ||
;[ | ||
'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)) | ||
}) | ||
me.emit("proxy", proxy) | ||
self.emit('proxy', proxy) | ||
proxy.on("ready", function () { | ||
// console.error("~~ proxy is ready!", me.path) | ||
me.ready = true | ||
me.emit("ready") | ||
proxy.on('ready', function () { | ||
// console.error("~~ proxy is ready!", self.path) | ||
self.ready = true | ||
self.emit('ready') | ||
}) | ||
var calls = me._buffer | ||
me._buffer.length = 0 | ||
var calls = self._buffer | ||
self._buffer.length = 0 | ||
calls.forEach(function (c) { | ||
@@ -88,0 +90,0 @@ proxy[c[0]].apply(proxy, c[1]) |
@@ -10,7 +10,7 @@ // A writer for when we don't know what kind of thing | ||
var Writer = require("./writer.js") | ||
, getType = require("./get-type.js") | ||
, inherits = require("inherits") | ||
, collect = require("./collect.js") | ||
, fs = require("fs") | ||
var Writer = require('./writer.js') | ||
var getType = require('./get-type.js') | ||
var inherits = require('inherits') | ||
var collect = require('./collect.js') | ||
var fs = require('fs') | ||
@@ -20,17 +20,18 @@ inherits(ProxyWriter, Writer) | ||
function ProxyWriter (props) { | ||
var me = this | ||
if (!(me instanceof ProxyWriter)) throw new Error( | ||
"ProxyWriter must be called as constructor.") | ||
var self = this | ||
if (!(self instanceof ProxyWriter)) { | ||
throw new Error('ProxyWriter must be called as constructor.') | ||
} | ||
me.props = props | ||
me._needDrain = false | ||
self.props = props | ||
self._needDrain = false | ||
Writer.call(me, props) | ||
Writer.call(self, props) | ||
} | ||
ProxyWriter.prototype._stat = function () { | ||
var me = this | ||
, props = me.props | ||
// stat the thing to see what the proxy should be. | ||
, stat = props.follow ? "stat" : "lstat" | ||
var self = this | ||
var props = self.props | ||
// stat the thing to see what the proxy should be. | ||
var stat = props.follow ? 'stat' : 'lstat' | ||
@@ -40,3 +41,3 @@ fs[stat](props.path, function (er, current) { | ||
if (er || !current) { | ||
type = "File" | ||
type = 'File' | ||
} else { | ||
@@ -47,6 +48,6 @@ type = getType(current) | ||
props[type] = true | ||
props.type = me.type = type | ||
props.type = self.type = type | ||
me._old = current | ||
me._addProxy(Writer(props, current)) | ||
self._old = current | ||
self._addProxy(Writer(props, current)) | ||
}) | ||
@@ -57,21 +58,22 @@ } | ||
// console.error("~~ set proxy", this.path) | ||
var me = this | ||
if (me._proxy) { | ||
return me.error("proxy already set") | ||
var self = this | ||
if (self._proxy) { | ||
return self.error('proxy already set') | ||
} | ||
me._proxy = proxy | ||
; [ "ready" | ||
, "error" | ||
, "close" | ||
, "pipe" | ||
, "drain" | ||
, "warn" | ||
].forEach(function (ev) { | ||
proxy.on(ev, me.emit.bind(me, ev)) | ||
}) | ||
self._proxy = proxy | ||
;[ | ||
'ready', | ||
'error', | ||
'close', | ||
'pipe', | ||
'drain', | ||
'warn' | ||
].forEach(function (ev) { | ||
proxy.on(ev, self.emit.bind(self, ev)) | ||
}) | ||
me.emit("proxy", proxy) | ||
self.emit('proxy', proxy) | ||
var calls = me._buffer | ||
var calls = self._buffer | ||
calls.forEach(function (c) { | ||
@@ -81,4 +83,4 @@ // console.error("~~ ~~ proxy buffered call", c[0], c[1]) | ||
}) | ||
me._buffer.length = 0 | ||
if (me._needsDrain) me.emit("drain") | ||
self._buffer.length = 0 | ||
if (self._needsDrain) self.emit('drain') | ||
} | ||
@@ -91,3 +93,3 @@ | ||
if (!this._proxy) { | ||
this._buffer.push(["add", [entry]]) | ||
this._buffer.push(['add', [entry]]) | ||
this._needDrain = true | ||
@@ -100,5 +102,5 @@ return false | ||
ProxyWriter.prototype.write = function (c) { | ||
// console.error("~~ proxy write") | ||
// console.error('~~ proxy write') | ||
if (!this._proxy) { | ||
this._buffer.push(["write", [c]]) | ||
this._buffer.push(['write', [c]]) | ||
this._needDrain = true | ||
@@ -111,5 +113,5 @@ return false | ||
ProxyWriter.prototype.end = function (c) { | ||
// console.error("~~ proxy end") | ||
// console.error('~~ proxy end') | ||
if (!this._proxy) { | ||
this._buffer.push(["end", [c]]) | ||
this._buffer.push(['end', [c]]) | ||
return false | ||
@@ -116,0 +118,0 @@ } |
@@ -1,11 +0,10 @@ | ||
module.exports = Reader | ||
var fs = require("graceful-fs") | ||
, Stream = require("stream").Stream | ||
, inherits = require("inherits") | ||
, path = require("path") | ||
, getType = require("./get-type.js") | ||
, hardLinks = Reader.hardLinks = {} | ||
, Abstract = require("./abstract.js") | ||
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') | ||
@@ -15,13 +14,9 @@ // Must do this *before* loading the child classes | ||
var DirReader = require("./dir-reader.js") | ||
, FileReader = require("./file-reader.js") | ||
, LinkReader = require("./link-reader.js") | ||
, SocketReader = require("./socket-reader.js") | ||
, ProxyReader = require("./proxy-reader.js") | ||
var LinkReader = require('./link-reader.js') | ||
function Reader (props, currentStat) { | ||
var me = this | ||
if (!(me instanceof Reader)) return new Reader(props, currentStat) | ||
var self = this | ||
if (!(self instanceof Reader)) return new Reader(props, currentStat) | ||
if (typeof props === "string") { | ||
if (typeof props === 'string') { | ||
props = { path: props } | ||
@@ -31,3 +26,3 @@ } | ||
if (!props.path) { | ||
me.error("Must provide a path", null, true) | ||
self.error('Must provide a path', null, true) | ||
} | ||
@@ -41,7 +36,6 @@ | ||
var type | ||
, ClassType | ||
var ClassType | ||
if (props.type && typeof props.type === "function") { | ||
if (props.type && typeof props.type === 'function') { | ||
type = props.type | ||
@@ -61,7 +55,7 @@ ClassType = type | ||
switch (type) { | ||
case "Directory": | ||
ClassType = DirReader | ||
case 'Directory': | ||
ClassType = require('./dir-reader.js') | ||
break | ||
case "Link": | ||
case 'Link': | ||
// XXX hard links are just files. | ||
@@ -75,48 +69,49 @@ // However, it would be good to keep track of files' dev+inode | ||
case "File": | ||
ClassType = FileReader | ||
case 'File': | ||
ClassType = require('./file-reader.js') | ||
break | ||
case "SymbolicLink": | ||
case 'SymbolicLink': | ||
ClassType = LinkReader | ||
break | ||
case "Socket": | ||
ClassType = SocketReader | ||
case 'Socket': | ||
ClassType = require('./socket-reader.js') | ||
break | ||
case null: | ||
ClassType = ProxyReader | ||
default: | ||
ClassType = require('./proxy-reader.js') | ||
break | ||
} | ||
if (!(me instanceof ClassType)) { | ||
if (!(self instanceof ClassType)) { | ||
return new ClassType(props) | ||
} | ||
Abstract.call(me) | ||
Abstract.call(self) | ||
me.readable = true | ||
me.writable = false | ||
self.readable = true | ||
self.writable = false | ||
me.type = type | ||
me.props = props | ||
me.depth = props.depth = props.depth || 0 | ||
me.parent = props.parent || null | ||
me.root = props.root || (props.parent && props.parent.root) || me | ||
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 | ||
me._path = me.path = path.resolve(props.path) | ||
if (process.platform === "win32") { | ||
me.path = me._path = me.path.replace(/\?/g, "_") | ||
if (me._path.length >= 260) { | ||
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. | ||
me._swallowErrors = true | ||
//if (me._path.indexOf(" ") === -1) { | ||
me._path = "\\\\?\\" + me.path.replace(/\//g, "\\") | ||
//} | ||
self._swallowErrors = true | ||
// if (self._path.indexOf(" ") === -1) { | ||
self._path = '\\\\?\\' + self.path.replace(/\//g, '\\') | ||
// } | ||
} | ||
} | ||
me.basename = props.basename = path.basename(me.path) | ||
me.dirname = props.dirname = path.dirname(me.path) | ||
self.basename = props.basename = path.basename(self.path) | ||
self.dirname = props.dirname = path.dirname(self.path) | ||
@@ -127,11 +122,11 @@ // these have served their purpose, and are now just noisy clutter | ||
// console.error("\n\n\n%s setting size to", props.path, props.size) | ||
me.size = props.size | ||
me.filter = typeof props.filter === "function" ? props.filter : null | ||
if (props.sort === "alpha") props.sort = alphasort | ||
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 me._read() | ||
// this will stat the thing, and then call self._read() | ||
// to start reading whatever it is. | ||
// console.error("calling stat", props.path, currentStat) | ||
me._stat(currentStat) | ||
self._stat(currentStat) | ||
} | ||
@@ -148,13 +143,12 @@ | ||
Reader.prototype._stat = function (currentStat) { | ||
var me = this | ||
, props = me.props | ||
, stat = props.follow ? "stat" : "lstat" | ||
// console.error("Reader._stat", me._path, 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](me._path, statCb) | ||
else fs[stat](self._path, statCb) | ||
function statCb (er, props_) { | ||
// console.error("Reader._stat, statCb", me._path, props_, props_.nlink) | ||
if (er) return me.error(er) | ||
// console.error("Reader._stat, statCb", self._path, props_, props_.nlink) | ||
if (er) return self.error(er) | ||
@@ -166,29 +160,30 @@ Object.keys(props_).forEach(function (k) { | ||
// if it's not the expected size, then abort here. | ||
if (undefined !== me.size && props.size !== me.size) { | ||
return me.error("incorrect size") | ||
if (undefined !== self.size && props.size !== self.size) { | ||
return self.error('incorrect size') | ||
} | ||
me.size = props.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", me._path, k) | ||
if (hardLinks[k] === me._path || !hardLinks[k]) hardLinks[k] = me._path | ||
else { | ||
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 = me.type = me.props.type = "Link" | ||
me.Link = me.props.Link = true | ||
me.linkpath = me.props.linkpath = hardLinks[k] | ||
// console.error("Hardlink detected, switching mode", me._path, me.linkpath) | ||
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. | ||
me._stat = me._read = LinkReader.prototype._read | ||
self._stat = self._read = LinkReader.prototype._read | ||
} | ||
} | ||
if (me.type && me.type !== type) { | ||
me.error("Unexpected type: " + type) | ||
if (self.type && self.type !== type) { | ||
self.error('Unexpected type: ' + type) | ||
} | ||
@@ -198,10 +193,10 @@ | ||
// still have to emit end so that dir-walking can move on. | ||
if (me.filter) { | ||
var who = me._proxy || me | ||
if (self.filter) { | ||
var who = self._proxy || self | ||
// special handling for ProxyReaders | ||
if (!me.filter.call(who, who, props)) { | ||
if (!me._disowned) { | ||
me.abort() | ||
me.emit("end") | ||
me.emit("close") | ||
if (!self.filter.call(who, who, props)) { | ||
if (!self._disowned) { | ||
self.abort() | ||
self.emit('end') | ||
self.emit('close') | ||
} | ||
@@ -213,21 +208,21 @@ return | ||
// last chance to abort or disown before the flow starts! | ||
var events = ["_stat", "stat", "ready"] | ||
var events = ['_stat', 'stat', 'ready'] | ||
var e = 0 | ||
;(function go () { | ||
if (me._aborted) { | ||
me.emit("end") | ||
me.emit("close") | ||
if (self._aborted) { | ||
self.emit('end') | ||
self.emit('close') | ||
return | ||
} | ||
if (me._paused && me.type !== "Directory") { | ||
me.once("resume", go) | ||
if (self._paused && self.type !== 'Directory') { | ||
self.once('resume', go) | ||
return | ||
} | ||
var ev = events[e ++] | ||
var ev = events[e++] | ||
if (!ev) { | ||
return me._read() | ||
return self._read() | ||
} | ||
me.emit(ev, props) | ||
self.emit(ev, props) | ||
go() | ||
@@ -238,10 +233,10 @@ })() | ||
Reader.prototype.pipe = function (dest, opts) { | ||
var me = this | ||
if (typeof dest.add === "function") { | ||
Reader.prototype.pipe = function (dest) { | ||
var self = this | ||
if (typeof dest.add === 'function') { | ||
// piping to a multi-compatible, and we've got directory entries. | ||
me.on("entry", function (entry) { | ||
self.on('entry', function (entry) { | ||
var ret = dest.add(entry) | ||
if (false === ret) { | ||
me.pause() | ||
if (ret === false) { | ||
self.pause() | ||
} | ||
@@ -258,3 +253,3 @@ }) | ||
who = who || this | ||
this.emit("pause", who) | ||
this.emit('pause', who) | ||
if (this._stream) this._stream.pause(who) | ||
@@ -266,3 +261,3 @@ } | ||
who = who || this | ||
this.emit("resume", who) | ||
this.emit('resume', who) | ||
if (this._stream) this._stream.resume(who) | ||
@@ -273,4 +268,3 @@ this._read() | ||
Reader.prototype._read = function () { | ||
this.error("Cannot read unknown type: "+this.type) | ||
this.error('Cannot read unknown type: ' + this.type) | ||
} | ||
@@ -8,7 +8,4 @@ // Just get the stats, and then don't do anything. | ||
var fs = require("graceful-fs") | ||
, fstream = require("../fstream.js") | ||
, inherits = require("inherits") | ||
, mkdir = require("mkdirp") | ||
, Reader = require("./reader.js") | ||
var inherits = require('inherits') | ||
var Reader = require('./reader.js') | ||
@@ -18,23 +15,24 @@ inherits(SocketReader, Reader) | ||
function SocketReader (props) { | ||
var me = this | ||
if (!(me instanceof SocketReader)) throw new Error( | ||
"SocketReader must be called as constructor.") | ||
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) | ||
if (!(props.type === 'Socket' && props.Socket)) { | ||
throw new Error('Non-socket type ' + props.type) | ||
} | ||
Reader.call(me, props) | ||
Reader.call(self, props) | ||
} | ||
SocketReader.prototype._read = function () { | ||
var me = this | ||
if (me._paused) return | ||
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 (!me._ended) { | ||
me.emit("end") | ||
me.emit("close") | ||
me._ended = true | ||
if (!self._ended) { | ||
self.emit('end') | ||
self.emit('close') | ||
self._ended = true | ||
} | ||
} |
@@ -1,12 +0,11 @@ | ||
module.exports = Writer | ||
var fs = require("graceful-fs") | ||
, inherits = require("inherits") | ||
, rimraf = require("rimraf") | ||
, mkdir = require("mkdirp") | ||
, path = require("path") | ||
, umask = process.platform === "win32" ? 0 : process.umask() | ||
, getType = require("./get-type.js") | ||
, Abstract = require("./abstract.js") | ||
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') | ||
@@ -16,9 +15,9 @@ // Must do this *before* loading the child classes | ||
Writer.dirmode = 0777 & (~umask) | ||
Writer.filemode = 0666 & (~umask) | ||
Writer.dirmode = parseInt('0777', 8) & (~umask) | ||
Writer.filemode = parseInt('0666', 8) & (~umask) | ||
var DirWriter = require("./dir-writer.js") | ||
, LinkWriter = require("./link-writer.js") | ||
, FileWriter = require("./file-writer.js") | ||
, ProxyWriter = require("./proxy-writer.js") | ||
var DirWriter = require('./dir-writer.js') | ||
var LinkWriter = require('./link-writer.js') | ||
var FileWriter = require('./file-writer.js') | ||
var ProxyWriter = require('./proxy-writer.js') | ||
@@ -29,9 +28,9 @@ // props is the desired state. current is optionally the current stat, | ||
function Writer (props, current) { | ||
var me = this | ||
var self = this | ||
if (typeof props === "string") { | ||
if (typeof props === 'string') { | ||
props = { path: props } | ||
} | ||
if (!props.path) me.error("Must provide a path", null, true) | ||
if (!props.path) self.error('Must provide a path', null, true) | ||
@@ -41,16 +40,17 @@ // polymorphism. | ||
var type = getType(props) | ||
, ClassType = Writer | ||
var ClassType = Writer | ||
switch (type) { | ||
case "Directory": | ||
case 'Directory': | ||
ClassType = DirWriter | ||
break | ||
case "File": | ||
case 'File': | ||
ClassType = FileWriter | ||
break | ||
case "Link": | ||
case "SymbolicLink": | ||
case 'Link': | ||
case 'SymbolicLink': | ||
ClassType = LinkWriter | ||
break | ||
case null: | ||
default: | ||
// Don't know yet what type to create, so we wrap in a proxy. | ||
@@ -61,28 +61,28 @@ ClassType = ProxyWriter | ||
if (!(me instanceof ClassType)) return new ClassType(props) | ||
if (!(self instanceof ClassType)) return new ClassType(props) | ||
// now get down to business. | ||
Abstract.call(me) | ||
Abstract.call(self) | ||
// props is what we want to set. | ||
// set some convenience properties as well. | ||
me.type = props.type | ||
me.props = props | ||
me.depth = props.depth || 0 | ||
me.clobber = false === props.clobber ? props.clobber : true | ||
me.parent = props.parent || null | ||
me.root = props.root || (props.parent && props.parent.root) || me | ||
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 | ||
me._path = me.path = path.resolve(props.path) | ||
if (process.platform === "win32") { | ||
me.path = me._path = me.path.replace(/\?/g, "_") | ||
if (me._path.length >= 260) { | ||
me._swallowErrors = true | ||
me._path = "\\\\?\\" + me.path.replace(/\//g, "\\") | ||
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, '\\') | ||
} | ||
} | ||
me.basename = path.basename(props.path) | ||
me.dirname = path.dirname(props.path) | ||
me.linkpath = props.linkpath || null | ||
self.basename = path.basename(props.path) | ||
self.dirname = path.dirname(props.path) | ||
self.linkpath = props.linkpath || null | ||
@@ -92,21 +92,21 @@ props.parent = props.root = null | ||
// console.error("\n\n\n%s setting size to", props.path, props.size) | ||
me.size = props.size | ||
self.size = props.size | ||
if (typeof props.mode === "string") { | ||
if (typeof props.mode === 'string') { | ||
props.mode = parseInt(props.mode, 8) | ||
} | ||
me.readable = false | ||
me.writable = true | ||
self.readable = false | ||
self.writable = true | ||
// buffer until ready, or while handling another entry | ||
me._buffer = [] | ||
me.ready = false | ||
self._buffer = [] | ||
self.ready = false | ||
me.filter = typeof props.filter === "function" ? props.filter: null | ||
self.filter = typeof props.filter === 'function' ? props.filter : null | ||
// start the ball rolling. | ||
// this checks what's there already, and then calls | ||
// me._create() to call the impl-specific creation stuff. | ||
me._stat(current) | ||
// self._create() to call the impl-specific creation stuff. | ||
self._stat(current) | ||
} | ||
@@ -117,9 +117,9 @@ | ||
Writer.prototype._create = function () { | ||
var me = this | ||
fs[me.props.follow ? "stat" : "lstat"](me._path, function (er, current) { | ||
var self = this | ||
fs[self.props.follow ? 'stat' : 'lstat'](self._path, function (er) { | ||
if (er) { | ||
return me.warn("Cannot create " + me._path + "\n" + | ||
"Unsupported type: "+me.type, "ENOTSUP") | ||
return self.warn('Cannot create ' + self._path + '\n' + | ||
'Unsupported type: ' + self.type, 'ENOTSUP') | ||
} | ||
me._finish() | ||
self._finish() | ||
}) | ||
@@ -129,15 +129,15 @@ } | ||
Writer.prototype._stat = function (current) { | ||
var me = this | ||
, props = me.props | ||
, stat = props.follow ? "stat" : "lstat" | ||
, who = me._proxy || me | ||
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](me._path, statCb) | ||
else fs[stat](self._path, statCb) | ||
function statCb (er, current) { | ||
if (me.filter && !me.filter.call(who, who, current)) { | ||
me._aborted = true | ||
me.emit("end") | ||
me.emit("close") | ||
if (self.filter && !self.filter.call(who, who, current)) { | ||
self._aborted = true | ||
self.emit('end') | ||
self.emit('close') | ||
return | ||
@@ -149,6 +149,6 @@ } | ||
if (er || !current) { | ||
return create(me) | ||
return create(self) | ||
} | ||
me._old = current | ||
self._old = current | ||
var currentType = getType(current) | ||
@@ -158,7 +158,7 @@ | ||
// if it's not a type change, then let the impl take care of it. | ||
if (currentType !== me.type) { | ||
return rimraf(me._path, function (er) { | ||
if (er) return me.error(er) | ||
me._old = null | ||
create(me) | ||
if (currentType !== self.type) { | ||
return rimraf(self._path, function (er) { | ||
if (er) return self.error(er) | ||
self._old = null | ||
create(self) | ||
}) | ||
@@ -169,31 +169,31 @@ } | ||
// this creates a fs.WriteStream, or mkdir's, or whatever | ||
create(me) | ||
create(self) | ||
} | ||
} | ||
function create (me) { | ||
// console.error("W create", me._path, Writer.dirmode) | ||
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(me._path), Writer.dirmode, function (er, made) { | ||
// console.error("W created", path.dirname(me._path), er) | ||
if (er) return me.error(er) | ||
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 | ||
me._madeDir = made | ||
return me._create() | ||
self._madeDir = made | ||
return self._create() | ||
}) | ||
} | ||
function endChmod (me, want, current, path, cb) { | ||
var wantMode = want.mode | ||
, chmod = want.follow || me.type !== "SymbolicLink" | ||
? "chmod" : "lchmod" | ||
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() | ||
if (typeof wantMode !== 'number') return cb() | ||
var curMode = current.mode & 0777 | ||
wantMode = wantMode & 0777 | ||
var curMode = current.mode & parseInt('0777', 8) | ||
wantMode = wantMode & parseInt('0777', 8) | ||
if (wantMode === curMode) return cb() | ||
@@ -204,9 +204,8 @@ | ||
function endChown (me, want, current, path, 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.platform === 'win32') return cb() | ||
if (!process.getuid || process.getuid() !== 0) return cb() | ||
if (typeof want.uid !== "number" && | ||
typeof want.gid !== "number" ) return cb() | ||
if (typeof want.uid !== 'number' && | ||
typeof want.gid !== 'number') return cb() | ||
@@ -216,8 +215,8 @@ if (current.uid === want.uid && | ||
var chown = (me.props.follow || me.type !== "SymbolicLink") | ||
? "chown" : "lchown" | ||
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 | ||
if (typeof want.uid !== 'number') want.uid = current.uid | ||
if (typeof want.gid !== 'number') want.gid = current.gid | ||
@@ -227,10 +226,10 @@ fs[chown](path, want.uid, want.gid, cb) | ||
function endUtimes (me, want, current, path, cb) { | ||
if (!fs.utimes || process.platform === "win32") return cb() | ||
function endUtimes (self, want, current, path, cb) { | ||
if (!fs.utimes || process.platform === 'win32') return cb() | ||
var utimes = (want.follow || me.type !== "SymbolicLink") | ||
? "utimes" : "lutimes" | ||
var utimes = (want.follow || self.type !== 'SymbolicLink') | ||
? 'utimes' : 'lutimes' | ||
if (utimes === "lutimes" && !fs[utimes]) { | ||
utimes = "utimes" | ||
if (utimes === 'lutimes' && !fs[utimes]) { | ||
utimes = 'utimes' | ||
} | ||
@@ -241,5 +240,5 @@ | ||
var curA = current.atime | ||
, curM = current.mtime | ||
, meA = want.atime | ||
, meM = want.mtime | ||
var curM = current.mtime | ||
var meA = want.atime | ||
var meM = want.mtime | ||
@@ -258,11 +257,10 @@ if (meA === undefined) meA = curA | ||
// XXX This function is beastly. Break it up! | ||
Writer.prototype._finish = function () { | ||
var me = this | ||
var self = this | ||
if (me._finishing) return | ||
me._finishing = true | ||
if (self._finishing) return | ||
self._finishing = true | ||
// console.error(" W Finish", me._path, me.size) | ||
// console.error(" W Finish", self._path, self.size) | ||
@@ -276,14 +274,14 @@ // set up all the things. | ||
if (me._old) { | ||
if (self._old) { | ||
// the times will almost *certainly* have changed. | ||
// adds the utimes syscall, but remove another stat. | ||
me._old.atime = new Date(0) | ||
me._old.mtime = new Date(0) | ||
// console.error(" W Finish Stale Stat", me._path, me.size) | ||
setProps(me._old) | ||
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 = me.props.follow ? "stat" : "lstat" | ||
// console.error(" W Finish Stating", me._path, me.size) | ||
fs[stat](me._path, function (er, current) { | ||
// console.error(" W Finish Stated", me._path, me.size, current) | ||
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) { | ||
@@ -294,14 +292,14 @@ // if we're in the process of writing out a | ||
// so swallow ENOENT errors here and just soldier on. | ||
if (er.code === "ENOENT" && | ||
(me.type === "Link" || me.type === "SymbolicLink") && | ||
process.platform === "win32") { | ||
me.ready = true | ||
me.emit("ready") | ||
me.emit("end") | ||
me.emit("close") | ||
me.end = me._finish = function () {} | ||
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 me.error(er) | ||
} else return self.error(er) | ||
} | ||
setProps(me._old = current) | ||
setProps(self._old = current) | ||
}) | ||
@@ -314,5 +312,5 @@ } | ||
todo += 3 | ||
endChmod(me, me.props, current, me._path, next("chmod")) | ||
endChown(me, me.props, current, me._path, next("chown")) | ||
endUtimes(me, me.props, current, me._path, next("utimes")) | ||
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')) | ||
} | ||
@@ -326,3 +324,3 @@ | ||
er.fstream_finish_call = what | ||
return me.error(errState = er) | ||
return self.error(errState = er) | ||
} | ||
@@ -335,13 +333,13 @@ if (--todo > 0) return | ||
// that were created previously. delay end/close until then. | ||
if (!me._madeDir) return end() | ||
else endMadeDir(me, me._path, end) | ||
if (!self._madeDir) return end() | ||
else endMadeDir(self, self._path, end) | ||
function end (er) { | ||
if (er) { | ||
er.fstream_finish_call = "setupMadeDir" | ||
return me.error(er) | ||
er.fstream_finish_call = 'setupMadeDir' | ||
return self.error(er) | ||
} | ||
// all the props have been set, so we're completely done. | ||
me.emit("end") | ||
me.emit("close") | ||
self.emit('end') | ||
self.emit('close') | ||
} | ||
@@ -352,9 +350,9 @@ } | ||
function endMadeDir (me, p, cb) { | ||
var made = me._madeDir | ||
// everything *between* made and path.dirname(me._path) | ||
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_(me, d, function (er) { | ||
endMadeDir_(self, d, function (er) { | ||
if (er) return cb(er) | ||
@@ -364,14 +362,14 @@ if (d === made) { | ||
} | ||
endMadeDir(me, d, cb) | ||
endMadeDir(self, d, cb) | ||
}) | ||
} | ||
function endMadeDir_ (me, p, cb) { | ||
function endMadeDir_ (self, p, cb) { | ||
var dirProps = {} | ||
Object.keys(me.props).forEach(function (k) { | ||
dirProps[k] = me.props[k] | ||
Object.keys(self.props).forEach(function (k) { | ||
dirProps[k] = self.props[k] | ||
// only make non-readable dirs if explicitly requested. | ||
if (k === "mode" && me.type !== "Directory") { | ||
dirProps[k] = dirProps[k] | 0111 | ||
if (k === 'mode' && self.type !== 'Directory') { | ||
dirProps[k] = dirProps[k] | parseInt('0111', 8) | ||
} | ||
@@ -381,8 +379,8 @@ }) | ||
var todo = 3 | ||
, errState = null | ||
var errState = null | ||
fs.stat(p, function (er, current) { | ||
if (er) return cb(errState = er) | ||
endChmod(me, dirProps, current, p, next) | ||
endChown(me, dirProps, current, p, next) | ||
endUtimes(me, dirProps, current, p, next) | ||
endChmod(self, dirProps, current, p, next) | ||
endChown(self, dirProps, current, p, next) | ||
endUtimes(self, dirProps, current, p, next) | ||
}) | ||
@@ -393,3 +391,3 @@ | ||
if (er) return cb(errState = er) | ||
if (-- todo === 0) return cb() | ||
if (--todo === 0) return cb() | ||
} | ||
@@ -403,3 +401,3 @@ } | ||
Writer.prototype.add = function () { | ||
this.error("Cannot add to non-Directory type") | ||
this.error("Can't add to non-Directory type") | ||
} | ||
@@ -415,4 +413,4 @@ | ||
function isDate(d) { | ||
return typeof d === 'object' && objectToString(d) === '[object Date]'; | ||
function isDate (d) { | ||
return typeof d === 'object' && objectToString(d) === '[object Date]' | ||
} |
@@ -5,3 +5,3 @@ { | ||
"description": "Advanced file system stream things", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"repository": { | ||
@@ -22,8 +22,9 @@ "type": "git", | ||
"devDependencies": { | ||
"tap": "" | ||
"tap": "", | ||
"standard": "^2.3.2" | ||
}, | ||
"scripts": { | ||
"test": "tap examples/*.js" | ||
"test": "standard && tap examples/*.js" | ||
}, | ||
"license": "BSD" | ||
"license": "ISC" | ||
} |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
SPDX disjunction
LicenseSPDX disjunction for an artifact's license information
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
SPDX disjunction
LicenseSPDX disjunction for an artifact's license information
Found 1 instance in 1 package
Non-permissive License
License(Experimental) A license not known to be considered permissive was found
Found 1 instance in 1 package
1
1915
63714
2
1