grunt-contrib-compress
Advanced tools
Comparing version 0.3.3 to 0.4.0-rc7
{ | ||
"name": "grunt-contrib-compress", | ||
"description": "Compress files and folders.", | ||
"version": "0.3.3", | ||
"version": "0.4.0rc7", | ||
"homepage": "https://github.com/gruntjs/grunt-contrib-compress", | ||
@@ -23,5 +23,5 @@ "author": { | ||
], | ||
"main": "grunt.js", | ||
"main": "Gruntfile.js", | ||
"engines": { | ||
"node": ">= 0.6.3" | ||
"node": ">= 0.8.0" | ||
}, | ||
@@ -32,11 +32,12 @@ "scripts": { | ||
"dependencies": { | ||
"tar": "~0.1.13", | ||
"fstream": "~0.1.18", | ||
"archiver": "~0.1.0", | ||
"archiver": "~0.2.2", | ||
"rimraf": "~2.0.2", | ||
"grunt-lib-contrib": "~0.3.0" | ||
"grunt-lib-contrib": "~0.5.1" | ||
}, | ||
"devDependencies": { | ||
"grunt": "~0.3.15", | ||
"grunt-contrib-clean": "~0.3.0" | ||
"grunt-contrib-jshint": "0.1.1rc6", | ||
"grunt-contrib-nodeunit": "0.1.2rc6", | ||
"grunt-contrib-clean": "0.4.0rc6", | ||
"grunt-contrib-internal": "~0.1.1", | ||
"grunt": "0.4.0rc7" | ||
}, | ||
@@ -43,0 +44,0 @@ "keywords": [ |
102
README.md
@@ -5,76 +5,82 @@ # grunt-contrib-compress [![Build Status](https://secure.travis-ci.org/gruntjs/grunt-contrib-compress.png?branch=master)](http://travis-ci.org/gruntjs/grunt-contrib-compress) | ||
## Getting Started | ||
Install this grunt plugin next to your project's [grunt.js gruntfile][getting_started] with: `npm install grunt-contrib-compress` | ||
If you haven't used [grunt][] before, be sure to check out the [Getting Started][] guide, as it explains how to create a [gruntfile][Getting Started] as well as install and use grunt plugins. Once you're familiar with that process, install this plugin with this command: | ||
Then add this line to your project's `grunt.js` gruntfile: | ||
```javascript | ||
grunt.loadNpmTasks('grunt-contrib-compress'); | ||
```shell | ||
npm install grunt-contrib-compress --save-dev | ||
``` | ||
[grunt]: https://github.com/gruntjs/grunt | ||
[getting_started]: https://github.com/gruntjs/grunt/blob/master/docs/getting_started.md | ||
[grunt]: http://gruntjs.com/ | ||
[Getting Started]: https://github.com/gruntjs/grunt/blob/devel/docs/getting_started.md | ||
### Overview | ||
Inside your `grunt.js` file, add a section named `compress`. This section specifies the files to compress and the options passed to either [archiver](https://github.com/ctalkington/node-archiver) (for zip) or [tar](https://github.com/isaacs/node-tar) (for tar/tgz) or [zlib](http://nodejs.org/api/zlib.html#zlib_options) (for gzip). | ||
## Compress task | ||
_Run this task with the `grunt compress` command._ | ||
#### Parameters | ||
_This task is a [multi task][] so any targets, files and options should be specified according to the [multi task][] documentation._ | ||
[multi task]: https://github.com/gruntjs/grunt/wiki/Configuring-tasks | ||
##### files ```object``` | ||
This defines what files this task will compress and should contain key:value pairs. | ||
_Version `0.4.x` of this plugin is compatible with Grunt `0.4.x`. Version `0.3.x` of this plugin is compatible with Grunt `0.3.x`._ | ||
The key (destination) should be an unique filepath (supports [grunt.template](https://github.com/gruntjs/grunt/blob/master/docs/api_template.md)) and the value (source) should be a filepath or an array of filepaths (supports [minimatch](https://github.com/isaacs/minimatch)). | ||
Node Libraries Used: | ||
[archiver](https://github.com/ctalkington/node-archiver) (for zip/tar) | ||
[zlib](http://nodejs.org/api/zlib.html#zlib_options) (for gzip). | ||
##### options ```object``` | ||
### Options | ||
This controls how this task operates and should contain key:value pairs, see options below. | ||
#### archive | ||
Type: `String` | ||
#### Options | ||
This is used to define where to output the archive. Each target can only have one output file. | ||
##### mode ```string``` | ||
#### mode | ||
Type: `String` | ||
This is used to define which mode to use, currently supports gzip, tar, tgz (tar gzip) and zip. | ||
This is used to define which mode to use, currently supports `gzip`, `tar`, `tgz` (tar gzip) and `zip`. | ||
As of v0.3.0, this is now automatically detected per dest:src pair but can be overridden per target if desired. | ||
Automatically detected per dest:src pair, but can be overridden per target if desired. | ||
##### basePath ```string``` | ||
#### level (zip only) | ||
Type: `Integer` | ||
Default: 1 | ||
This option adjusts internal filenames to be relative to provided path, within the resulting archive file. | ||
Sets the level of archive compression. | ||
This has been automatically detected per dest:src pair for some time now but can be overridden per target if desired. | ||
*Currently, gzip compression related options are not supported due to deficiencies in node's zlib library.* | ||
##### flatten ```boolean``` | ||
### Usage Examples | ||
This option performs a flat copy that dumps all the files into the root of the destination file, overwriting files if they exist. | ||
```js | ||
compress: { | ||
main: { | ||
options: { | ||
archive: 'archive.zip' | ||
}, | ||
files: [ | ||
{src: ['path/*'], dest: 'internal_folder/', filter: 'isFile'}, // includes files in path | ||
{src: ['path/**'], dest: 'internal_folder2/'}, // includes files in path and its subdirs | ||
{expand: true, cwd: 'path/', src: ['**'], dest: 'internal_folder3/'}, // makes all src relative to cwd | ||
{flatten: true, src: ['path/**'], dest: 'internal_folder4/', filter: 'isFile'} // flattens results to a single level | ||
] | ||
} | ||
} | ||
``` | ||
##### level ```integer``` (zip only) | ||
This option sets the level of archive compression (defaults to 1). | ||
## Release History | ||
> Currently, gzip compression related options are not supported due to deficiencies in node's zlib library. | ||
* 2013-01-22 v0.4.0rc7 Updating grunt/gruntplugin dependencies to rc7. Changing in-development grunt/gruntplugin dependency versions from tilde version ranges to specific versions. | ||
* 2013-01-13 v0.4.0rc5 Updating to work with grunt v0.4.0rc5. Conversion to grunt v0.4 conventions. Replace basePath with cwd. | ||
* 2012-10-11 v0.3.2 Rename grunt-contrib-lib dep to grunt-lib-contrib. | ||
* 2012-10-08 v0.3.1 Replace zipstream package with archiver. | ||
* 2012-09-23 v0.3.0 General cleanup. Options no longer accepted from global config key. | ||
* 2012-09-17 v0.2.2 Test refactoring. No valid source check. Automatic mode detection. | ||
* 2012-09-09 v0.2.0 Refactored from grunt-contrib into individual repo. | ||
##### rootDir ```string``` | ||
--- | ||
This option allows the creation of a root folder to contain files within the resulting archive file. | ||
Task submitted by [Chris Talkington](http://christalkington.com/) | ||
#### Config Example | ||
``` javascript | ||
compress: { | ||
zip: { | ||
files: { | ||
"path/to/result.zip": "path/to/source/*", // includes files in dir | ||
"path/to/another.tar": "path/to/source/**", // includes files in dir and subdirs | ||
"path/to/final.tgz": ["path/to/sources/*.js", "path/to/more/*.js"], // include JS files in two diff dirs | ||
"path/to/single.gz": "path/to/source/single.js", // gzip a single file | ||
"path/to/project-<%= pkg.version %>.zip": "path/to/source/**" // variables in destination | ||
} | ||
} | ||
} | ||
``` | ||
-- | ||
*Task submitted by [Chris Talkington](https://github.com/ctalkington).* | ||
*This file was generated on Wed Jan 23 2013 10:29:21.* |
@@ -9,5 +9,5 @@ /* | ||
'use strict'; | ||
module.exports = function(grunt) { | ||
'use strict'; | ||
var fs = require('fs'); | ||
@@ -17,71 +17,132 @@ var path = require('path'); | ||
// TODO: ditch this when grunt v0.4 is released | ||
grunt.file.exists = grunt.file.exists || fs.existsSync || path.existsSync; | ||
grunt.registerMultiTask('compress', 'Compress files.', function() { | ||
var archiver = require('archiver'); | ||
var zlib = require('zlib'); | ||
// TODO: ditch this when grunt v0.4 is released | ||
grunt.util = grunt.util || grunt.utils; | ||
var kindOf = grunt.util.kindOf; | ||
var helpers = require('grunt-lib-contrib').init(grunt); | ||
var helpers = require('grunt-lib-contrib').init(grunt); | ||
var done = this.async(); | ||
grunt.registerMultiTask('compress', 'Compress files.', function() { | ||
var options = helpers.options(this, { | ||
var options = this.options({ | ||
archive: null, | ||
mode: null, | ||
basePath: false, | ||
flatten: false, | ||
level: 1, | ||
rootDir: false | ||
level: 1 | ||
}); | ||
// TODO: ditch this when grunt v0.4 is released | ||
this.files = this.files || helpers.normalizeMultiTaskFiles(this.data, this.target); | ||
var archiverOptions = options; | ||
var supportedModes = ['zip', 'tar', 'tgz', 'gzip']; | ||
var targetMode = options.mode; | ||
delete options.mode; | ||
var done = this.async(); | ||
var shouldGzipTar = false; | ||
if (grunt.util.kindOf(options.rootDir) === 'string' && options.rootDir.length >= 1) { | ||
options.rootDir = path.normalize(options.rootDir).split(path.sep)[0]; | ||
} else { | ||
options.rootDir = false; | ||
grunt.verbose.writeflags(options, 'Options'); | ||
if (kindOf(options.archive) !== 'string' || options.archive.length === 0) { | ||
grunt.fail.warn('Unable to compress; no valid archive file was specified.'); | ||
} | ||
grunt.verbose.writeflags(options, 'Options'); | ||
var archiveFile = options.archive; | ||
var archiveDir = path.dirname(archiveFile); | ||
var srcFiles; | ||
var destDir; | ||
var mode; | ||
var mode = options.mode || autoDetectMode(archiveFile); | ||
grunt.util.async.forEachSeries(this.files, function(file, next) { | ||
srcFiles = grunt.file.expandFiles(file.src); | ||
destDir = path.dirname(file.dest); | ||
if (mode === 'tgz') { | ||
shouldGzipTar = true; | ||
mode = 'tar'; | ||
} | ||
if (srcFiles.length === 0) { | ||
grunt.fail.warn('Unable to compress; no valid source files were found.'); | ||
} | ||
if (grunt.util._.include(supportedModes, mode) === false) { | ||
grunt.fail.warn('Mode ' + mode.cyan + ' not supported.'); | ||
} | ||
mode = targetMode || autoDetectMode(file.dest); | ||
if (this.filesSrc.length === 0) { | ||
grunt.fail.warn('Unable to compress; no valid source files were found.'); | ||
} | ||
if (grunt.util._.include(supportedModes, mode) === false) { | ||
grunt.fail.warn('Mode ' + mode.cyan + ' not supported.'); | ||
} | ||
if (grunt.file.exists(archiveDir) === false) { | ||
grunt.file.mkdir(archiveDir); | ||
} | ||
if (mode === 'gzip' && srcFiles.length > 1) { | ||
var archiveStream = fs.createWriteStream(archiveFile); | ||
var internalFileName; | ||
var srcFile; | ||
var filePairSrc; | ||
var isExpandedPair; | ||
var archive; | ||
if (mode === 'gzip') { | ||
// this needs to be evaluated as it doesn't fit new flow | ||
var srcFiles = this.filesSrc; | ||
srcFiles = srcFiles.filter(function(src) { | ||
return grunt.file.isFile(src); | ||
}); | ||
if (srcFiles.length > 1) { | ||
grunt.fail.warn('Cannot specify multiple input files for gzip compression.'); | ||
srcFiles = srcFiles[0]; | ||
} | ||
if (grunt.file.exists(destDir) === false) { | ||
grunt.file.mkdir(destDir); | ||
var srcStream = fs.createReadStream(srcFiles[0]); | ||
srcStream.pipe(zlib.createGzip()).pipe(archiveStream); | ||
archiveStream.on('close', function() { | ||
grunt.log.writeln('File ' + archiveFile.cyan + ' created (' + getSize(archiveFile) + ' bytes).'); | ||
done(); | ||
}); | ||
} else if (mode === 'tar' || mode === 'zip') { | ||
if (mode === 'tar') { | ||
archive = archiver.createTar(archiverOptions); | ||
} else if (mode === 'zip') { | ||
archive = archiver.createZip(archiverOptions); | ||
} | ||
methods[mode](srcFiles, file.dest, options, function(written) { | ||
grunt.log.writeln('File ' + file.dest.cyan + ' created (' + written + ' bytes written).'); | ||
next(); | ||
if (shouldGzipTar) { | ||
archive.pipe(zlib.createGzip()).pipe(archiveStream); | ||
} else { | ||
archive.pipe(archiveStream); | ||
} | ||
archive.on('error', function(err) { | ||
grunt.log.error(err); | ||
grunt.fail.warn('archiver failed'); | ||
}); | ||
}, function() { | ||
done(); | ||
}); | ||
grunt.util.async.forEachSeries(this.files, function(filePair, nextPair) { | ||
isExpandedPair = filePair.orig.expand || false; | ||
filePairSrc = filePair.src; | ||
filePairSrc = filePairSrc.filter(function(src) { | ||
return grunt.file.isFile(src); | ||
}); | ||
grunt.util.async.forEachSeries(filePairSrc, function(srcFile, nextFile) { | ||
internalFileName = (isExpandedPair) ? filePair.dest : unixifyPath(path.join(filePair.dest || '', srcFile)); | ||
archive.addFile(fs.createReadStream(srcFile), { name: internalFileName }, function() { | ||
grunt.log.writeln('Archiving ' + srcFile.cyan + ' -> ' + archiveFile.cyan + '/'.cyan + internalFileName.cyan); | ||
nextFile(); | ||
}); | ||
}, nextPair); | ||
}, function(err) { | ||
if (err) { | ||
grunt.fail.warn(err); | ||
} | ||
archive.finalize(function(written) { | ||
if (shouldGzipTar) { | ||
grunt.log.writeln('Created ' + archiveFile.cyan + ' (' + getSize(archiveFile) + ' bytes)'); | ||
} else { | ||
grunt.log.writeln('Created ' + archiveFile.cyan + ' (' + written + ' bytes)'); | ||
} | ||
done(); | ||
}); | ||
}); | ||
} | ||
}); | ||
@@ -111,149 +172,9 @@ | ||
var tempCopy = function(srcFiles, tempDir, options) { | ||
var newFiles = []; | ||
var newMeta = {}; | ||
var filename; | ||
var relative; | ||
var destPath; | ||
var basePath = helpers.findBasePath(srcFiles, options.basePath); | ||
var rootDir = options.rootDir; | ||
srcFiles.forEach(function(srcFile) { | ||
filename = path.basename(srcFile); | ||
relative = path.dirname(srcFile); | ||
relative = path.normalize(relative); | ||
if (options.flatten) { | ||
relative = ''; | ||
} else if (basePath && basePath.length >= 1) { | ||
relative = grunt.util._(relative).strRight(basePath).trim(path.sep); | ||
} | ||
if (rootDir && rootDir.length >= 1) { | ||
relative = path.join(options.rootDir, relative); | ||
} | ||
// make paths outside grunts working dir relative | ||
relative = relative.replace(/\.\.(\/|\\)/g, ''); | ||
destPath = path.join(tempDir, relative, filename); | ||
newFiles.push(destPath); | ||
newMeta[destPath] = {name: path.join(relative, filename)}; | ||
grunt.verbose.writeln('Adding ' + srcFile + ' to temporary structure.'); | ||
grunt.file.copy(srcFile, destPath); | ||
}); | ||
return [newFiles, newMeta]; | ||
}; | ||
var methods = { | ||
zip: function(srcFiles, dest, options, callback) { | ||
var zip = require('archiver').createZip(options); | ||
var destDir = path.dirname(dest); | ||
var tempDir = path.join(destDir, 'zip_' + (new Date()).getTime()); | ||
var copyResult = tempCopy(srcFiles, tempDir, options); | ||
var zipFiles = grunt.util._.uniq(copyResult[0]); | ||
var zipMeta = copyResult[1]; | ||
zip.pipe(fs.createWriteStream(dest)); | ||
var srcFile; | ||
function addFile() { | ||
if (!zipFiles.length) { | ||
zip.finalize(function(written) { | ||
rimraf.sync(tempDir); | ||
callback(written); | ||
}); | ||
return; | ||
} | ||
srcFile = zipFiles.shift(); | ||
zip.addFile(fs.createReadStream(srcFile), zipMeta[srcFile], addFile); | ||
} | ||
addFile(); | ||
zip.on('error', function(e) { | ||
grunt.log.error(e); | ||
grunt.fail.warn('zipHelper failed.'); | ||
}); | ||
}, | ||
tar: function(srcFiles, dest, options, callback, gzip) { | ||
var fstream = require('fstream'); | ||
var tar = require('tar'); | ||
var zlib = require('zlib'); | ||
var destDir = path.dirname(dest); | ||
var destFile = path.basename(dest); | ||
var destFileExt = path.extname(destFile); | ||
var tempDir = path.join(destDir, 'tar_' + (new Date()).getTime()); | ||
var tarDir; | ||
if (options.rootDir && options.rootDir.length >= 1) { | ||
tarDir = options.rootDir; | ||
options.rootDir = false; | ||
} else { | ||
tarDir = grunt.util._(destFile).strLeftBack(destFileExt); | ||
} | ||
if (gzip === true) { | ||
tarDir = tarDir.replace('.tar', ''); | ||
} | ||
var tarProcess; | ||
tarDir = path.join(tempDir, tarDir); | ||
tempCopy(srcFiles, tarDir, options); | ||
var reader = fstream.Reader({path: tarDir, type: 'Directory'}); | ||
var packer = tar.Pack(); | ||
var gzipper = zlib.createGzip(); | ||
var writer = fstream.Writer(dest); | ||
if (gzip === true) { | ||
tarProcess = reader.pipe(packer).pipe(gzipper).pipe(writer); | ||
} else { | ||
tarProcess = reader.pipe(packer).pipe(writer); | ||
} | ||
tarProcess.on('error', function(e) { | ||
grunt.log.error(e); | ||
grunt.fail.warn('tarHelper failed.'); | ||
}); | ||
tarProcess.on('close', function() { | ||
rimraf.sync(tempDir); | ||
callback(getSize(dest)); | ||
}); | ||
}, | ||
tgz: function(srcFiles, dest, options, callback) { | ||
methods.tar(srcFiles, dest, options, callback, true); | ||
}, | ||
gzip: function(file, dest, options, callback) { | ||
var zlib = require('zlib'); | ||
zlib.gzip(grunt.file.read(file), function(e, result) { | ||
if (!e) { | ||
grunt.file.write(dest, result); | ||
callback(result.length); | ||
} else { | ||
grunt.log.error(e); | ||
grunt.fail.warn('tarHelper failed.'); | ||
} | ||
}); | ||
var unixifyPath = function(filepath) { | ||
if (process.platform === 'win32') { | ||
return filepath.replace(/\\/g, '/'); | ||
} else { | ||
return filepath; | ||
} | ||
}; | ||
}; |
@@ -18,3 +18,3 @@ var grunt = require('grunt'); | ||
test.expect(11); | ||
test.expect(4); | ||
@@ -26,10 +26,2 @@ // Zip | ||
actual = getSize('tmp/compress_test_v0.1.0.zip'); | ||
expected = getSize('test/expected/compress_test_v0.1.0.zip'); | ||
test.equal(expected, actual, 'should compress folders and their files into zip (with template support)'); | ||
actual = getSize('tmp/compress_test_files_template.zip'); | ||
expected = getSize('test/expected/compress_test_files_template.zip'); | ||
test.equal(expected, actual, 'should compress files and folders into zip (grunt template in source)'); | ||
// Tar | ||
@@ -40,72 +32,14 @@ actual = getSize('tmp/compress_test_files.tar'); | ||
actual = getSize('tmp/compress_test_v0.1.0.tar'); | ||
expected = getSize('test/expected/compress_test_v0.1.0.tar'); | ||
test.equal(expected, actual, 'should add folders and their files into tar (with template support)'); | ||
actual = getSize('tmp/compress_test_files_template.tar'); | ||
expected = getSize('test/expected/compress_test_files_template.tar'); | ||
test.equal(expected, actual, 'should add files and folders into tar (grunt template in source)'); | ||
// Tar (gzip) | ||
actual = getSize('tmp/compress_test_files.tgz') >= 200; | ||
actual = getSize('tmp/compress_test_files.tgz') >= 195; | ||
expected = true; | ||
test.equal(expected, actual, 'should compress files into tar'); | ||
test.equal(expected, actual, 'should add files into tar. compressing the tar with gzip.'); | ||
actual = getSize('tmp/compress_test_v0.1.0.tgz') >= 350; | ||
expected = true; | ||
test.equal(expected, actual, 'should compress folders and their files into tgz (with template support)'); | ||
actual = getSize('tmp/compress_test_files_template.tgz') >= 200; | ||
expected = true; | ||
test.equal(expected, actual, 'should compress files and folders into tgz (grunt template in source)'); | ||
// gzip | ||
actual = getSize('tmp/compress_test_file.gz'); | ||
expected = getSize('test/expected/compress_test_file.gz'); | ||
actual = getSize('tmp/compress_test_file.js.gz'); | ||
expected = getSize('test/expected/compress_test_file.js.gz'); | ||
test.equal(expected, actual, 'should gzip file'); | ||
actual = getSize('tmp/compress_test_file2.gz'); | ||
expected = getSize('test/expected/compress_test_file2.gz'); | ||
test.equal(expected, actual, 'should gzip another file (multiple dest:source pairs)'); | ||
test.done(); | ||
}, | ||
flatten: function(test) { | ||
'use strict'; | ||
test.expect(3); | ||
var actual = getSize('tmp/compress_test_flatten.zip'); | ||
var expected = getSize('test/expected/compress_test_flatten.zip'); | ||
test.equal(expected, actual, 'should create a flat internal structure'); | ||
actual = getSize('tmp/compress_test_flatten.tar'); | ||
expected = getSize('test/expected/compress_test_flatten.tar'); | ||
test.equal(expected, actual, 'should create a flat internal structure'); | ||
actual = getSize('tmp/compress_test_flatten.tgz') >= 320; | ||
expected = true; | ||
test.equal(expected, actual, 'should create a flat internal structure'); | ||
test.done(); | ||
}, | ||
rootdir: function(test) { | ||
'use strict'; | ||
test.expect(3); | ||
var actual = getSize('tmp/compress_test_rootdir.zip'); | ||
var expected = getSize('test/expected/compress_test_rootdir.zip'); | ||
test.equal(expected, actual, 'should compress folders and their files into zip (with a root dir)'); | ||
actual = getSize('tmp/compress_test_rootdir.tar'); | ||
expected = getSize('test/expected/compress_test_rootdir.tar'); | ||
test.equal(expected, actual, 'should compress folders and their files into tar (with a custom root dir)'); | ||
actual = getSize('tmp/compress_test_rootdir.tgz') >= 200; | ||
expected = true; | ||
test.equal(expected, actual, 'should compress folders and their files into tgz (with a custom root dir)'); | ||
test.done(); | ||
} | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
3
86
2
5
27278
5
25
249
+ Addedarchiver@0.2.2(transitive)
+ Addedgrunt-lib-contrib@0.5.3(transitive)
+ Addedlodash@0.10.0(transitive)
+ Addedmkdirp@0.3.5(transitive)
+ Addedzlib-browserify@0.0.1(transitive)
- Removedfstream@~0.1.18
- Removedtar@~0.1.13
- Removedarchiver@0.1.1(transitive)
- Removedblock-stream@0.0.9(transitive)
- Removedfstream@0.1.31(transitive)
- Removedgraceful-fs@3.0.12(transitive)
- Removedgrunt-lib-contrib@0.3.1(transitive)
- Removedinherits@2.0.4(transitive)
- Removedminimist@1.2.8(transitive)
- Removedmkdirp@0.5.6(transitive)
- Removednatives@1.1.6(transitive)
- Removedtar@0.1.20(transitive)
Updatedarchiver@~0.2.2
Updatedgrunt-lib-contrib@~0.5.1