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

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2012-01-13 20:33:27 +0400
committerisaacs <i@izs.me>2012-01-13 20:41:06 +0400
commitc18fe966ddbeb66c8a9b9aa8ab4899166e6986f5 (patch)
tree8650e7575caff9d05e04352b78669dd81d21230d /node_modules/fstream
parentb7ff884870958221eb52c5a600c101fab4c26781 (diff)
check in node_modules
Diffstat (limited to 'node_modules/fstream')
-rw-r--r--node_modules/fstream/.npmignore3
-rw-r--r--node_modules/fstream/.travis.yml3
-rw-r--r--node_modules/fstream/README.md76
-rw-r--r--node_modules/fstream/fstream.js31
-rw-r--r--node_modules/fstream/lib/abstract.js82
-rw-r--r--node_modules/fstream/lib/collect.js67
-rw-r--r--node_modules/fstream/lib/dir-reader.js192
-rw-r--r--node_modules/fstream/lib/dir-writer.js165
-rw-r--r--node_modules/fstream/lib/file-reader.js147
-rw-r--r--node_modules/fstream/lib/file-writer.js95
-rw-r--r--node_modules/fstream/lib/get-type.js32
-rw-r--r--node_modules/fstream/lib/link-reader.js54
-rw-r--r--node_modules/fstream/lib/link-writer.js96
-rw-r--r--node_modules/fstream/lib/proxy-reader.js89
-rw-r--r--node_modules/fstream/lib/proxy-writer.js109
-rw-r--r--node_modules/fstream/lib/reader.js240
-rw-r--r--node_modules/fstream/lib/socket-reader.js38
-rw-r--r--node_modules/fstream/lib/writer.js316
-rw-r--r--node_modules/fstream/package.json26
19 files changed, 1861 insertions, 0 deletions
diff --git a/node_modules/fstream/.npmignore b/node_modules/fstream/.npmignore
new file mode 100644
index 000000000..66880db1a
--- /dev/null
+++ b/node_modules/fstream/.npmignore
@@ -0,0 +1,3 @@
+.*.swp
+examples/deep-copy
+node_modules/
diff --git a/node_modules/fstream/.travis.yml b/node_modules/fstream/.travis.yml
new file mode 100644
index 000000000..2d26206d5
--- /dev/null
+++ b/node_modules/fstream/.travis.yml
@@ -0,0 +1,3 @@
+language: node_js
+node_js:
+ - 0.6
diff --git a/node_modules/fstream/README.md b/node_modules/fstream/README.md
new file mode 100644
index 000000000..9d8cb77e5
--- /dev/null
+++ b/node_modules/fstream/README.md
@@ -0,0 +1,76 @@
+Like FS streams, but with stat on them, and supporting directories and
+symbolic links, as well as normal files. Also, you can use this to set
+the stats on a file, even if you don't change its contents, or to create
+a symlink, etc.
+
+So, for example, you can "write" a directory, and it'll call `mkdir`. You
+can specify a uid and gid, and it'll call `chown`. You can specify a
+`mtime` and `atime`, and it'll call `utimes`. You can call it a symlink
+and provide a `linkpath` and it'll call `symlink`.
+
+Note that it won't automatically resolve symbolic links. So, if you
+call `fstream.Reader('/some/symlink')` then you'll get an object
+that stats and then ends immediately (since it has no data). To follow
+symbolic links, do this: `fstream.Reader({path:'/some/symlink', follow:
+true })`.
+
+There are various checks to make sure that the bytes emitted are the
+same as the intended size, if the size is set.
+
+## Examples
+
+```javascript
+fstream
+ .Writer({ path: "path/to/file"
+ , mode: 0755
+ , size: 6
+ })
+ .write("hello\n")
+ .end()
+```
+
+This will create the directories if they're missing, and then write
+`hello\n` into the file, chmod it to 0755, and assert that 6 bytes have
+been written when it's done.
+
+```javascript
+fstream
+ .Writer({ path: "path/to/file"
+ , mode: 0755
+ , size: 6
+ , flags: "a"
+ })
+ .write("hello\n")
+ .end()
+```
+
+You can pass flags in, if you want to append to a file.
+
+```javascript
+fstream
+ .Writer({ path: "path/to/symlink"
+ , linkpath: "./file"
+ , SymbolicLink: true
+ , mode: "0755" // octal strings supported
+ })
+ .end()
+```
+
+If isSymbolicLink is a function, it'll be called, and if it returns
+true, then it'll treat it as a symlink. If it's not a function, then
+any truish value will make a symlink, or you can set `type:
+'SymbolicLink'`, which does the same thing.
+
+Note that the linkpath is relative to the symbolic link location, not
+the parent dir or cwd.
+
+```javascript
+fstream
+ .Reader("path/to/dir")
+ .pipe(fstream.Writer("path/to/other/dir"))
+```
+
+This will do like `cp -Rp path/to/dir path/to/other/dir`. If the other
+dir exists and isn't a directory, then it'll emit an error. It'll also
+set the uid, gid, mode, etc. to be identical. In this way, it's more
+like `rsync -a` than simply a copy.
diff --git a/node_modules/fstream/fstream.js b/node_modules/fstream/fstream.js
new file mode 100644
index 000000000..c66d26f51
--- /dev/null
+++ b/node_modules/fstream/fstream.js
@@ -0,0 +1,31 @@
+exports.Abstract = require("./lib/abstract.js")
+exports.Reader = require("./lib/reader.js")
+exports.Writer = require("./lib/writer.js")
+
+exports.File =
+ { Reader: require("./lib/file-reader.js")
+ , Writer: require("./lib/file-writer.js") }
+
+exports.Dir =
+ { Reader : require("./lib/dir-reader.js")
+ , Writer : require("./lib/dir-writer.js") }
+
+exports.Link =
+ { Reader : require("./lib/link-reader.js")
+ , Writer : require("./lib/link-writer.js") }
+
+exports.Proxy =
+ { Reader : require("./lib/proxy-reader.js")
+ , Writer : require("./lib/proxy-writer.js") }
+
+exports.Reader.Dir = exports.DirReader = exports.Dir.Reader
+exports.Reader.File = exports.FileReader = exports.File.Reader
+exports.Reader.Link = exports.LinkReader = exports.Link.Reader
+exports.Reader.Proxy = exports.ProxyReader = exports.Proxy.Reader
+
+exports.Writer.Dir = exports.DirWriter = exports.Dir.Writer
+exports.Writer.File = exports.FileWriter = exports.File.Writer
+exports.Writer.Link = exports.LinkWriter = exports.Link.Writer
+exports.Writer.Proxy = exports.ProxyWriter = exports.Proxy.Writer
+
+exports.collect = require("./lib/collect.js")
diff --git a/node_modules/fstream/lib/abstract.js b/node_modules/fstream/lib/abstract.js
new file mode 100644
index 000000000..add48b945
--- /dev/null
+++ b/node_modules/fstream/lib/abstract.js
@@ -0,0 +1,82 @@
+// the parent class for all fstreams.
+
+module.exports = Abstract
+
+var Stream = require("stream").Stream
+ , inherits = require("inherits")
+
+function Abstract () {
+ Stream.call(this)
+}
+
+inherits(Abstract, Stream)
+
+Abstract.prototype.on = function (ev, fn) {
+ if (ev === "ready" && this.ready) {
+ process.nextTick(fn.bind(this))
+ } else {
+ Stream.prototype.on.call(this, ev, fn)
+ }
+ return this
+}
+
+Abstract.prototype.destroy = function () {}
+
+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",
+ er.stack,
+ er.path,
+ er.syscall,
+ er.fstream_type,
+ er.fstream_path,
+ er.fstream_unc_path,
+ er.fstream_class,
+ er.fstream_stack.join("\n"))
+ } else {
+ me.emit("warn", er)
+ }
+}
+
+Abstract.prototype.info = function (msg, code) {
+ var me = this
+ if (!me.listeners("info")) return
+ me.emit("info", msg, code)
+}
+
+Abstract.prototype.error = function (msg, code, th) {
+ var er = decorate(msg, code, this)
+ if (th) throw er
+ else this.emit("error", er)
+}
+
+function decorate (er, code, me) {
+ 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
+ }
+ if (me.linkpath) {
+ er.fstream_linkpath = er.fstream_linkpath || me.linkpath
+ }
+ er.fstream_class = er.fstream_class || me.constructor.name
+ er.fstream_stack = er.fstream_stack ||
+ new Error().stack.split(/\n/).slice(3).map(function (s) {
+ return s.replace(/^ at /, "")
+ })
+
+ return er
+}
diff --git a/node_modules/fstream/lib/collect.js b/node_modules/fstream/lib/collect.js
new file mode 100644
index 000000000..a36f780eb
--- /dev/null
+++ b/node_modules/fstream/lib/collect.js
@@ -0,0 +1,67 @@
+module.exports = collect
+
+function collect (stream) {
+ if (stream._collected) return
+
+ stream._collected = true
+ stream.pause()
+
+ stream.on("data", save)
+ stream.on("end", save)
+ var buf = []
+ function save (b) {
+ if (typeof b === "string") b = new Buffer(b)
+ if (Buffer.isBuffer(b) && !b.length) return
+ buf.push(b)
+ }
+
+ stream.on("entry", saveEntry)
+ var entryBuffer = []
+ function saveEntry (e) {
+ collect(e)
+ entryBuffer.push(e)
+ }
+
+ stream.on("proxy", proxyPause)
+ function proxyPause (p) {
+ p.pause()
+ }
+
+
+ // replace the pipe method with a new version that will
+ // unlock the buffered stuff. if you just call .pipe()
+ // without a destination, then it'll re-play the events.
+ stream.pipe = (function (orig) { return function (dest) {
+ // console.error(" === open the pipes", dest && dest.path)
+
+ // let the entries flow through one at a time.
+ // Once they're all done, then we can resume completely.
+ var e = 0
+ ;(function unblockEntry () {
+ var entry = entryBuffer[e++]
+ // console.error(" ==== unblock entry", entry && entry.path)
+ if (!entry) return resume()
+ entry.on("end", unblockEntry)
+ if (dest) dest.add(entry)
+ else stream.emit("entry", entry)
+ })()
+
+ function resume () {
+ stream.removeListener("entry", saveEntry)
+ stream.removeListener("data", save)
+ stream.removeListener("end", save)
+
+ stream.pipe = orig
+ if (dest) stream.pipe(dest)
+
+ buf.forEach(function (b) {
+ if (b) stream.emit("data", b)
+ else stream.emit("end")
+ })
+
+ stream.resume()
+ }
+
+ return dest
+ }})(stream.pipe)
+}
diff --git a/node_modules/fstream/lib/dir-reader.js b/node_modules/fstream/lib/dir-reader.js
new file mode 100644
index 000000000..ab990d150
--- /dev/null
+++ b/node_modules/fstream/lib/dir-reader.js
@@ -0,0 +1,192 @@
+// A thing that emits "entry" events with Reader objects
+// Pausing it causes it to stop emitting entry events, and also
+// pauses the current entry if there is one.
+
+module.exports = DirReader
+
+var fs = require("graceful-fs")
+ , fstream = require("../fstream.js")
+ , Reader = fstream.Reader
+ , inherits = require("inherits")
+ , mkdir = require("mkdirp")
+ , path = require("path")
+ , Reader = require("./reader.js")
+
+inherits(DirReader, Reader)
+
+function DirReader (props) {
+ var me = this
+ if (!(me 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)
+ }
+
+ me._entries = null
+ me._index = -1
+ me._paused = false
+ me._length = -1
+
+ Reader.call(this, props)
+}
+
+DirReader.prototype._getEntries = function () {
+ var me = this
+ fs.readdir(me._path, function (er, entries) {
+ if (er) return me.error(er)
+ me._entries = entries
+ me._length = entries.length
+ // console.error("DR %s sort =", me.path, me.props.sort)
+ if (typeof me.props.sort === "function") {
+ me._entries.sort(me.props.sort)
+ }
+ me._read()
+ })
+}
+
+// start walking the dir, and emit an "entry" event for each one.
+DirReader.prototype._read = function () {
+ var me = this
+
+ if (!me._entries) return me._getEntries()
+
+ if (me._paused || me._currentEntry || me._aborted) {
+ // console.error("DR paused=%j, current=%j, aborted=%j", me._paused, !!me._currentEntry, me._aborted)
+ return
+ }
+
+ me._index ++
+ if (me._index >= me._length) {
+ if (!me._ended) {
+ me._ended = true
+ me.emit("end")
+ me.emit("close")
+ }
+ return
+ }
+
+ // ok, handle this one, then.
+
+ // save creating a proxy, by stat'ing the thing now.
+ var p = path.resolve(me._path, me._entries[me._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)
+
+ var entry = Reader({ path: p
+ , depth: me.depth + 1
+ , root: me.root || me._proxy || me
+ , parent: me._proxy || me
+ , follow: me.follow
+ , filter: me.filter
+ , sort: me.props.sort
+ }, stat)
+
+ // console.error("DR Entry", p, stat.size)
+
+ me._currentEntry = entry
+
+ // "entry" events are for direct entries in a specific dir.
+ // "child" events are for any and all children at all levels.
+ // This nomenclature is not completely final.
+
+ entry.on("pause", function (who) {
+ if (!me._paused) {
+ me.pause(who)
+ }
+ })
+
+ entry.on("resume", function (who) {
+ if (me._paused) {
+ me.resume(who)
+ }
+ })
+
+ entry.on("ready", function EMITCHILD () {
+ // console.error("DR emit child", entry._path)
+ if (me._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)
+ }
+
+ // skip over sockets. they can't be piped around properly,
+ // so there's really no sense even acknowledging them.
+ // if someone really wants to see them, they can listen to
+ // the "socket" events.
+ if (entry.type === "Socket") {
+ me.emit("socket", entry)
+ } else {
+ me.emit("entry", entry)
+ me.emit("child", entry)
+ }
+ })
+
+ var ended = false
+ entry.on("close", onend)
+ function onend () {
+ if (ended) return
+ ended = true
+ me.emit("childEnd", entry)
+ me.emit("entryEnd", entry)
+ me._currentEntry = null
+ me._read()
+ }
+
+ // XXX Make this work in node.
+ // Long filenames should not break stuff.
+ entry.on("error", function (er) {
+ if (entry._swallowErrors) {
+ me.warn(er)
+ entry.emit("end")
+ entry.emit("close")
+ } else {
+ me.emit("error", er)
+ }
+ })
+
+ // proxy up some events.
+ ; [ "child"
+ , "childEnd"
+ , "warn"
+ ].forEach(function (ev) {
+ entry.on(ev, me.emit.bind(me, ev))
+ })
+ })
+}
+
+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)
+ }
+ me.emit("pause", who)
+}
+
+DirReader.prototype.resume = function (who) {
+ var me = this
+ if (!me._paused) return
+ who = who || me
+
+ me._paused = false
+ // console.error("DR Emit Resume", me._path)
+ me.emit("resume", who)
+ if (me._paused) {
+ // console.error("DR Re-paused", me._path)
+ return
+ }
+
+ if (me._currentEntry) {
+ if (me._currentEntry.resume) {
+ me._currentEntry.resume(who)
+ }
+ } else me._read()
+}
diff --git a/node_modules/fstream/lib/dir-writer.js b/node_modules/fstream/lib/dir-writer.js
new file mode 100644
index 000000000..01920244c
--- /dev/null
+++ b/node_modules/fstream/lib/dir-writer.js
@@ -0,0 +1,165 @@
+// It is expected that, when .add() returns false, the consumer
+// of the DirWriter will pause until a "drain" event occurs. Note
+// that this is *almost always going to be the case*, unless the
+// thing being written is some sort of unsupported type, and thus
+// skipped over.
+
+module.exports = DirWriter
+
+var 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")
+
+inherits(DirWriter, Writer)
+
+function DirWriter (props) {
+ var me = this
+ if (!(me instanceof DirWriter)) me.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)
+ }
+
+ Writer.call(this, props)
+}
+
+DirWriter.prototype._create = function () {
+ var me = this
+ mkdir(me._path, Writer.dirmode, function (er) {
+ if (er) return me.error(er)
+ // ready to start getting entries!
+ me.ready = true
+ me.emit("ready")
+ })
+}
+
+// a DirWriter has an add(entry) method, but its .write() doesn't
+// do anything. Why a no-op rather than a throw? Because this
+// leaves open the door for writing directory metadata for
+// gnu/solaris style dumpdirs.
+DirWriter.prototype.write = function () {
+ return true
+}
+
+DirWriter.prototype.end = function () {
+ this._ended = true
+ this._process()
+}
+
+DirWriter.prototype.add = function (entry) {
+ var me = this
+
+ // console.error("\tadd", entry._path, "->", me._path)
+ collect(entry)
+ if (!me.ready || me._currentEntry) {
+ me._buffer.push(entry)
+ return false
+ }
+
+ // create a new writer, and pipe the incoming entry into it.
+ if (me._ended) {
+ return me.error("add after end")
+ }
+
+ me._buffer.push(entry)
+ me._process()
+
+ return 0 === this._buffer.length
+}
+
+DirWriter.prototype._process = function () {
+ var me = this
+
+ // console.error("DW Process p=%j", me._processing, me.basename)
+
+ if (me._processing) return
+
+ var entry = me._buffer.shift()
+ if (!entry) {
+ // console.error("DW Drain")
+ me.emit("drain")
+ if (me._ended) me._finish()
+ return
+ }
+
+ me._processing = true
+ // console.error("DW Entry", entry._path)
+
+ me.emit("entry", entry)
+
+ // ok, add this entry
+ //
+ // don't allow recursive copying
+ var p = entry
+ do {
+ if (p._path === me.root._path || p._path === me._path) {
+ // console.error("DW Exit (recursive)", entry.basename, me._path)
+ me._processing = false
+ if (entry._collected) entry.pipe()
+ return me._process()
+ }
+ } while (p = p.parent)
+
+ // 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 p = entry._path || entry.path || entry.props.path
+ if (entry.parent) {
+ p = p.substr(entry.parent._path.length + 1)
+ }
+ // get rid of any ../../ shenanigans
+ props.path = path.join(me.path, path.join("/", p))
+
+ // all the rest of the stuff, copy over from the source.
+ Object.keys(entry.props).forEach(function (k) {
+ if (!props.hasOwnProperty(k)) {
+ props[k] = entry.props[k]
+ }
+ })
+
+ // not sure at this point what kind of writer this is.
+ var child = me._currentChild = new Writer(props)
+ child.on("ready", function () {
+ // console.error("DW Child Ready", child.type, child._path)
+ // console.error(" resuming", entry._path)
+ entry.pipe(child)
+ entry.resume()
+ })
+
+ // XXX Make this work in node.
+ // Long filenames should not break stuff.
+ child.on("error", function (er) {
+ if (child._swallowErrors) {
+ me.warn(er)
+ child.emit("end")
+ child.emit("close")
+ } else {
+ me.emit("error", er)
+ }
+ })
+
+ // we fire _end internally *after* end, so that we don't move on
+ // until any "end" listeners have had their chance to do stuff.
+ child.on("close", onend)
+ var ended = false
+ function onend () {
+ if (ended) return
+ ended = true
+ // console.error("* DW Child end", child.basename)
+ me._currentChild = null
+ me._processing = false
+ me._process()
+ }
+}
diff --git a/node_modules/fstream/lib/file-reader.js b/node_modules/fstream/lib/file-reader.js
new file mode 100644
index 000000000..b1f986183
--- /dev/null
+++ b/node_modules/fstream/lib/file-reader.js
@@ -0,0 +1,147 @@
+// Basically just a wrapper around an fs.ReadStream
+
+module.exports = FileReader
+
+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}
+
+inherits(FileReader, Reader)
+
+function FileReader (props) {
+ // 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.")
+
+ // should already be established as a File type
+ // XXX Todo: preserve hardlinks by tracking dev+inode+nlink,
+ // with a HardLinkReader class.
+ if (!((props.type === "Link" && props.Link) ||
+ (props.type === "File" && props.File))) {
+ throw new Error("Non-file type "+ props.type)
+ }
+
+ me._buffer = []
+ me._bytesEmitted = 0
+ Reader.call(me, props)
+}
+
+FileReader.prototype._getStream = function () {
+ var me = this
+ , stream = me._stream = fs.createReadStream(me._path, me.props)
+
+ if (me.props.blksize) {
+ stream.bufferSize = me.props.blksize
+ }
+
+ stream.on("open", me.emit.bind(me, "open"))
+
+ stream.on("data", function (c) {
+ // console.error("\t\t%d %s", c.length, me.basename)
+ me._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)
+ })
+
+ stream.on("end", function () {
+ if (me._paused || me._buffer.length) {
+ // console.error("FR Buffering End", me._path)
+ me._buffer.push(EOF)
+ me._read()
+ } else {
+ me.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)
+ }
+ })
+
+ stream.on("close", function () {
+ if (me._paused || me._buffer.length) {
+ // console.error("FR Buffering Close", me._path)
+ me._buffer.push(CLOSE)
+ me._read()
+ } else {
+ // console.error("FR close 1", me._path)
+ me.emit("close")
+ }
+ })
+
+ me._read()
+}
+
+FileReader.prototype._read = function () {
+ var me = this
+ // console.error("FR _read", me._path)
+ if (me._paused) {
+ // console.error("FR _read paused", me._path)
+ return
+ }
+
+ if (!me._stream) {
+ // console.error("FR _getStream calling", me._path)
+ return me._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 ++) {
+ var c = buf[i]
+ if (c === EOF) {
+ // console.error("FR Read emitting buffered end", me._path)
+ me.emit("end")
+ } else if (c === CLOSE) {
+ // console.error("FR Read emitting buffered close", me._path)
+ me.emit("close")
+ } else {
+ // console.error("FR Read emitting buffered data", me._path)
+ me.emit("data", c)
+ }
+
+ if (me._paused) {
+ // console.error("FR Read Re-pausing at "+i, me._path)
+ me._buffer = buf.slice(i)
+ return
+ }
+ }
+ me._buffer.length = 0
+ }
+ // console.error("FR _read done")
+ // that's about all there is to it.
+}
+
+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)
+}
+
+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()
+}
diff --git a/node_modules/fstream/lib/file-writer.js b/node_modules/fstream/lib/file-writer.js
new file mode 100644
index 000000000..4ed0c9c6c
--- /dev/null
+++ b/node_modules/fstream/lib/file-writer.js
@@ -0,0 +1,95 @@
+module.exports = FileWriter
+
+var fs = require("graceful-fs")
+ , mkdir = require("mkdirp")
+ , Writer = require("./writer.js")
+ , inherits = require("inherits")
+ , EOF = {}
+
+inherits(FileWriter, Writer)
+
+function FileWriter (props) {
+ var me = this
+ if (!(me 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)
+ }
+
+ me._buffer = []
+ me._bytesWritten = 0
+
+ Writer.call(this, props)
+}
+
+FileWriter.prototype._create = function () {
+ var me = this
+ if (me._stream) return
+
+ var so = {}
+ if (me.props.flags) so.flags = me.props.flags
+ so.mode = Writer.filemode
+ if (me._old && me._old.blksize) so.bufferSize = me._old.blksize
+
+ me._stream = fs.createWriteStream(me._path, so)
+
+ me._stream.on("open", function (fd) {
+ me.ready = true
+ me._buffer.forEach(function (c) {
+ if (c === EOF) me._stream.end()
+ else me._stream.write(c)
+ })
+ me.emit("ready")
+ })
+
+ me._stream.on("drain", function () { me.emit("drain") })
+
+ me._stream.on("close", function () {
+ // console.error("\n\nFW Stream Close", me._path, me.size)
+ me._finish()
+ })
+}
+
+FileWriter.prototype.write = function (c) {
+ var me = this
+
+ me._bytesWritten += c.length
+
+ if (!me.ready) {
+ me._buffer.push(c)
+ return false
+ }
+
+ var ret = me._stream.write(c)
+ // console.error("\t-- fw wrote, _stream says", ret, me._stream._queue.length)
+
+ // allow 2 buffered writes, because otherwise there's just too
+ // much stop and go bs.
+ return ret || (me._stream._queue && me._stream._queue.length <= 2)
+}
+
+FileWriter.prototype.end = function (c) {
+ var me = this
+
+ if (c) me.write(c)
+
+ if (!me.ready) {
+ me._buffer.push(EOF)
+ return false
+ }
+
+ return me._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)
+ }
+ Writer.prototype._finish.call(me)
+}
diff --git a/node_modules/fstream/lib/get-type.js b/node_modules/fstream/lib/get-type.js
new file mode 100644
index 000000000..cd65c41d8
--- /dev/null
+++ b/node_modules/fstream/lib/get-type.js
@@ -0,0 +1,32 @@
+module.exports = getType
+
+function getType (st) {
+ var types =
+ [ "Directory"
+ , "File"
+ , "SymbolicLink"
+ , "Link" // special for hardlinks from tarballs
+ , "BlockDevice"
+ , "CharacterDevice"
+ , "FIFO"
+ , "Socket" ]
+ , type
+
+ if (st.type && -1 !== types.indexOf(st.type)) {
+ st[st.type] = true
+ return st.type
+ }
+
+ for (var i = 0, l = types.length; i < l; i ++) {
+ type = types[i]
+ var is = st[type] || st["is" + type]
+ if (typeof is === "function") is = is.call(st)
+ if (is) {
+ st[type] = true
+ st.type = type
+ return type
+ }
+ }
+
+ return null
+}
diff --git a/node_modules/fstream/lib/link-reader.js b/node_modules/fstream/lib/link-reader.js
new file mode 100644
index 000000000..7e7ab6ce5
--- /dev/null
+++ b/node_modules/fstream/lib/link-reader.js
@@ -0,0 +1,54 @@
+// Basically just a wrapper around an fs.readlink
+//
+// XXX: Enhance this to support the Link type, by keeping
+// a lookup table of {<dev+inode>:<path>}, so that hardlinks
+// can be preserved in tarballs.
+
+module.exports = LinkReader
+
+var fs = require("graceful-fs")
+ , fstream = require("../fstream.js")
+ , inherits = require("inherits")
+ , mkdir = require("mkdirp")
+ , Reader = require("./reader.js")
+
+inherits(LinkReader, Reader)
+
+function LinkReader (props) {
+ var me = this
+ if (!(me instanceof LinkReader)) throw new Error(
+ "LinkReader must be called as constructor.")
+
+ if (!((props.type === "Link" && props.Link) ||
+ (props.type === "SymbolicLink" && props.SymbolicLink))) {
+ throw new Error("Non-link type "+ props.type)
+ }
+
+ Reader.call(me, props)
+}
+
+// When piping a LinkReader into a LinkWriter, we have to
+// already have the linkpath property set, so that has to
+// happen *before* the "ready" event, which means we need to
+// override the _stat method.
+LinkReader.prototype._stat = function (currentStat) {
+ var 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)
+ })
+}
+
+LinkReader.prototype._read = function () {
+ var me = this
+ if (me._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
+ }
+}
diff --git a/node_modules/fstream/lib/link-writer.js b/node_modules/fstream/lib/link-writer.js
new file mode 100644
index 000000000..8a9816380
--- /dev/null
+++ b/node_modules/fstream/lib/link-writer.js
@@ -0,0 +1,96 @@
+
+module.exports = LinkWriter
+
+var fs = require("graceful-fs")
+ , Writer = require("./writer.js")
+ , inherits = require("inherits")
+ , collect = require("./collect.js")
+ , path = require("path")
+ , rimraf = require("rimraf")
+
+inherits(LinkWriter, Writer)
+
+function LinkWriter (props) {
+ var me = this
+ if (!(me instanceof LinkWriter)) throw new Error(
+ "LinkWriter must be called as constructor.")
+
+ // should already be established as a Link type
+ if (!((props.type === "Link" && props.Link) ||
+ (props.type === "SymbolicLink" && props.SymbolicLink))) {
+ throw new Error("Non-link type "+ props.type)
+ }
+
+ if (props.linkpath === "") props.linkpath = "."
+ if (!props.linkpath) {
+ me.error("Need linkpath property to create " + props.type)
+ }
+
+ Writer.call(this, props)
+}
+
+LinkWriter.prototype._create = function () {
+ // 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
+
+ // can only change the link path by clobbering
+ // For hard links, let's just assume that's always the case, since
+ // there's no good way to read them if we don't already know.
+ if (hard) return clobber(me, lp, link)
+
+ fs.readlink(me._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)
+ })
+}
+
+function clobber (me, lp, link) {
+ rimraf(me._path, function (er) {
+ if (er) return me.error(er)
+ create(me, lp, link)
+ })
+}
+
+function create (me, lp, link) {
+ fs[link](lp, me._path, function (er) {
+ // if this is a hard link, and we're in the process of writing out a
+ // directory, it's very possible that the thing we're linking to
+ // doesn't exist yet (especially if it was intended as a symlink),
+ // so swallow ENOENT errors here and just soldier in.
+ // Additionally, an EPERM or EACCES can happen on win32 if it's trying
+ // to make a link to a directory. Again, just skip it.
+ // A better solution would be to have fs.symlink be supported on
+ // windows in some nice fashion.
+ if (er) {
+ if ((er.code === "ENOENT" ||
+ er.code === "EACCES" ||
+ er.code === "EPERM" ) && process.platform === "win32") {
+ me.ready = true
+ me.emit("ready")
+ me.emit("end")
+ me.emit("close")
+ me.end = me._finish = function () {}
+ } else return me.error(er)
+ }
+ finish(me)
+ })
+}
+
+function finish (me) {
+ me.ready = true
+ me.emit("ready")
+ if (me._ended && !me._finished) me._finish()
+}
+
+LinkWriter.prototype.end = function () {
+ // console.error("LW finish in end")
+ this._ended = true
+ if (this.ready) {
+ this._finished = true
+ this._finish()
+ }
+}
diff --git a/node_modules/fstream/lib/proxy-reader.js b/node_modules/fstream/lib/proxy-reader.js
new file mode 100644
index 000000000..f99b28fe5
--- /dev/null
+++ b/node_modules/fstream/lib/proxy-reader.js
@@ -0,0 +1,89 @@
+// A reader for when we don't yet know what kind of thing
+// the thing is.
+
+module.exports = ProxyReader
+
+var Reader = require("./reader.js")
+ , getType = require("./get-type.js")
+ , inherits = require("inherits")
+ , fs = require("graceful-fs")
+
+inherits(ProxyReader, Reader)
+
+function ProxyReader (props) {
+ var me = this
+ if (!(me instanceof ProxyReader)) throw new Error(
+ "ProxyReader must be called as constructor.")
+
+ me.props = props
+ me._buffer = []
+ me.ready = false
+
+ Reader.call(me, 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"
+
+ fs[stat](props.path, function (er, current) {
+ var type
+ if (er || !current) {
+ type = "File"
+ } else {
+ type = getType(current)
+ }
+
+ props[type] = true
+ props.type = me.type = type
+
+ me._old = current
+ me._addProxy(Reader(props, current))
+ })
+}
+
+ProxyReader.prototype._addProxy = function (proxy) {
+ var me = this
+ if (me._proxyTarget) {
+ return me.error("proxy already set")
+ }
+
+ me._proxyTarget = proxy
+ proxy._proxy = me
+
+ ; [ "error"
+ , "data"
+ , "end"
+ , "close"
+ , "linkpath"
+ , "entry"
+ , "warn"
+ ].forEach(function (ev) {
+ // console.error("~~ proxy event", ev, me.path)
+ proxy.on(ev, me.emit.bind(me, ev))
+ })
+
+ me.emit("proxy", proxy)
+
+ proxy.on("ready", function () {
+ // console.error("~~ proxy is ready!", me.path)
+ me.ready = true
+ me.emit("ready")
+ })
+
+ var calls = me._buffer
+ me._buffer.length = 0
+ calls.forEach(function (c) {
+ proxy[c[0]].apply(proxy, c[1])
+ })
+}
+
+ProxyReader.prototype.pause = function () {
+ return this._proxyTarget ? this._proxyTarget.pause() : false
+}
+
+ProxyReader.prototype.resume = function () {
+ return this._proxyTarget ? this._proxyTarget.resume() : false
+}
diff --git a/node_modules/fstream/lib/proxy-writer.js b/node_modules/fstream/lib/proxy-writer.js
new file mode 100644
index 000000000..2c78fc673
--- /dev/null
+++ b/node_modules/fstream/lib/proxy-writer.js
@@ -0,0 +1,109 @@
+// A writer for when we don't know what kind of thing
+// the thing is. That is, it's not explicitly set,
+// so we're going to make it whatever the thing already
+// is, or "File"
+//
+// Until then, collect all events.
+
+module.exports = ProxyWriter
+
+var Writer = require("./writer.js")
+ , getType = require("./get-type.js")
+ , inherits = require("inherits")
+ , collect = require("./collect.js")
+ , fs = require("fs")
+
+inherits(ProxyWriter, Writer)
+
+function ProxyWriter (props) {
+ var me = this
+ if (!(me instanceof ProxyWriter)) throw new Error(
+ "ProxyWriter must be called as constructor.")
+
+ me.props = props
+ me._needDrain = false
+
+ Writer.call(me, 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"
+
+ fs[stat](props.path, function (er, current) {
+ var type
+ if (er || !current) {
+ type = "File"
+ } else {
+ type = getType(current)
+ }
+
+ props[type] = true
+ props.type = me.type = type
+
+ me._old = current
+ me._addProxy(Writer(props, current))
+ })
+}
+
+ProxyWriter.prototype._addProxy = function (proxy) {
+ // console.error("~~ set proxy", this.path)
+ var me = this
+ if (me._proxy) {
+ return me.error("proxy already set")
+ }
+
+ me._proxy = proxy
+ ; [ "ready"
+ , "error"
+ , "close"
+ , "pipe"
+ , "drain"
+ , "warn"
+ ].forEach(function (ev) {
+ proxy.on(ev, me.emit.bind(me, ev))
+ })
+
+ me.emit("proxy", proxy)
+
+ var calls = me._buffer
+ calls.forEach(function (c) {
+ // console.error("~~ ~~ proxy buffered call", c[0], c[1])
+ proxy[c[0]].call(proxy, c[1])
+ })
+ me._buffer.length = 0
+ if (me._needsDrain) me.emit("drain")
+}
+
+ProxyWriter.prototype.add = function (entry) {
+ // console.error("~~ proxy add")
+ collect(entry)
+
+ if (!this._proxy) {
+ this._buffer.push(["add", [entry]])
+ this._needDrain = true
+ return false
+ }
+ return this._proxy.add(entry)
+}
+
+ProxyWriter.prototype.write = function (c) {
+ // console.error("~~ proxy write")
+ if (!this._proxy) {
+ this._buffer.push(["write", [c]])
+ this._needDrain = true
+ return false
+ }
+ return this._proxy.write(c)
+}
+
+ProxyWriter.prototype.end = function (c) {
+ // console.error("~~ proxy end")
+ if (!this._proxy) {
+ this._buffer.push(["end", c])
+ return false
+ }
+ return this._proxy.end(c)
+}
diff --git a/node_modules/fstream/lib/reader.js b/node_modules/fstream/lib/reader.js
new file mode 100644
index 000000000..6aa67ada7
--- /dev/null
+++ b/node_modules/fstream/lib/reader.js
@@ -0,0 +1,240 @@
+
+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")
+
+// Must do this *before* loading the child classes
+inherits(Reader, Abstract)
+
+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")
+
+function Reader (props, currentStat) {
+ var me = this
+ if (!(me instanceof Reader)) return new Reader(props, currentStat)
+
+ if (typeof props === "string") {
+ props = { path: props }
+ }
+
+ if (!props.path) {
+ me.error("Must provide a path", null, true)
+ }
+
+ // polymorphism.
+ // call fstream.Reader(dir) to get a DirReader object, etc.
+ // Note that, unlike in the Writer case, ProxyReader is going
+ // to be the *normal* state of affairs, since we rarely know
+ // the type of a file prior to reading it.
+
+
+ var type
+ , ClassType
+
+ if (props.type && typeof props.type === "function") {
+ type = props.type
+ ClassType = type
+ } else {
+ type = getType(props)
+ ClassType = Reader
+ }
+
+ if (currentStat && !type) {
+ type = getType(currentStat)
+ props[type] = true
+ props.type = type
+ }
+
+ switch (type) {
+ case "Directory":
+ ClassType = DirReader
+ break
+
+ case "Link":
+ // XXX hard links are just files.
+ // However, it would be good to keep track of files' dev+inode
+ // and nlink values, and create a HardLinkReader that emits
+ // a linkpath value of the original copy, so that the tar
+ // writer can preserve them.
+ // ClassType = HardLinkReader
+ // break
+
+ case "File":
+ ClassType = FileReader
+ break
+
+ case "SymbolicLink":
+ ClassType = LinkReader
+ break
+
+ case "Socket":
+ ClassType = SocketReader
+ break
+
+ case null:
+ ClassType = ProxyReader
+ break
+ }
+
+ if (!(me instanceof ClassType)) {
+ return new ClassType(props)
+ }
+
+ Abstract.call(me)
+
+ me.readable = true
+ me.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
+
+ 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) {
+ // 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)
+ me.dirname = props.dirname = path.dirname(me.path)
+
+ // these have served their purpose, and are now just noisy clutter
+ props.parent = props.root = null
+
+ // console.error("\n\n\n%s setting size to", props.path, props.size)
+ me.size = props.size
+ me.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()
+ // to start reading whatever it is.
+ // console.error("calling stat", props.path, currentStat)
+ me._stat(currentStat)
+}
+
+function alphasort (a, b) {
+ return a === b ? 0
+ : a.toLowerCase() > b.toLowerCase() ? 1
+ : a.toLowerCase() < b.toLowerCase() ? -1
+ : a > b ? 1
+ : -1
+}
+
+Reader.prototype._stat = function (currentStat) {
+ var me = this
+ , props = me.props
+ , stat = props.follow ? "stat" : "lstat"
+
+ // console.error("Reader._stat", me._path, currentStat)
+ if (currentStat) process.nextTick(statCb.bind(null, null, currentStat))
+ else fs[stat](me._path, statCb)
+
+
+ function statCb (er, props_) {
+ // console.error("Reader._stat, statCb", me._path, props_, props_.nlink)
+ if (er) return me.error(er)
+
+ Object.keys(props_).forEach(function (k) {
+ props[k] = props_[k]
+ })
+
+ // if it's not the expected size, then abort here.
+ if (undefined !== me.size && props.size !== me.size) {
+ return me.error("incorrect size")
+ }
+ me.size = props.size
+
+ var type = getType(props)
+ // special little thing for handling hardlinks.
+ if (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 {
+ // 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)
+ // Setting __proto__ would arguably be the "correct"
+ // approach here, but that just seems too wrong.
+ me._stat = me._read = LinkReader.prototype._read
+ }
+ }
+
+ if (me.type && me.type !== type) {
+ me.error("Unexpected type: " + type)
+ }
+
+ // if the filter doesn't pass, then just skip over this one.
+ // still have to emit end so that dir-walking can move on.
+ if (me.filter) {
+ // special handling for ProxyReaders
+ if (!me.filter.call(me._proxy || me)) {
+ me._aborted = true
+ me.emit("end")
+ me.emit("close")
+ return
+ }
+ }
+
+ me.emit("ready", props)
+
+ // if it's a directory, then we'll be emitting "entry" events.
+ me._read()
+ }
+}
+
+Reader.prototype.pipe = function (dest, opts) {
+ var me = this
+ if (typeof dest.add === "function") {
+ // piping to a multi-compatible, and we've got directory entries.
+ me.on("entry", function (entry) {
+ var ret = dest.add(entry)
+ if (false === ret) {
+ me.pause()
+ }
+ })
+ }
+
+ // console.error("R Pipe apply Stream Pipe")
+ return Stream.prototype.pipe.apply(this, arguments)
+}
+
+Reader.prototype.pause = function (who) {
+ this._paused = true
+ who = who || this
+ this.emit("pause", who)
+ if (this._stream) this._stream.pause(who)
+}
+
+Reader.prototype.resume = function (who) {
+ this._paused = false
+ who = who || this
+ this.emit("resume", who)
+ if (this._stream) this._stream.resume(who)
+ this._read()
+}
+
+Reader.prototype._read = function () {
+ this.error("Cannot read unknown type: "+this.type)
+}
+
diff --git a/node_modules/fstream/lib/socket-reader.js b/node_modules/fstream/lib/socket-reader.js
new file mode 100644
index 000000000..e89c1731a
--- /dev/null
+++ b/node_modules/fstream/lib/socket-reader.js
@@ -0,0 +1,38 @@
+// Just get the stats, and then don't do anything.
+// You can't really "read" from a socket. You "connect" to it.
+// Mostly, this is here so that reading a dir with a socket in it
+// doesn't blow up.
+
+module.exports = SocketReader
+
+var fs = require("graceful-fs")
+ , fstream = require("../fstream.js")
+ , inherits = require("inherits")
+ , mkdir = require("mkdirp")
+ , Reader = require("./reader.js")
+
+inherits(SocketReader, Reader)
+
+function SocketReader (props) {
+ var me = this
+ if (!(me instanceof SocketReader)) throw new Error(
+ "SocketReader must be called as constructor.")
+
+ if (!(props.type === "Socket" && props.Socket)) {
+ throw new Error("Non-socket type "+ props.type)
+ }
+
+ Reader.call(me, props)
+}
+
+SocketReader.prototype._read = function () {
+ var me = this
+ if (me._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
+ }
+}
diff --git a/node_modules/fstream/lib/writer.js b/node_modules/fstream/lib/writer.js
new file mode 100644
index 000000000..dde29fd7b
--- /dev/null
+++ b/node_modules/fstream/lib/writer.js
@@ -0,0 +1,316 @@
+
+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")
+
+// Must do this *before* loading the child classes
+inherits(Writer, Abstract)
+
+Writer.dirmode = 0777 & (~umask)
+Writer.filemode = 0666 & (~umask)
+
+var DirWriter = require("./dir-writer.js")
+ , LinkWriter = require("./link-writer.js")
+ , FileWriter = require("./file-writer.js")
+ , ProxyWriter = require("./proxy-writer.js")
+
+// props is the desired state. current is optionally the current stat,
+// provided here so that subclasses can avoid statting the target
+// more than necessary.
+function Writer (props, current) {
+ var me = this
+
+ if (typeof props === "string") {
+ props = { path: props }
+ }
+
+ if (!props.path) me.error("Must provide a path", null, true)
+
+ // polymorphism.
+ // call fstream.Writer(dir) to get a DirWriter object, etc.
+ var type = getType(props)
+ , ClassType = Writer
+
+ switch (type) {
+ case "Directory":
+ ClassType = DirWriter
+ break
+ case "File":
+ ClassType = FileWriter
+ break
+ case "Link":
+ case "SymbolicLink":
+ ClassType = LinkWriter
+ break
+ case null:
+ // Don't know yet what type to create, so we wrap in a proxy.
+ ClassType = ProxyWriter
+ break
+ }
+
+ if (!(me instanceof ClassType)) return new ClassType(props)
+
+ // now get down to business.
+
+ Abstract.call(me)
+
+ // 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
+
+ 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, "\\")
+ }
+ }
+ me.basename = path.basename(props.path)
+ me.dirname = path.dirname(props.path)
+ me.linkpath = props.linkpath || null
+
+ props.parent = props.root = null
+
+ // console.error("\n\n\n%s setting size to", props.path, props.size)
+ me.size = props.size
+
+ if (typeof props.mode === "string") {
+ props.mode = parseInt(props.mode, 8)
+ }
+
+ me.readable = false
+ me.writable = true
+
+ // buffer until ready, or while handling another entry
+ me._buffer = []
+ me.ready = false
+
+ // 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)
+}
+
+// Calling this means that it's something we can't create.
+// Just assert that it's already there, otherwise raise a warning.
+Writer.prototype._create = function () {
+ var me = this
+ fs[me.props.follow ? "stat" : "lstat"](me._path, function (er, current) {
+ if (er) {
+ return me.warn("Cannot create " + me._path + "\n" +
+ "Unsupported type: "+me.type, "ENOTSUP")
+ }
+ me._finish()
+ })
+}
+
+Writer.prototype._stat = function (current) {
+ var me = this
+ , props = me.props
+ , stat = props.follow ? "stat" : "lstat"
+
+ if (current) statCb(null, current)
+ else fs[stat](me._path, statCb)
+
+ function statCb (er, current) {
+ // if it's not there, great. We'll just create it.
+ // if it is there, then we'll need to change whatever differs
+ if (er || !current) {
+ return create(me)
+ }
+
+ me._old = current
+ var currentType = getType(current)
+
+ // if it's a type change, then we need to clobber or error.
+ // if it's not a type change, then let the impl take care of it.
+ if (currentType !== me.type) {
+ return rimraf(me._path, function (er) {
+ if (er) return me.error(er)
+ me._old = null
+ create(me)
+ })
+ }
+
+ // otherwise, just handle in the app-specific way
+ // this creates a fs.WriteStream, or mkdir's, or whatever
+ create(me)
+ }
+}
+
+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)
+ me._create()
+ })
+}
+
+Writer.prototype._finish = function () {
+ var me = this
+
+ // console.error(" W Finish", me._path, me.size)
+
+ // set up all the things.
+ // At this point, we're already done writing whatever we've gotta write,
+ // adding files to the dir, etc.
+ var todo = 0
+ var errState = null
+ var done = false
+
+ if (me._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)
+ } 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)
+ if (er) {
+ // if we're in the process of writing out a
+ // directory, it's very possible that the thing we're linking to
+ // doesn't exist yet (especially if it was intended as a symlink),
+ // so swallow ENOENT errors here and just soldier on.
+ if (er.code === "ENOENT" &&
+ (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)
+ })
+ }
+
+ return
+
+ function setProps (current) {
+ // console.error(" W setprops", me._path)
+ // mode
+ var wantMode = me.props.mode
+ , chmod = me.props.follow || me.type !== "SymbolicLink"
+ ? "chmod" : "lchmod"
+
+ if (fs[chmod] && typeof wantMode === "number") {
+ wantMode = wantMode & 0777
+ todo ++
+ // console.error(" W chmod", wantMode.toString(8), me.basename, "\r")
+ fs[chmod](me._path, wantMode, next(chmod))
+ }
+
+ // uid, gid
+ // Don't even try it unless root. Too easy to EPERM.
+ if (process.platform !== "win32" &&
+ process.getuid && process.getuid() === 0 &&
+ ( typeof me.props.uid === "number" ||
+ typeof me.props.gid === "number" )) {
+ var chown = (me.props.follow || me.type !== "SymbolicLink")
+ ? "chown" : "lchown"
+ if (fs[chown]) {
+ if (typeof me.props.uid !== "number") me.props.uid = current.uid
+ if (typeof me.props.gid !== "number") me.props.gid = current.gid
+ if (me.props.uid !== current.uid || me.props.gid !== current.gid) {
+ todo ++
+ // console.error(" W chown", me.props.uid, me.props.gid, me.basename)
+ fs[chown](me._path, me.props.uid, me.props.gid, next("chown"))
+ }
+ }
+ }
+
+ // atime, mtime.
+ if (fs.utimes && process.platform !== "win32") {
+ var utimes = (me.props.follow || me.type !== "SymbolicLink")
+ ? "utimes" : "lutimes"
+
+ if (utimes === "lutimes" && !fs[utimes]) {
+ utimes = "utimes"
+ }
+
+ var curA = current.atime
+ , curM = current.mtime
+ , meA = me.props.atime
+ , meM = me.props.mtime
+
+ if (meA === undefined) meA = curA
+ if (meM === undefined) meM = curM
+
+ if (!isDate(meA)) meA = new Date(meA)
+ if (!isDate(meM)) meA = new Date(meM)
+
+ if (meA.getTime() !== curA.getTime() ||
+ meM.getTime() !== curM.getTime()) {
+ todo ++
+ // console.error(" W utimes", meA, meM, me.basename)
+ fs[utimes](me._path, meA, meM, next("utimes"))
+ }
+ }
+
+ // finally, handle the case if there was nothing to do.
+ if (todo === 0) {
+ // console.error(" W nothing to do", me.basename)
+ next("nothing to do")()
+ }
+ }
+
+ function next (what) { return function (er) {
+ // console.error(" W Finish", what, todo)
+ if (errState) return
+ if (er) {
+ er.fstream_finish_call = what
+ return me.error(errState = er)
+ }
+ if (--todo > 0) return
+ if (done) return
+ done = true
+
+ // all the props have been set, so we're completely done.
+ me.emit("end")
+ me.emit("close")
+ }}
+}
+
+Writer.prototype.pipe = function () {
+ this.error("Can't pipe from writable stream")
+}
+
+Writer.prototype.add = function () {
+ this.error("Cannot add to non-Directory type")
+}
+
+Writer.prototype.write = function () {
+ return true
+}
+
+function objectToString (d) {
+ return Object.prototype.toString.call(d)
+}
+
+function isDate(d) {
+ return typeof d === 'object' && objectToString(d) === '[object Date]';
+}
+
diff --git a/node_modules/fstream/package.json b/node_modules/fstream/package.json
new file mode 100644
index 000000000..eb8561532
--- /dev/null
+++ b/node_modules/fstream/package.json
@@ -0,0 +1,26 @@
+{
+ "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
+ "name": "fstream",
+ "description": "Advanced file system stream things",
+ "version": "0.1.11",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/fstream.git"
+ },
+ "main": "fstream.js",
+ "engines": {
+ "node": "0.5 || 0.6 || 0.7"
+ },
+ "dependencies": {
+ "rimraf": "~1.0.8",
+ "mkdirp": "~0.1.0",
+ "graceful-fs": "~1.1.2",
+ "inherits": "~1.0.0"
+ },
+ "devDependencies": {
+ "tap": "0.1"
+ },
+ "scripts": {
+ "test": "tap examples/*.js"
+ }
+}