Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 1d14cee
Showing
7 changed files
with
228 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#!/usr/bin/env node | ||
|
||
var path = require('path') | ||
var minimist = require('minimist') | ||
var extract = require('./') | ||
|
||
var args = process.argv.slice(2) | ||
var source = args[0] | ||
var dest = args[1] || process.cwd() | ||
if (!source) { | ||
console.error('Usage: extract-zip foo.zip <targetDirectory>') | ||
process.exit(1) | ||
} | ||
|
||
extract(source, {dir: dest}, function(err, results) { | ||
if (err) console.error('error!', err) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
var fs = require('fs') | ||
var path = require('path') | ||
var async = require('async') | ||
var yauzl = require('yauzl') | ||
var mkdirp = require('mkdirp') | ||
var concat = require('concat-stream') | ||
var debug = require('debug')('extract-zip') | ||
|
||
// lolol zips | ||
var MAGIC_SYMLINK_ATTR_1 = 2716663808 | ||
var MAGIC_SYMLINK_ATTR_2 = 2716680192 | ||
|
||
module.exports = function(zipPath, opts, cb) { | ||
debug('opening', zipPath, 'with opts', opts) | ||
yauzl.open(zipPath, {autoClose: false}, function(err, zipfile) { | ||
if (err) return cb(err) | ||
|
||
var cancelled = false | ||
var finished = false | ||
|
||
var q = async.queue(extractEntry, 1) | ||
|
||
q.drain = function() { | ||
if (!finished) return | ||
debug('zip extraction complete') | ||
cb() | ||
} | ||
|
||
zipfile.on("entry", function(entry) { | ||
debug('zipfile entry', entry.fileName) | ||
if (/\/$/.test(entry.fileName)) { | ||
// directory file names end with '/' | ||
return | ||
} | ||
|
||
q.push(entry, function(err) { | ||
debug('finished processing', entry.fileName, {err: err}) | ||
}) | ||
}) | ||
|
||
zipfile.on('end', function() { | ||
finished = true | ||
}) | ||
|
||
function extractEntry(entry, done) { | ||
if (cancelled) { | ||
debug('skipping entry', entry.fileName, {cancelled: cancelled}) | ||
return setImmediate(done) | ||
} else { | ||
debug('extracting entry', entry.fileName) | ||
} | ||
|
||
var dest = path.join(opts.dir, entry.fileName) | ||
var destDir = path.dirname(dest) | ||
var symlink = false | ||
|
||
if (entry.externalFileAttributes === MAGIC_SYMLINK_ATTR_1 || | ||
entry.externalFileAttributes === MAGIC_SYMLINK_ATTR_2) { | ||
symlink = true | ||
} | ||
|
||
zipfile.openReadStream(entry, function(err, readStream) { | ||
if (err) { | ||
debug('openReadStream error', err) | ||
cancelled = true | ||
return done(err) | ||
} | ||
|
||
readStream.on('error', function(err) { | ||
console.log('read err', err) | ||
}) | ||
|
||
mkdirp(destDir, function(err) { | ||
if (err) { | ||
debug('mkdirp error', destDir, {error: err}) | ||
cancelled = true | ||
return done(err) | ||
} | ||
|
||
if (symlink) writeSymlink() | ||
else writeStream() | ||
}) | ||
|
||
function writeStream() { | ||
var writeStream = fs.createWriteStream(dest) | ||
readStream.pipe(writeStream) | ||
writeStream.on('finish', function() { | ||
done() | ||
}) | ||
writeStream.on('error', function(err) { | ||
debug('write error', {error: err}) | ||
cancelled = true | ||
return done(err) | ||
}) | ||
} | ||
|
||
// AFAICT the content of the symlink file itself is the symlink target filename string | ||
function writeSymlink() { | ||
readStream.pipe(concat(function(data) { | ||
var link = data.toString() | ||
debug('creating symlink', link, dest) | ||
fs.symlink(link, dest, function(err) { | ||
if (err) cancelled = true | ||
done(err) | ||
}) | ||
})) | ||
} | ||
|
||
}) | ||
} | ||
|
||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"name": "extract-zip", | ||
"version": "1.0.0", | ||
"description": "unzip a zip file into a directory using 100% pure gluten-free organic javascript", | ||
"main": "index.js", | ||
"bin": "cli.js", | ||
"scripts": { | ||
"test": "node test/test.js" | ||
}, | ||
"author": "max ogden", | ||
"license": "BSD", | ||
"repository": { | ||
"type": "git", | ||
"url": "git@github.com:maxogden/extract-zip.git" | ||
}, | ||
"keywords": [ | ||
"unzip", | ||
"zip", | ||
"extract" | ||
], | ||
"bugs": { | ||
"url": "https://github.com/maxogden/extract-zip/issues" | ||
}, | ||
"homepage": "https://github.com/maxogden/extract-zip", | ||
"dependencies": { | ||
"debug": "0.7.4", | ||
"async": "0.9.0", | ||
"mkdirp": "0.5.0", | ||
"concat-stream": "^1.4.6", | ||
"through2": "0.6.3", | ||
"yauzl": "^2.0.3" | ||
}, | ||
"devDependencies": { | ||
"rimraf": "^2.2.8" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# extract-zip | ||
|
||
Streaming unzip written in pure JavaScript. Available as a library or a command line program. | ||
|
||
Uses the [`yauzl`](http://npmjs.org/yauzl) ZIP parser. | ||
|
||
[![NPM](https://nodei.co/npm/extract-zip.png?global=true)](https://nodei.co/npm/extract-zip/) | ||
|
||
## Installation | ||
|
||
Get the library: | ||
|
||
``` | ||
npm install extract-zip --save | ||
``` | ||
|
||
Install the command line program: | ||
|
||
``` | ||
npm install extract-zip -g | ||
``` | ||
|
||
## JS API | ||
|
||
```js | ||
var extract = require('extract-zip') | ||
extract(source, {dir: target}, function(err) { | ||
|
||
}) | ||
``` | ||
|
||
If not specified, `dir` will default to `process.cwd()`. | ||
|
||
## CLI Usage | ||
|
||
``` | ||
extract-zip foo.zip <targetDirectory> | ||
``` | ||
|
||
If not specified, `targetDirectory` will default to `process.cwd()`. | ||
|
||
## stuff to figure out | ||
|
||
-- better handling of magic symlink attr | ||
-- ignore __macosx folder? | ||
-- when to chmod +x (internal file attribute?) |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
var os = require('os') | ||
var path = require('path') | ||
var rimraf = require('rimraf') | ||
var extract = require('../') | ||
|
||
var source = path.join(__dirname, 'cats.zip') | ||
var target = path.join(os.tmpdir(), 'cat-extract-test') | ||
rimraf.sync(target) | ||
|
||
console.log('extracting to', target) | ||
|
||
extract(source, {dir: target}, function(err, results) { | ||
console.log('FIN', err, results) | ||
}) |