fstream
Advanced tools
Comparing version 0.1.1 to 0.1.2
@@ -20,8 +20,8 @@ var fstream = require("../fstream.js") | ||
r.on("entry", appears) | ||
//r.on("ready", function () { | ||
// appears(r) | ||
//}) | ||
r.on("ready", function () { | ||
console.error("ready to begin!", r.path) | ||
}) | ||
function appears (entry) { | ||
console.error(indent + "a %s appears!", entry.type, entry.basename) | ||
console.error(indent + "a %s appears!", entry.type, entry.basename, typeof entry.basename, entry) | ||
if (foggy) { | ||
@@ -107,2 +107,4 @@ console.error("FOGGY!") | ||
console.error("A WINNAR IS YOU!") | ||
console.log("ok 1 A WINNAR IS YOU") | ||
ended = true | ||
@@ -112,5 +114,5 @@ }) | ||
process.on("exit", function () { | ||
console.error("ended? "+ended) | ||
console.log((ended ? "" : "not ") + "ok 2 ended") | ||
}) | ||
r.pipe(w) | ||
var fstream = require("../fstream.js") | ||
var tap = require("tap") | ||
var path = require("path") | ||
var children = -1 | ||
var r = fstream.Reader({ path: path.dirname(__dirname) | ||
, filter: function () { | ||
return !this.basename.match(/^\./) | ||
} | ||
}) | ||
var gotReady = false | ||
var ended = false | ||
console.error(r instanceof fstream.Reader) | ||
console.error(r instanceof require("stream").Stream) | ||
console.error(r instanceof require("events").EventEmitter) | ||
console.error(r.on) | ||
tap.test("reader test", function (t) { | ||
r.on("stat", function () { | ||
console.error("a %s !!!\t", r.type, r.path) | ||
}) | ||
var r = fstream.Reader({ path: path.dirname(__dirname) | ||
, filter: function () { | ||
// return this.parent === r | ||
return this.parent === r || this === r | ||
} | ||
}) | ||
r.on("entries", function (entries) { | ||
console.error("\t" + entries.join("\n\t")) | ||
}) | ||
r.on("ready", function () { | ||
gotReady = true | ||
children = r.props.nlink | ||
t.equal(r.type, "Directory", "should be a directory") | ||
}) | ||
r.on("entry", function (entry) { | ||
console.error("a %s !!!\t", entry.type, entry.path) | ||
}) | ||
r.on("entry", function (entry) { | ||
children -- | ||
t.equal(entry.dirname, r.path, "basename is parent dir") | ||
}) | ||
r.on("end", function () { | ||
console.error("IT'S OVER!!") | ||
r.on("error", function (er) { | ||
t.fail(er) | ||
t.end() | ||
process.exit(1) | ||
}) | ||
r.on("end", function () { | ||
// 2 because "." and ".." aren't traversed | ||
t.equal(children, 2, "should have seen all children") | ||
ended = true | ||
}) | ||
var closed = false | ||
r.on("close", function () { | ||
t.ok(ended, "saw end before close") | ||
t.notOk(closed, "close should only happen once") | ||
closed = true | ||
t.end() | ||
}) | ||
}) |
var fstream = require("../fstream.js") | ||
, closed = false | ||
@@ -9,2 +10,16 @@ fstream | ||
}) | ||
.on("close", function () { | ||
closed = true | ||
var fs = require("fs") | ||
var s = fs.lstatSync("path/to/symlink") | ||
var isSym = s.isSymbolicLink() | ||
console.log((isSym?"":"not ") +"ok 1 should be symlink") | ||
var t = fs.readlinkSync("path/to/symlink") | ||
var isTarget = t === "./file" | ||
console.log((isTarget?"":"not ") +"ok 2 should link to ./file") | ||
}) | ||
.end() | ||
process.on("exit", function () { | ||
console.log((closed?"":"not ")+"ok 3 should be closed") | ||
}) |
@@ -72,2 +72,5 @@ // the parent class for all fstreams. | ||
} | ||
if (me.linkpath) { | ||
er.fstream_linkpath = er.fstream_linkpath || me.linkpath | ||
} | ||
er.fstream_class = er.fstream_class || me.constructor.name | ||
@@ -74,0 +77,0 @@ er.fstream_stack = er.fstream_stack || |
@@ -61,5 +61,10 @@ // A thing that emits "entry" events with Reader objects | ||
if (me._index >= me._length) { | ||
// console.error(" DR End/close", me._path) | ||
me.emit("end") | ||
me.emit("close") | ||
if (!me._ended) { | ||
me._ended = true | ||
// console.error(" DR End/close", me._path, new Error("trace").stack) | ||
me.emit("end") | ||
// console.error(" DR emitted end, emitting close", me._path) | ||
me.emit("close") | ||
// console.error(" DR After End/close", me._path) | ||
} | ||
return | ||
@@ -79,4 +84,4 @@ } | ||
, depth: me.depth + 1 | ||
, root: me.root || me | ||
, parent: me | ||
, root: me.root || me._proxy || me | ||
, parent: me._proxy || me | ||
, follow: me.follow | ||
@@ -134,4 +139,6 @@ , filter: me.filter | ||
entry.on("error", function (er) { | ||
if (entry.path !== entry._path) { | ||
if (entry._swallowErrors) { | ||
me.warn(er) | ||
entry.emit("end") | ||
entry.emit("close") | ||
} else { | ||
@@ -138,0 +145,0 @@ me.emit("error", er) |
@@ -144,4 +144,6 @@ // It is expected that, when .add() returns false, the consumer | ||
child.on("error", function (er) { | ||
if (child.path !== child._path) { | ||
if (child._swallowErrors) { | ||
me.warn(er) | ||
child.emit("end") | ||
child.emit("close") | ||
} else { | ||
@@ -148,0 +150,0 @@ me.emit("error", er) |
@@ -32,2 +32,3 @@ | ||
LinkWriter.prototype._create = function () { | ||
// console.error(" LW _create") | ||
var me = this | ||
@@ -59,3 +60,15 @@ , hard = me.type === "Link" || process.platform === "win32" | ||
fs[link](lp, me._path, function (er) { | ||
if (er) return me.error(er) | ||
// if this is a hard link, and we're in the process of writing out a | ||
// directory, it's very possible that the thing we're linking to | ||
// doesn't exist yet (especially if it was intended as a symlink), | ||
// so swallow ENOENT errors here and just soldier in. | ||
if (er) { | ||
if (er.code === "ENOENT" && 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) | ||
} | ||
finish(me) | ||
@@ -68,6 +81,12 @@ }) | ||
me.emit("ready") | ||
if (me._ended && !me._finished) me._finish() | ||
} | ||
LinkWriter.prototype.end = function () { | ||
this._finish() | ||
// console.error("LW finish in end") | ||
this._ended = true | ||
if (this.ready) { | ||
this._finished = true | ||
this._finish() | ||
} | ||
} |
@@ -49,9 +49,10 @@ // A reader for when we don't yet know what kind of thing | ||
var me = this | ||
if (me._proxy) { | ||
if (me._proxyTarget) { | ||
return me.error("proxy already set") | ||
} | ||
me._proxy = proxy | ||
me._proxyTarget = proxy | ||
proxy._proxy = me | ||
; [ "error" | ||
, "close" | ||
, "data" | ||
@@ -64,2 +65,3 @@ , "end" | ||
].forEach(function (ev) { | ||
// console.error("~~ proxy event", ev, me.path) | ||
proxy.on(ev, me.emit.bind(me, ev)) | ||
@@ -84,7 +86,7 @@ }) | ||
ProxyReader.prototype.pause = function () { | ||
return this._proxy ? this._proxy.pause() : false | ||
return this._proxyTarget ? this._proxyTarget.pause() : false | ||
} | ||
ProxyReader.prototype.resume = function (c) { | ||
return this._proxy ? this._proxy.resume() : false | ||
ProxyReader.prototype.resume = function () { | ||
return this._proxyTarget ? this._proxyTarget.resume() : false | ||
} |
@@ -99,7 +99,13 @@ | ||
me._path = me.path = path.resolve(props.path) | ||
if (process.platform === "win32" && me._path.length > 200) { | ||
// how DOES one create files on the moon? | ||
me._path = "\\\\?\\" + me.path.replace(/\//g, "\\") | ||
if (process.platform === "win32") { | ||
me.path = me._path = me.path.replace(/\?/g, "_") | ||
if (me._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, "\\") | ||
//} | ||
} | ||
} | ||
me.basename = props.basename = path.basename(me.path) | ||
@@ -180,3 +186,4 @@ me.dirname = props.dirname = path.dirname(me.path) | ||
if (me.filter) { | ||
if (!me.filter()) { | ||
// special handling for ProxyReaders | ||
if (!me.filter.call(me._proxy || me)) { | ||
me._aborted = true | ||
@@ -183,0 +190,0 @@ me.emit("end") |
@@ -74,7 +74,11 @@ | ||
me._path = me.path = path.resolve(props.path) | ||
if (process.platform === "win32" && me._path.length > 200) { | ||
// how DOES one create files on the moon? | ||
me._path = "\\\\?\\" + me.path.replace(/\//g, "\\") | ||
if (process.platform === "win32") { | ||
me.path = me._path = me.path.replace(/\?/g, "_") | ||
if (me._path.length >= 260) { | ||
me._swallowErrors = true | ||
//if (me._path.indexOf(" ") === -1) { | ||
me._path = "\\\\?\\" + me.path.replace(/\//g, "\\") | ||
//} | ||
} | ||
} | ||
me.basename = path.basename(props.path) | ||
@@ -149,3 +153,3 @@ me.dirname = path.dirname(props.path) | ||
// this creates a fs.WriteStream, or mkdir's, or whatever | ||
me._create() | ||
create(me) | ||
} | ||
@@ -155,5 +159,8 @@ } | ||
function create (me) { | ||
// console.error("W create", me._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) { | ||
// console.error("W created", path.dirname(me._path), er) | ||
if (er) return me.error(er) | ||
@@ -188,3 +195,18 @@ me._create() | ||
// console.error(" W Finish Stated", me._path, me.size, current) | ||
if (er) return me.error(er) | ||
if (er) { | ||
// if we're in the process of writing out a | ||
// directory, it's very possible that the thing we're linking to | ||
// doesn't exist yet (especially if it was intended as a symlink), | ||
// so swallow ENOENT errors here and just soldier in. | ||
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 () {} | ||
return | ||
} else return me.error(er) | ||
} | ||
setProps(me._old = current) | ||
@@ -234,13 +256,3 @@ }) | ||
if (utimes === "lutimes" && !fs[utimes]) { | ||
if (!fs.futimes) fs.ltimes = function (a, b, c, cb) { return cb() } | ||
else fs.lutimes = function (path, atime, mtime, cb) { | ||
var c = require("constants") | ||
fs.open(path, c.O_SYMLINK, function (er, fd) { | ||
if (er) return cb(er) | ||
fs.futimes(fd, atime, mtime, function (er) { | ||
if (er) return cb(er) | ||
fs.close(fd, cb) | ||
}) | ||
}) | ||
} | ||
utimes = "utimes" | ||
} | ||
@@ -247,0 +259,0 @@ |
@@ -5,3 +5,3 @@ { | ||
"description": "Advanced file system stream things", | ||
"version": "0.0.1", | ||
"version": "0.1.1", | ||
"repository": { | ||
@@ -13,3 +13,3 @@ "type": "git", | ||
"engines": { | ||
"node": "0.5 || 0.6" | ||
"node": "0.5 || 0.6 || 0.7" | ||
}, | ||
@@ -19,6 +19,11 @@ "dependencies": { | ||
"mkdirp": "~0.1.0", | ||
"graceful-fs": "~1.0.1", | ||
"graceful-fs": "1.1", | ||
"inherits": "~1.0.0" | ||
}, | ||
"devDependencies": {} | ||
"devDependencies": { | ||
"tap": "0.1" | ||
}, | ||
"scripts": { | ||
"test": "cd examples; tap *.js" | ||
} | ||
} |
@@ -20,8 +20,8 @@ var fstream = require("../fstream.js") | ||
r.on("entry", appears) | ||
//r.on("ready", function () { | ||
// appears(r) | ||
//}) | ||
r.on("ready", function () { | ||
console.error("ready to begin!", r.path) | ||
}) | ||
function appears (entry) { | ||
console.error(indent + "a %s appears!", entry.type, entry.basename) | ||
console.error(indent + "a %s appears!", entry.type, entry.basename, typeof entry.basename, entry) | ||
if (foggy) { | ||
@@ -107,2 +107,4 @@ console.error("FOGGY!") | ||
console.error("A WINNAR IS YOU!") | ||
console.log("ok 1 A WINNAR IS YOU") | ||
ended = true | ||
@@ -112,5 +114,5 @@ }) | ||
process.on("exit", function () { | ||
console.error("ended? "+ended) | ||
console.log((ended ? "" : "not ") + "ok 2 ended") | ||
}) | ||
r.pipe(w) | ||
var fstream = require("../fstream.js") | ||
var tap = require("tap") | ||
var path = require("path") | ||
var children = -1 | ||
var r = fstream.Reader({ path: path.dirname(__dirname) | ||
, filter: function () { | ||
return !this.basename.match(/^\./) | ||
} | ||
}) | ||
var gotReady = false | ||
var ended = false | ||
console.error(r instanceof fstream.Reader) | ||
console.error(r instanceof require("stream").Stream) | ||
console.error(r instanceof require("events").EventEmitter) | ||
console.error(r.on) | ||
tap.test("reader test", function (t) { | ||
r.on("stat", function () { | ||
console.error("a %s !!!\t", r.type, r.path) | ||
}) | ||
var r = fstream.Reader({ path: path.dirname(__dirname) | ||
, filter: function () { | ||
// return this.parent === r | ||
return this.parent === r || this === r | ||
} | ||
}) | ||
r.on("entries", function (entries) { | ||
console.error("\t" + entries.join("\n\t")) | ||
}) | ||
r.on("ready", function () { | ||
gotReady = true | ||
children = r.props.nlink | ||
t.equal(r.type, "Directory", "should be a directory") | ||
}) | ||
r.on("entry", function (entry) { | ||
console.error("a %s !!!\t", entry.type, entry.path) | ||
}) | ||
r.on("entry", function (entry) { | ||
children -- | ||
t.equal(entry.dirname, r.path, "basename is parent dir") | ||
}) | ||
r.on("end", function () { | ||
console.error("IT'S OVER!!") | ||
r.on("error", function (er) { | ||
t.fail(er) | ||
t.end() | ||
process.exit(1) | ||
}) | ||
r.on("end", function () { | ||
// 2 because "." and ".." aren't traversed | ||
t.equal(children, 2, "should have seen all children") | ||
ended = true | ||
}) | ||
var closed = false | ||
r.on("close", function () { | ||
t.ok(ended, "saw end before close") | ||
t.notOk(closed, "close should only happen once") | ||
closed = true | ||
t.end() | ||
}) | ||
}) |
var fstream = require("../fstream.js") | ||
, closed = false | ||
@@ -9,2 +10,16 @@ fstream | ||
}) | ||
.on("close", function () { | ||
closed = true | ||
var fs = require("fs") | ||
var s = fs.lstatSync("path/to/symlink") | ||
var isSym = s.isSymbolicLink() | ||
console.log((isSym?"":"not ") +"ok 1 should be symlink") | ||
var t = fs.readlinkSync("path/to/symlink") | ||
var isTarget = t === "./file" | ||
console.log((isTarget?"":"not ") +"ok 2 should link to ./file") | ||
}) | ||
.end() | ||
process.on("exit", function () { | ||
console.log((closed?"":"not ")+"ok 3 should be closed") | ||
}) |
@@ -61,5 +61,7 @@ // A thing that emits "entry" events with Reader objects | ||
if (me._index >= me._length) { | ||
// console.error(" DR End/close", me._path) | ||
me.emit("end") | ||
me.emit("close") | ||
if (!me._ended) { | ||
me._ended = true | ||
me.emit("end") | ||
me.emit("close") | ||
} | ||
return | ||
@@ -79,4 +81,4 @@ } | ||
, depth: me.depth + 1 | ||
, root: me.root || me | ||
, parent: me | ||
, root: me.root || me._proxy || me | ||
, parent: me._proxy || me | ||
, follow: me.follow | ||
@@ -83,0 +85,0 @@ , filter: me.filter |
@@ -32,2 +32,3 @@ | ||
LinkWriter.prototype._create = function () { | ||
// console.error(" LW _create") | ||
var me = this | ||
@@ -79,6 +80,12 @@ , hard = me.type === "Link" || process.platform === "win32" | ||
me.emit("ready") | ||
if (me._ended && !me._finished) me._finish() | ||
} | ||
LinkWriter.prototype.end = function () { | ||
this._finish() | ||
// console.error("LW finish in end") | ||
this._ended = true | ||
if (this.ready) { | ||
this._finished = true | ||
this._finish() | ||
} | ||
} |
@@ -49,9 +49,10 @@ // A reader for when we don't yet know what kind of thing | ||
var me = this | ||
if (me._proxy) { | ||
if (me._proxyTarget) { | ||
return me.error("proxy already set") | ||
} | ||
me._proxy = proxy | ||
me._proxyTarget = proxy | ||
proxy._proxy = me | ||
; [ "error" | ||
, "close" | ||
, "data" | ||
@@ -64,2 +65,3 @@ , "end" | ||
].forEach(function (ev) { | ||
// console.error("~~ proxy event", ev, me.path) | ||
proxy.on(ev, me.emit.bind(me, ev)) | ||
@@ -84,7 +86,7 @@ }) | ||
ProxyReader.prototype.pause = function () { | ||
return this._proxy ? this._proxy.pause() : false | ||
return this._proxyTarget ? this._proxyTarget.pause() : false | ||
} | ||
ProxyReader.prototype.resume = function (c) { | ||
return this._proxy ? this._proxy.resume() : false | ||
ProxyReader.prototype.resume = function () { | ||
return this._proxyTarget ? this._proxyTarget.resume() : false | ||
} |
@@ -98,4 +98,2 @@ | ||
me.basename = props.basename = path.basename(me.path) | ||
me.dirname = props.dirname = path.dirname(me.path) | ||
me._path = me.path = path.resolve(props.path) | ||
@@ -113,2 +111,4 @@ if (process.platform === "win32") { | ||
} | ||
me.basename = props.basename = path.basename(me.path) | ||
me.dirname = props.dirname = path.dirname(me.path) | ||
@@ -187,3 +187,4 @@ // these have served their purpose, and are now just noisy clutter | ||
if (me.filter) { | ||
if (!me.filter()) { | ||
// special handling for ProxyReaders | ||
if (!me.filter.call(me._proxy || me)) { | ||
me._aborted = true | ||
@@ -190,0 +191,0 @@ me.emit("end") |
@@ -73,5 +73,2 @@ | ||
me.basename = path.basename(props.path) | ||
me.dirname = path.dirname(props.path) | ||
me.linkpath = props.linkpath || null | ||
me._path = me.path = path.resolve(props.path) | ||
@@ -87,2 +84,5 @@ if (process.platform === "win32") { | ||
} | ||
me.basename = path.basename(props.path) | ||
me.dirname = path.dirname(props.path) | ||
me.linkpath = props.linkpath || null | ||
@@ -154,3 +154,3 @@ props.parent = props.root = null | ||
// this creates a fs.WriteStream, or mkdir's, or whatever | ||
me._create() | ||
create(me) | ||
} | ||
@@ -160,5 +160,8 @@ } | ||
function create (me) { | ||
// console.error("W create", me._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) { | ||
// console.error("W created", path.dirname(me._path), er) | ||
if (er) return me.error(er) | ||
@@ -165,0 +168,0 @@ me._create() |
@@ -5,3 +5,3 @@ { | ||
"description": "Advanced file system stream things", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"repository": { | ||
@@ -18,6 +18,11 @@ "type": "git", | ||
"mkdirp": "~0.1.0", | ||
"graceful-fs": "1.1", | ||
"graceful-fs": "~1.1.1", | ||
"inherits": "~1.0.0" | ||
}, | ||
"devDependencies": {} | ||
"devDependencies": { | ||
"tap": "0.1" | ||
}, | ||
"scripts": { | ||
"test": "cd examples; tap *.js" | ||
} | ||
} |
105025
42
3135
1
4
Updatedgraceful-fs@~1.1.1