diff --git a/src/shell/shell.js b/src/shell/shell.js index 8b6abf1..c619270 100644 --- a/src/shell/shell.js +++ b/src/shell/shell.js @@ -501,23 +501,24 @@ define(function(require) { if(err) return callback(err); var unzip = new Zlib.Unzip(data); - // Separate filenames within the zip archive with what will go in fs + + // Separate filenames within the zip archive with what will go in fs. + // Also mark any directories (i.e., paths with a trailing '/') var filenames = unzip.getFilenames().map(function(filename) { return { zipFilename: filename, - fsFilename: Path.join(destination, filename) + fsFilename: Path.join(destination, filename), + isDirectory: /\/$/.test(filename) }; }); function decompress(path, callback) { var data = unzip.decompress(path.zipFilename); - - // Make sure the dir(s) we need exist before writing file - var dir = Path.dirname(path.fsFilename); - sh.mkdirp(dir, function(err) { -console.log('inflate', path.zipFilename, path.fsFilename); + if(path.isDirectory) { + sh.mkdirp(path.fsFilename, callback); + } else { fs.writeFile(path.fsFilename, data, callback); - }); + } } async.eachSeries(filenames, decompress, callback); diff --git a/tests/spec/shell/unzip.spec.js b/tests/spec/shell/unzip.spec.js index 3045ddc..7befeb5 100644 --- a/tests/spec/shell/unzip.spec.js +++ b/tests/spec/shell/unzip.spec.js @@ -90,5 +90,65 @@ define(["Filer", "util"], function(Filer, util) { }); }); + it('should be able to handle a deep tree structure in a zip', function(done) { + // test-dir.zip has the following structure: + // + // test-dir/ + // ├── test-dir2 + // │ └── test-file.txt + // ├── test-file.txt + // └── test-file2.txt + + var fs = util.fs(); + var shell = fs.Shell(); + var url = "test-dir.zip"; + var Path = Filer.Path; + var contents = "This is a test file used in some of the tests.\n"; + + function confirmFile(filename, callback) { + filename = Path.join('/', filename); + fs.readFile(filename, 'utf8', function(err, data) { + if(err) { + console.error('Expected ' + filename + ' to exist.'); + expect(false).to.be.true; + return callback(err); + } + expect(data).to.equal(contents); + callback(); + }); + } + + function confirmDir(dirname, callback) { + dirname = Path.join('/', dirname); + fs.stat(dirname, function(err, stats) { + if(err) { + console.error('Expected ' + dirname + ' to exist.'); + expect(false).to.be.true; + return callback(err); + } + expect(stats.isDirectory()).to.be.true; + callback(); + }); + } + + shell.wget(url, {filename: url}, function(err, path) { + if(err) throw err; + + shell.unzip(path, function(err) { + if(err) throw err; + + // Forgive the crazy indenting, trying to match tree structure ;) + confirmDir('test-dir', function() { + confirmDir('test-dir/test-dir2', function() { + confirmFile('test-dir/test-dir2/test-file.txt', function() { + confirmFile('test-dir/test-file.txt', function() { + confirmFile('test-dir/test-file2.txt', function() { + done(); + });});});});}); + + }); + }); + }); + }); }); diff --git a/tests/test-dir.zip b/tests/test-dir.zip new file mode 100644 index 0000000..0e41eca Binary files /dev/null and b/tests/test-dir.zip differ