| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 | // pipe in an fstream, and it'll make a tarball.// key-value pair argument is global extended header props.module.exports = Packvar EntryWriter = require("./entry-writer.js")  , Stream = require("stream").Stream  , path = require("path")  , inherits = require("inherits")  , GlobalHeaderWriter = require("./global-header-writer.js")  , collect = require("fstream").collect  , eof = new Buffer(512)for (var i = 0; i < 512; i ++) eof[i] = 0inherits(Pack, Stream)function Pack (props) {  // console.error("-- p ctor")  var me = this  if (!(me instanceof Pack)) return new Pack(props)  if (props) me._noProprietary = props.noProprietary  else me._noProprietary = false  me._global = props  me.readable = true  me.writable = true  me._buffer = []  // console.error("-- -- set current to null in ctor")  me._currentEntry = null  me._processing = false  me._pipeRoot = null  me.on("pipe", function (src) {    if (src.root === me._pipeRoot) return    me._pipeRoot = src    src.on("end", function () {      me._pipeRoot = null    })    me.add(src)  })}Pack.prototype.addGlobal = function (props) {  // console.error("-- p addGlobal")  if (this._didGlobal) return  this._didGlobal = true  var me = this  GlobalHeaderWriter(props)    .on("data", function (c) {      me.emit("data", c)    })    .end()}Pack.prototype.add = function (stream) {  if (this._global && !this._didGlobal) this.addGlobal(this._global)  if (this._ended) return this.emit("error", new Error("add after end"))  collect(stream)  this._buffer.push(stream)  this._process()  this._needDrain = this._buffer.length > 0  return !this._needDrain}Pack.prototype.pause = function () {  this._paused = true  if (this._currentEntry) this._currentEntry.pause()  this.emit("pause")}Pack.prototype.resume = function () {  this._paused = false  if (this._currentEntry) this._currentEntry.resume()  this.emit("resume")  this._process()}Pack.prototype.end = function () {  this._ended = true  this._buffer.push(eof)  this._process()}Pack.prototype._process = function () {  var me = this  if (me._paused || me._processing) {    return  }  var entry = me._buffer.shift()  if (!entry) {    if (me._needDrain) {      me.emit("drain")    }    return  }  if (entry.ready === false) {    // console.error("-- entry is not ready", entry)    me._buffer.unshift(entry)    entry.on("ready", function () {      // console.error("-- -- ready!", entry)      me._process()    })    return  }  me._processing = true  if (entry === eof) {    // need 2 ending null blocks.    me.emit("data", eof)    me.emit("data", eof)    me.emit("end")    me.emit("close")    return  }  // Change the path to be relative to the root dir that was  // added to the tarball.  //  // XXX This should be more like how -C works, so you can  // explicitly set a root dir, and also explicitly set a pathname  // in the tarball to use.  That way we can skip a lot of extra  // work when resolving symlinks for bundled dependencies in npm.  var root = path.dirname((entry.root || entry).path);  if (me._global && me._global.fromBase && entry.root && entry.root.path) {    // user set 'fromBase: true' indicating tar root should be directory itself    root = entry.root.path;  }  var wprops = {}  Object.keys(entry.props || {}).forEach(function (k) {    wprops[k] = entry.props[k]  })  if (me._noProprietary) wprops.noProprietary = true  wprops.path = path.relative(root, entry.path || '')  // actually not a matter of opinion or taste.  if (process.platform === "win32") {    wprops.path = wprops.path.replace(/\\/g, "/")  }  if (!wprops.type)    wprops.type = 'Directory'  switch (wprops.type) {    // sockets not supported    case "Socket":      return    case "Directory":      wprops.path += "/"      wprops.size = 0      break    case "Link":      var lp = path.resolve(path.dirname(entry.path), entry.linkpath)      wprops.linkpath = path.relative(root, lp) || "."      wprops.size = 0      break    case "SymbolicLink":      var lp = path.resolve(path.dirname(entry.path), entry.linkpath)      wprops.linkpath = path.relative(path.dirname(entry.path), lp) || "."      wprops.size = 0      break  }  // console.error("-- new writer", wprops)  // if (!wprops.type) {  //   // console.error("-- no type?", entry.constructor.name, entry)  // }  // console.error("-- -- set current to new writer", wprops.path)  var writer = me._currentEntry = EntryWriter(wprops)  writer.parent = me  // writer.on("end", function () {  //   // console.error("-- -- writer end", writer.path)  // })  writer.on("data", function (c) {    me.emit("data", c)  })  writer.on("header", function () {    Buffer.prototype.toJSON = function () {      return this.toString().split(/\0/).join(".")    }    // console.error("-- -- writer header %j", writer.props)    if (writer.props.size === 0) nextEntry()  })  writer.on("close", nextEntry)  var ended = false  function nextEntry () {    if (ended) return    ended = true    // console.error("-- -- writer close", writer.path)    // console.error("-- -- set current to null", wprops.path)    me._currentEntry = null    me._processing = false    me._process()  }  writer.on("error", function (er) {    // console.error("-- -- writer error", writer.path)    me.emit("error", er)  })  // if it's the root, then there's no need to add its entries,  // or data, since they'll be added directly.  if (entry === me._pipeRoot) {    // console.error("-- is the root, don't auto-add")    writer.add = null  }  entry.pipe(writer)}Pack.prototype.destroy = function () {}Pack.prototype.write = function () {}
 |