UNPKG

@testim/testim-cli

Version:

Command line interface for running Testing on you CI

195 lines (155 loc) 4.29 kB
var util = require('util') var eos = require('end-of-stream') var headers = require('./headers') var Readable = require('readable-stream').Readable var Writable = require('readable-stream').Writable var PassThrough = require('readable-stream').PassThrough var END_OF_TAR = new Buffer(1024) END_OF_TAR.fill(0) var noop = function() {} var overflow = function(self, size) { size &= 511 if (size) self.push(END_OF_TAR.slice(0, 512 - size)) } var Sink = function(to) { Writable.call(this) this.written = 0 this._to = to this._destroyed = false } util.inherits(Sink, Writable) Sink.prototype._write = function(data, enc, cb) { this.written += data.length if (this._to.push(data)) return cb() this._to._drain = cb } Sink.prototype.destroy = function() { if (this._destroyed) return this._destroyed = true this.emit('close') } var Void = function() { Writable.call(this) this._destroyed = false } util.inherits(Void, Writable) Void.prototype._write = function(data, enc, cb) { cb(new Error('No body allowed for this entry')) } Void.prototype.destroy = function() { if (this._destroyed) return this._destroyed = true this.emit('close') } var Pack = function(opts) { if (!(this instanceof Pack)) return new Pack(opts) Readable.call(this, opts) this._drain = noop this._finalized = false this._finalizing = false this._destroyed = false this._stream = null } util.inherits(Pack, Readable) Pack.prototype.entry = function(header, buffer, callback) { if (this._stream) throw new Error('already piping an entry') if (this._finalized || this._destroyed) return if (typeof buffer === 'function') { callback = buffer buffer = null } if (!callback) callback = noop var self = this if (!header.size) header.size = 0 if (!header.type) header.type = 'file' if (!header.mode) header.mode = header.type === 'directory' ? 0755 : 0644 if (!header.uid) header.uid = 0 if (!header.gid) header.gid = 0 if (!header.mtime) header.mtime = new Date() if (typeof buffer === 'string') buffer = new Buffer(buffer) if (Buffer.isBuffer(buffer)) { header.size = buffer.length this._encode(header) this.push(buffer) overflow(self, header.size) process.nextTick(callback) return new Void() } if (header.type !== 'file' && header.type !== 'contigious-file') { this._encode(header) process.nextTick(callback) return new Void() } var sink = new Sink(this) this._encode(header) this._stream = sink eos(sink, function(err) { self._stream = null if (err) { // stream was closed self.destroy() return callback(err) } if (sink.written !== header.size) { // corrupting tar self.destroy() return callback(new Error('size mismatch')) } overflow(self, header.size) if (self._finalizing) self.finalize() callback() }) return sink } Pack.prototype.finalize = function() { if (this._stream) { this._finalizing = true return } if (this._finalized) return this._finalized = true this.push(END_OF_TAR) this.push(null) } Pack.prototype.destroy = function(err) { if (this._destroyed) return this._destroyed = true if (err) this.emit('error', err) this.emit('close') if (this._stream && this._stream.destroy) this._stream.destroy() } Pack.prototype._encode = function(header) { var buf = headers.encode(header) if (buf) this.push(buf) else this._encodePax(header) } Pack.prototype._encodePax = function(header) { var paxHeader = headers.encodePax({ name: header.name, linkname: header.linkname }) var newHeader = { name: 'PaxHeader', mode: header.mode, uid: header.uid, gid: header.gid, size: paxHeader.length, mtime: header.mtime, type: 'pax-header', linkname: header.linkname && 'PaxHeader', uname: header.uname, gname: header.gname, devmajor: header.devmajor, devminor: header.devminor } this.push(headers.encode(newHeader)) this.push(paxHeader) overflow(this, paxHeader.length) newHeader.size = header.size newHeader.type = header.type this.push(headers.encode(newHeader)) } Pack.prototype._read = function(n) { var drain = this._drain this._drain = noop drain() } module.exports = Pack