Comparing version 0.10.1 to 0.11.0-alpha
@@ -8,7 +8,9 @@ /** | ||
*/ | ||
var fs = require('fs'); | ||
var inherits = require('util').inherits; | ||
var Transform = require('readable-stream').Transform; | ||
var async = require('async'); | ||
var util = require('../../util'); | ||
var Queue = require('./queue'); | ||
@@ -22,12 +24,14 @@ var Archiver = module.exports = function(options) { | ||
this._moduleOutputPiped = false; | ||
this._entries = []; | ||
this._module = false; | ||
this._pointer = 0; | ||
this._files = []; | ||
this._module = false; | ||
this._queue = new Queue(); | ||
this._queue.on('error', this._onQueueError.bind(this)); | ||
this._queue.on('entry', this._onQueueEntry.bind(this)); | ||
this._queue.once('end', this._onQueueEnd.bind(this)); | ||
this._queue = async.queue(this._onQueueTask.bind(this), 1); | ||
this._queue.drain = this._onQueueDrain.bind(this); | ||
this._state = { | ||
finalize: false, | ||
finalized: false, | ||
modulePiped: false | ||
}; | ||
}; | ||
@@ -37,2 +41,35 @@ | ||
Archiver.prototype._append = function(filepath, data) { | ||
data = data || {}; | ||
if (!data.name) { | ||
data.name = filepath; | ||
} | ||
data.sourcePath = filepath; | ||
this._queue.push({ | ||
data: data, | ||
source: null, | ||
deferredStat: true, | ||
filepath: filepath | ||
}); | ||
}; | ||
Archiver.prototype._moduleAppend = function(source, data, callback) { | ||
this._module.append(source, data, callback); | ||
}; | ||
Archiver.prototype._moduleFinalize = function() { | ||
this._state.finalized = true; | ||
if (typeof this._module.finalize === 'function') { | ||
this._module.finalize(); | ||
} else if (typeof this._module.end === 'function') { | ||
this._module.end(); | ||
} else { | ||
this.emit('error', new Error('format module missing finalize and end method')); | ||
} | ||
}; | ||
Archiver.prototype._moduleSupports = function(key) { | ||
@@ -46,3 +83,4 @@ this._module.supports = util.defaults(this._module.supports, { | ||
Archiver.prototype._normalizeFileData = function(data) { | ||
Archiver.prototype._normalizeEntryData = function(data, stats) { | ||
stats = stats || false; | ||
data = util.defaults(data, { | ||
@@ -71,2 +109,4 @@ type: 'file', | ||
data.mode &= 0777; | ||
} else if (stats) { | ||
data.mode = stats.mode & 0777; | ||
} else { | ||
@@ -76,4 +116,10 @@ data.mode = isDir ? 0755 : 0644; | ||
if (stats && data.date === null) { | ||
data.date = stats.mtime; | ||
} | ||
data.date = util.dateify(data.date); | ||
data._stats = stats; | ||
return data; | ||
@@ -86,31 +132,66 @@ }; | ||
Archiver.prototype._onQueueEnd = function() { | ||
if (typeof this._module.finalize === 'function') { | ||
this._module.finalize(); | ||
} else if (typeof this._module.end === 'function') { | ||
this._module.end(); | ||
} else { | ||
this.emit('error', new Error('format module missing finalize and end method')); | ||
Archiver.prototype._onQueueDrain = function() { | ||
if (this._state.finalize && !this._state.finalized && this._queue.idle()) { | ||
this._moduleFinalize(); | ||
} | ||
}; | ||
Archiver.prototype._onQueueEntry = function(entry) { | ||
var nextCallback = function(err, file) { | ||
Archiver.prototype._onQueueTask = function(task, callback) { | ||
var afterAppend = function(err, entry) { | ||
if (err) { | ||
this.emit('error', err); | ||
callback(); | ||
return; | ||
} | ||
file = file || entry.data; | ||
entry = entry || task.data; | ||
this.emit('entry', file); | ||
this._files.push(file); | ||
this._queue.next(); | ||
this.emit('entry', entry); | ||
this._entries.push(entry); | ||
callback(); | ||
}.bind(this); | ||
this._module.append(entry.source, entry.data, nextCallback); | ||
var afterStat = function(err, stats) { | ||
if (err) { | ||
this.emit('error', err); | ||
callback(); | ||
return; | ||
} | ||
task = this._updateQueueTaskWithStats(task, stats); | ||
if (task.source !== null) { | ||
this._moduleAppend(task.source, task.data, afterAppend); | ||
} else { | ||
this.emit('error', new Error('unsupported entry: ' + task.filepath)); | ||
callback(); | ||
return; | ||
} | ||
}.bind(this); | ||
if (task.deferredStat) { | ||
fs.stat(task.filepath, afterStat); | ||
} else { | ||
this._moduleAppend(task.source, task.data, afterAppend); | ||
} | ||
}; | ||
Archiver.prototype._onQueueError = function(err) { | ||
this.emit('error', err); | ||
Archiver.prototype._updateQueueTaskWithStats = function(task, stats) { | ||
if (stats.isFile()) { | ||
task.data.type = 'file'; | ||
task.data.sourceType = 'stream'; | ||
task.source = util.lazyReadStream(task.filepath); | ||
} else if (stats.isDirectory() && this._moduleSupports('directory')) { | ||
task.data.name = util.trailingSlashIt(task.data.name); | ||
task.data.type = 'directory'; | ||
task.data.sourcePath = util.trailingSlashIt(task.filepath); | ||
task.data.sourceType = 'buffer'; | ||
task.source = new Buffer(0); | ||
} else { | ||
return task; | ||
} | ||
task.data = this._normalizeEntryData(task.data, stats); | ||
return task; | ||
}; | ||
@@ -122,3 +203,3 @@ | ||
this._moduleOutputPiped = true; | ||
this._state.modulePiped = true; | ||
}; | ||
@@ -139,4 +220,9 @@ | ||
Archiver.prototype.append = function(source, data) { | ||
data = this._normalizeFileData(data); | ||
if (this._state.finalize) { | ||
this.emit('error', new Error('unable to append after calling finalize.')); | ||
return this; | ||
} | ||
data = this._normalizeEntryData(data); | ||
if (typeof data.name !== 'string' || data.name.length === 0) { | ||
@@ -148,4 +234,4 @@ this.emit('error', new Error('entry name must be a non-empty string value')); | ||
if (data.type === 'directory' && !this._moduleSupports('directory')) { | ||
this.emit('error', new Error('entries of "' + data.type + '" type not currently supported by this module')); | ||
return; | ||
this.emit('error', new Error('entries of "directory" type not currently supported by this module')); | ||
return this; | ||
} | ||
@@ -164,3 +250,3 @@ | ||
this._queue.add({ | ||
this._queue.push({ | ||
data: data, | ||
@@ -174,2 +260,7 @@ source: source | ||
Archiver.prototype.bulk = function(mappings) { | ||
if (this._state.finalize) { | ||
this.emit('error', new Error('unable to append after calling finalize.')); | ||
return this; | ||
} | ||
if (!Array.isArray(mappings)) { | ||
@@ -180,3 +271,3 @@ mappings = [mappings]; | ||
var self = this; | ||
var files = util.normalizeFilesArray(mappings); | ||
var files = util.file.normalizeFilesArray(mappings); | ||
@@ -195,32 +286,4 @@ files.forEach(function(file){ | ||
var stat = util.stat(filepath); | ||
var source; | ||
if (!stat) { | ||
return; | ||
} | ||
data.name = util.sanitizePath(name); | ||
data.sourcePath = filepath; | ||
if (stat.isFile()) { | ||
data.type = 'file'; | ||
data.sourceType = 'stream'; | ||
source = util.lazyReadStream(filepath); | ||
} else if (stat.isDirectory() && self._moduleSupports('directory')) { | ||
data.name = util.trailingSlashIt(data.name); | ||
data.type = 'directory'; | ||
data.sourcePath = util.trailingSlashIt(data.sourcePath); | ||
data.sourceType = 'buffer'; | ||
source = new Buffer(0); | ||
} else { | ||
return; | ||
} | ||
self._queue.add({ | ||
data: data, | ||
source: source | ||
}); | ||
data.name = name; | ||
self._append(filepath, data); | ||
}); | ||
@@ -233,3 +296,6 @@ }); | ||
Archiver.prototype.file = function(filepath, data) { | ||
data = this._normalizeFileData(data); | ||
if (this._state.finalize) { | ||
this.emit('error', new Error('unable to append after calling finalize.')); | ||
return this; | ||
} | ||
@@ -241,24 +307,14 @@ if (typeof filepath !== 'string' || filepath.length === 0) { | ||
if (util.file.isFile(filepath)) { | ||
if (typeof data.name !== 'string' || data.name.length === 0) { | ||
data.name = util.sanitizePath(filepath); | ||
} | ||
this._append(filepath, data); | ||
data.sourcePath = filepath; | ||
data.sourceType = 'stream'; | ||
this._queue.add({ | ||
data: data, | ||
source: util.lazyReadStream(filepath) | ||
}); | ||
} else { | ||
this.emit('error', new Error('invalid file: ' + filepath)); | ||
} | ||
return this; | ||
}; | ||
Archiver.prototype.finalize = function(callback) { | ||
this._queue.close(); | ||
Archiver.prototype.finalize = function() { | ||
this._state.finalize = true; | ||
if (this._queue.idle()) { | ||
this._moduleFinalize(); | ||
} | ||
return this; | ||
@@ -268,3 +324,3 @@ }; | ||
Archiver.prototype.setModule = function(module) { | ||
if (this._moduleOutputPiped) { | ||
if (this._state.modulePiped) { | ||
this.emit('error', new Error('format module already set')); | ||
@@ -271,0 +327,0 @@ return; |
@@ -57,2 +57,10 @@ /** | ||
append(null, source); | ||
} else if (data.sourceType === 'stream' && data._stats) { | ||
data.size = data._stats.size; | ||
var entry = self.engine.entry(data, function(err) { | ||
callback(err, data); | ||
}); | ||
source.pipe(entry); | ||
} else if (data.sourceType === 'stream') { | ||
@@ -59,0 +67,0 @@ util.collectStream(source, append); |
@@ -18,3 +18,3 @@ /** | ||
util.lazystream = require('lazystream'); | ||
util.file = require('file-utils'); | ||
util.file = require('./file'); | ||
@@ -77,82 +77,2 @@ util.collectStream = function(source, callback) { | ||
// reusing bits of grunt's multi-task source normalization | ||
util.normalizeFilesArray = function(data) { | ||
var files = []; | ||
data.forEach(function(obj) { | ||
var prop; | ||
if ('src' in obj || 'dest' in obj) { | ||
files.push(obj); | ||
} | ||
}); | ||
if (files.length === 0) { | ||
return []; | ||
} | ||
files = util._(files).chain().forEach(function(obj) { | ||
if (!('src' in obj) || !obj.src) { return; } | ||
// Normalize .src properties to flattened array. | ||
if (Array.isArray(obj.src)) { | ||
obj.src = util._.flatten(obj.src); | ||
} else { | ||
obj.src = [obj.src]; | ||
} | ||
}).map(function(obj) { | ||
// Build options object, removing unwanted properties. | ||
var expandOptions = util._.extend({}, obj); | ||
delete expandOptions.src; | ||
delete expandOptions.dest; | ||
// Expand file mappings. | ||
if (obj.expand) { | ||
return util.file.expandMapping(obj.src, obj.dest, expandOptions).map(function(mapObj) { | ||
// Copy obj properties to result. | ||
var result = util._.extend({}, obj); | ||
// Make a clone of the orig obj available. | ||
result.orig = util._.extend({}, obj); | ||
// Set .src and .dest, processing both as templates. | ||
result.src = mapObj.src; | ||
result.dest = mapObj.dest; | ||
// Remove unwanted properties. | ||
['expand', 'cwd', 'flatten', 'rename', 'ext'].forEach(function(prop) { | ||
delete result[prop]; | ||
}); | ||
return result; | ||
}); | ||
} | ||
// Copy obj properties to result, adding an .orig property. | ||
var result = util._.extend({}, obj); | ||
// Make a clone of the orig obj available. | ||
result.orig = util._.extend({}, obj); | ||
if ('src' in result) { | ||
// Expose an expand-on-demand getter method as .src. | ||
Object.defineProperty(result, 'src', { | ||
enumerable: true, | ||
get: function fn() { | ||
var src; | ||
if (!('result' in fn)) { | ||
src = obj.src; | ||
// If src is an array, flatten it. Otherwise, make it into an array. | ||
src = Array.isArray(src) ? util._.flatten(src) : [src]; | ||
// Expand src files, memoizing result. | ||
fn.result = util.file.expand(expandOptions, src); | ||
} | ||
return fn.result; | ||
} | ||
}); | ||
} | ||
if ('dest' in result) { | ||
result.dest = obj.dest; | ||
} | ||
return result; | ||
}).flatten().value(); | ||
return files; | ||
}; | ||
util.normalizeInputSource = function(source) { | ||
@@ -178,12 +98,2 @@ if (source === null) { | ||
util.stat = function() { | ||
var filepath = path.join.apply(path, arguments); | ||
if (!util.file.exists(filepath)) { | ||
return false; | ||
} | ||
return fs.statSync(filepath); | ||
}; | ||
util.trailingSlashIt = function(str) { | ||
@@ -190,0 +100,0 @@ return str.slice(-1) !== '/' ? str + '/' : str; |
{ | ||
"name": "archiver", | ||
"version": "0.10.1", | ||
"version": "0.11.0-alpha", | ||
"description": "a streaming interface for archive generation", | ||
@@ -36,13 +36,14 @@ "homepage": "https://github.com/ctalkington/node-archiver", | ||
"dependencies": { | ||
"async": "~0.9.0", | ||
"buffer-crc32": "~0.2.1", | ||
"glob": "~3.2.6", | ||
"lazystream": "~0.1.0", | ||
"lodash": "~2.4.1", | ||
"readable-stream": "~1.0.26", | ||
"tar-stream": "~0.4.0", | ||
"zip-stream": "~0.3.0", | ||
"lazystream": "~0.1.0", | ||
"file-utils": "~0.2.0", | ||
"lodash": "~2.4.1" | ||
"zip-stream": "~0.3.0" | ||
}, | ||
"devDependencies": { | ||
"chai": "~1.9.1", | ||
"mocha": "~1.18.2", | ||
"mocha": "~1.20.1", | ||
"rimraf": "~2.2.8", | ||
@@ -49,0 +50,0 @@ "mkdirp": "~0.5.0", |
@@ -1,2 +0,2 @@ | ||
# Archiver v0.10.1 [![Build Status](https://travis-ci.org/ctalkington/node-archiver.svg?branch=master)](https://travis-ci.org/ctalkington/node-archiver) | ||
# Archiver v0.11.0-alpha [![Build Status](https://travis-ci.org/ctalkington/node-archiver.svg?branch=master)](https://travis-ci.org/ctalkington/node-archiver) | ||
@@ -3,0 +3,0 @@ a streaming interface for archive generation |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
30224
700
8
3
+ Addedasync@~0.9.0
+ Addedglob@~3.2.6
+ Addedasync@0.9.2(transitive)
+ Addedglob@3.2.11(transitive)
+ Addedlru-cache@2.7.3(transitive)
+ Addedminimatch@0.3.0(transitive)
+ Addedsigmund@1.0.1(transitive)
- Removedfile-utils@~0.2.0
- Removedbalanced-match@1.0.2(transitive)
- Removedbrace-expansion@1.1.11(transitive)
- Removedconcat-map@0.0.1(transitive)
- Removedfile-utils@0.2.2(transitive)
- Removedfindup-sync@0.2.1(transitive)
- Removedfs.realpath@1.0.0(transitive)
- Removedglob@4.3.54.5.37.2.3(transitive)
- Removediconv-lite@0.4.24(transitive)
- Removedinflight@1.0.6(transitive)
- Removedisbinaryfile@2.0.4(transitive)
- Removedminimatch@2.0.103.1.2(transitive)
- Removedpath-is-absolute@1.0.1(transitive)
- Removedrimraf@2.7.1(transitive)
- Removedsafer-buffer@2.1.2(transitive)