Comparing version
@@ -36,4 +36,13 @@ /** | ||
Archiver.prototype._moduleSupports = function(key) { | ||
this._module.supports = util.defaults(this._module.supports, { | ||
directory: false | ||
}); | ||
return this._module.supports[key]; | ||
}; | ||
Archiver.prototype._normalizeFileData = function(data) { | ||
data = util.defaults(data, { | ||
type: 'file', | ||
name: null, | ||
@@ -44,4 +53,13 @@ date: null, | ||
var isDir = data.type === 'directory'; | ||
if (data.name) { | ||
data.name = util.sanitizePath(data.name); | ||
if (data.name.slice(-1) === '/') { | ||
isDir = true; | ||
data.type = 'directory'; | ||
} else if (isDir) { | ||
data.name += '/'; | ||
} | ||
} | ||
@@ -55,3 +73,5 @@ | ||
Archiver.prototype._normalizeSource = function(source) { | ||
if (typeof source === 'string') { | ||
if (source === null) { | ||
return new Buffer(0); | ||
} else if (typeof source === 'string') { | ||
return new Buffer(source); | ||
@@ -126,6 +146,11 @@ } else if (util.isStream(source) && !source._readableState) { | ||
if (typeof data.name !== 'string' || data.name.length === 0) { | ||
this.emit('error', new Error('filename must be a non-empty string value')); | ||
this.emit('error', new Error('entry name must be a non-empty string value')); | ||
return this; | ||
} | ||
if (data.type === 'directory' && !this._moduleSupports('directory')) { | ||
this.emit('error', new Error('entries of "' + data.type + '" type not currently supported by this module')); | ||
return; | ||
} | ||
source = this._normalizeSource(source); | ||
@@ -161,17 +186,35 @@ | ||
var fileData = file.data || {}; | ||
var src = file.src.filter(function(f) { | ||
return util.file.isFile(f); | ||
}); | ||
src.forEach(function(filepath) { | ||
file.src.forEach(function(filepath) { | ||
var data = util._.extend({}, fileData); | ||
var name = isExpandedPair ? file.dest : util.unixifyPath(file.dest || '', filepath); | ||
var data = util._.extend({}, fileData); | ||
var stat = util.stat(filepath); | ||
var source; | ||
if (!stat) { | ||
return; | ||
} | ||
data.name = util.sanitizePath(name); | ||
data.sourcePath = filepath; | ||
data.sourceType = 'stream'; | ||
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: util.lazyReadStream(filepath) | ||
source: source | ||
}); | ||
@@ -178,0 +221,0 @@ }); |
@@ -11,2 +11,3 @@ /** | ||
var crc32 = require('buffer-crc32'); | ||
var util = require('../../util'); | ||
@@ -19,2 +20,6 @@ | ||
this.supports = { | ||
directory: true | ||
}; | ||
this.files = []; | ||
@@ -51,3 +56,3 @@ }; | ||
if (file.size > 0) { | ||
file.crc32 = util.crc32(sourceBuffer).digest(); | ||
file.crc32 = crc32.unsigned(sourceBuffer); | ||
} | ||
@@ -54,0 +59,0 @@ |
@@ -33,3 +33,3 @@ /** | ||
{field: 'checksum', len: 8, type: 'number'}, | ||
{field: 'type', len: 1, type: 'string', def: '0'}, | ||
{field: 'type', len: 1, valKey: '_type', type: 'string', def: '0'}, | ||
{field: 'linkName', len: 100, type: 'string'}, | ||
@@ -60,3 +60,4 @@ {field: 'ustar', len: 6, type: 'string', def: 'ustar'}, | ||
fallback = (value.type === 'number') ? 0 : ''; | ||
val = data[value.field] || value.def || fallback; | ||
val = value.valKey ? data[value.valKey] : data[value.field]; | ||
val = val || value.def || fallback; | ||
@@ -121,3 +122,2 @@ if (value.field === 'checksum') { | ||
data.name = util.sanitizePath(data.name); | ||
data.mode = typeof data.mode === 'number' ? data.mode & 0777 : DEFAULT_FILE_MODE; | ||
@@ -127,2 +127,9 @@ data.uid = typeof data.uid === 'number' ? data.uid : 0; | ||
if (data.type && data.type === 'directory') { | ||
data._type = '5'; | ||
data.mode = typeof data.mode === 'number' ? data.mode & 0777 : DEFAULT_DIR_MODE; | ||
} else { | ||
data.mode = typeof data.mode === 'number' ? data.mode & 0777 : DEFAULT_FILE_MODE; | ||
} | ||
if (typeof data.mtime !== 'number') { | ||
@@ -129,0 +136,0 @@ data.date = util.dateify(data.date); |
@@ -28,2 +28,6 @@ /** | ||
this.supports = { | ||
directory: true | ||
}; | ||
this.compressor = false; | ||
@@ -61,7 +65,6 @@ this.offset = 0; | ||
var file = data; | ||
file.offset = self.offset; | ||
data.offset = self.offset; | ||
if (file.name.length > 255) { | ||
callback(new Error('Filename "' + file.name + '" is too long even with prefix support [' + file.name.length + '/255]')); | ||
if (data.name.length > 255) { | ||
callback(new Error('entry name "' + data.name + '" is too long even with prefix support [' + data.name.length + '/255]')); | ||
return; | ||
@@ -77,9 +80,9 @@ } | ||
sourceBuffer = sourceBuffer || false; | ||
file.size = sourceBuffer.length || 0; | ||
data.size = sourceBuffer.length || 0; | ||
var extraBytes = self.recordSize - (file.size % self.recordSize || self.recordSize); | ||
var extraBytes = self.recordSize - (data.size % self.recordSize || self.recordSize); | ||
self.write(headers.encode('file', file)); | ||
self.write(headers.encode('file', data)); | ||
if (file.size > 0) { | ||
if (data.size > 0) { | ||
self.write(sourceBuffer); | ||
@@ -89,10 +92,10 @@ } | ||
self.write(util.cleanBuffer(extraBytes)); | ||
self.files.push(file); | ||
self.files.push(data); | ||
callback(null, file); | ||
callback(null, data); | ||
} | ||
if (file.sourceType === 'buffer') { | ||
if (data.sourceType === 'buffer') { | ||
onend(null, source); | ||
} else if (file.sourceType === 'stream') { | ||
} else if (data.sourceType === 'stream') { | ||
util.collectStream(source, onend); | ||
@@ -99,0 +102,0 @@ } |
@@ -18,2 +18,6 @@ /** | ||
this.supports = { | ||
directory: true | ||
}; | ||
this.engine = new engine(options); | ||
@@ -20,0 +24,0 @@ }; |
@@ -11,3 +11,3 @@ /** | ||
var util = require('./'); | ||
var crc32 = require('buffer-crc32'); | ||
@@ -17,4 +17,5 @@ function ChecksumStream(options) { | ||
this.checksum = util.crc32(); | ||
this.digest = null; | ||
this.checksum = new Buffer(4); | ||
this.checksum.writeInt32BE(0, 0); | ||
this.digest = 0; | ||
@@ -28,3 +29,3 @@ this.rawSize = 0; | ||
if (chunk) { | ||
this.checksum.update(chunk); | ||
this.checksum = crc32(chunk, this.checksum); | ||
this.rawSize += chunk.length; | ||
@@ -37,3 +38,3 @@ } | ||
ChecksumStream.prototype._flush = function(callback) { | ||
this.digest = this.checksum.digest(); | ||
this.digest = crc32.unsigned(0, this.checksum); | ||
@@ -40,0 +41,0 @@ callback(); |
@@ -15,3 +15,2 @@ /** | ||
util._ = require('lodash'); | ||
util.crc32 = require('./crc32'); | ||
util.lazystream = require('lazystream'); | ||
@@ -274,2 +273,16 @@ util.file = require('file-utils'); | ||
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) { | ||
return str.slice(-1) !== '/' ? str + '/' : str; | ||
}; | ||
util.unixifyPath = function() { | ||
@@ -276,0 +289,0 @@ var filepath = path.join.apply(path, arguments); |
{ | ||
"name": "archiver", | ||
"version": "0.7.1", | ||
"version": "0.8.0", | ||
"description": "Creates Archives (ZIP) via Node Streams.", | ||
@@ -32,4 +32,5 @@ "homepage": "https://github.com/ctalkington/node-archiver", | ||
"dependencies": { | ||
"buffer-crc32": "~0.2.1", | ||
"readable-stream": "~1.0.24", | ||
"zip-stream": "~0.2.0", | ||
"zip-stream": "~0.3.0", | ||
"lazystream": "~0.1.0", | ||
@@ -36,0 +37,0 @@ "file-utils": "~0.1.5", |
@@ -1,2 +0,2 @@ | ||
# Archiver v0.7.1 [](https://travis-ci.org/ctalkington/node-archiver) | ||
# Archiver v0.8.0 [](https://travis-ci.org/ctalkington/node-archiver) | ||
@@ -27,2 +27,4 @@ Creates Archives (Zip, Tar) via Node Streams. | ||
Inherits [Transform Stream](http://nodejs.org/api/stream.html#stream_class_stream_transform) methods. | ||
#### append(input, data) | ||
@@ -42,7 +44,7 @@ | ||
Appends multiple files from passed array of src-dest file mappings, based on [Grunt's "Files Array" format](http://gruntjs.com/configuring-tasks#files-array-format). A lazystream wrapper is used to prevent issues with open file limits. | ||
Appends multiple entries from passed array of src-dest mappings, based on [Grunt's "Files Array" format](http://gruntjs.com/configuring-tasks#files-array-format). A lazystream wrapper is used to prevent issues with open file limits. | ||
[Globbing patterns](http://gruntjs.com/configuring-tasks#globbing-patterns) and [multiple properties](http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically) are supported through use of the [file-utils](https://github.com/SBoudrias/file-utils) package, based on Grunt's file utilities. Please note that multiple src files to single dest file (ie concat) is not supported. | ||
The `data` property can be set (per src-dest mapping) to define file data for matched files. | ||
The `data` property can be set (per src-dest mapping) to define data for matched entries. | ||
@@ -74,7 +76,7 @@ ```js | ||
Each instance is a node `Transform` stream and inherits all its events. Events listed here are custom. | ||
Inherits [Transform Stream](http://nodejs.org/api/stream.html#stream_class_stream_transform) events. | ||
#### entry | ||
Fired when the input has been received, processed, and emitted. Passes file data as first argument. | ||
Fired when the input has been received, processed, and emitted. Passes entry data as first argument. | ||
@@ -91,7 +93,7 @@ ## Zip | ||
If true, forces the file date and time to UTC. Helps with testing across timezones. | ||
If true, forces the entry date to UTC. Helps with testing across timezones. | ||
#### store `boolean` | ||
If true, all file contents will be archived without compression by default. | ||
If true, all entry contents will be archived without compression by default. | ||
@@ -102,23 +104,23 @@ #### zlib `object` | ||
### File Data | ||
### Entry Data | ||
#### name `string` `required` | ||
Sets the file name including internal path. | ||
Sets the entry name including internal path. | ||
#### date `string|Date` | ||
Sets the file date. This can be any valid date string or instance. Defaults to current time in locale. | ||
Sets the entry date. This can be any valid date string or instance. Defaults to current time in locale. | ||
#### store `boolean` | ||
If true, file contents will be archived without compression. | ||
If true, entry contents will be archived without compression. | ||
#### comment `string` | ||
Sets the file comment. | ||
Sets the entry comment. | ||
#### mode `number` | ||
Sets the file permissions. (experimental) | ||
Sets the entry permissions. (experimental) | ||
@@ -145,15 +147,15 @@ ## Tar | ||
### File Data | ||
### Entry Data | ||
#### name `string` `required` | ||
Sets the file name including internal path. | ||
Sets the entry name including internal path. | ||
#### date `string|Date` | ||
Sets the file date. This can be any valid date string or instance. Defaults to current time in locale. | ||
Sets the entry date. This can be any valid date string or instance. Defaults to current time in locale. | ||
#### mode `number` | ||
Sets the file permissions. Defaults to 0664. | ||
Sets the entry permissions. Defaults to octal 0664. | ||
@@ -160,0 +162,0 @@ ## Things of Interest |
@@ -107,11 +107,14 @@ /*global before,describe,it */ | ||
it('should append multiple files', function() { | ||
it('should append multiple entries', function() { | ||
assert.isArray(actual); | ||
assert.lengthOf(actual, 3); | ||
assert.propertyVal(actual[0], 'name', 'directory/level0.txt'); | ||
assert.propertyVal(actual[1], 'name', 'directory/subdir/level1.txt'); | ||
assert.propertyVal(actual[2], 'name', 'directory/subdir/subsub/level2.txt'); | ||
assert.lengthOf(actual, 6); | ||
assert.propertyVal(actual[0], 'name', 'directory/'); | ||
assert.propertyVal(actual[1], 'name', 'directory/level0.txt'); | ||
assert.propertyVal(actual[2], 'name', 'directory/subdir/'); | ||
assert.propertyVal(actual[3], 'name', 'directory/subdir/level1.txt'); | ||
assert.propertyVal(actual[4], 'name', 'directory/subdir/subsub/'); | ||
assert.propertyVal(actual[5], 'name', 'directory/subdir/subsub/level2.txt'); | ||
}); | ||
it('should support passing data property', function() { | ||
it('should support passing data properties', function() { | ||
assert.propertyVal(actual[0], 'prop', 'value'); | ||
@@ -215,2 +218,18 @@ }); | ||
}); | ||
it("should support directory entries", function(done) { | ||
var archive = archiver('tar'); | ||
var testStream = new WriteHashStream('tmp/type-directory.tar'); | ||
testStream.on('close', function() { | ||
assert.equal(testStream.digest, '4e2986ce5df27dbfb36c8cc05825c66906af084d'); | ||
done(); | ||
}); | ||
archive.pipe(testStream); | ||
archive | ||
.append(null, { name: 'directory/', date: testDate }) | ||
.finalize(); | ||
}); | ||
}); | ||
@@ -217,0 +236,0 @@ |
@@ -12,3 +12,2 @@ /*global describe,it */ | ||
var ChecksumStream = require('../lib/util/ChecksumStream'); | ||
var crc32 = require('../lib/util/crc32'); | ||
var utils = require('../lib/util'); | ||
@@ -33,3 +32,3 @@ | ||
checksum.on('end', function() { | ||
assert.equal(checksum.digest, -270675091); | ||
assert.equal(checksum.digest, 4024292205); | ||
@@ -59,30 +58,2 @@ done(); | ||
describe('crc32', function() { | ||
describe('crc32(data)', function() { | ||
it('should initialize CRC32 instance based on data', function() { | ||
var actual = crc32('testing checksum'); | ||
assert.equal(actual.crc, 323269802); | ||
}); | ||
}); | ||
describe('#update(data)', function() { | ||
it('should update CRC32 based on data', function() { | ||
var actual = crc32().update('testing checksum'); | ||
assert.equal(actual.crc, 323269802); | ||
}); | ||
}); | ||
describe('#digest()', function() { | ||
it('should return digest of CRC32', function() { | ||
var actual = crc32().update('testing checksum').digest(); | ||
assert.equal(actual, -323269803); | ||
}); | ||
}); | ||
}); | ||
describe('index', function() { | ||
@@ -191,2 +162,9 @@ | ||
describe('trailingSlashIt(str)', function() { | ||
it('should add trailing slash when missing', function() { | ||
assert.equal(utils.trailingSlashIt('this/path'), 'this/path/'); | ||
assert.equal(utils.trailingSlashIt('this/path/'), 'this/path/'); | ||
}); | ||
}); | ||
describe('unixifyPath(filepath)', function() { | ||
@@ -193,0 +171,0 @@ it('should unixify filepath', function() { |
Sorry, the diff of this file is not supported yet
169
1.2%75816
-1.94%6
20%41
-2.38%1512
-2.01%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated