Skip to content
This repository has been archived by the owner on Oct 25, 2023. It is now read-only.

Add a helper method to compress file hierarchies based on glob pattern #122

Merged
merged 3 commits into from
Aug 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
os: linux
dist: xenial
language: node_js
node_js:
- "10"
- "12"
addons:
apt:
sources:
- llvm-toolchain-trusty-5.0
- llvm-toolchain-r-test
packages:
- clang-5.0
env:
Expand Down
51 changes: 49 additions & 2 deletions lib/zip.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,52 @@ async function assertValidZip (filePath) {
}
}

export { extractAllTo, readEntries, toInMemoryZip, _extractEntryTo, assertValidZip };
export default { extractAllTo, readEntries, toInMemoryZip, assertValidZip };
/**
* @typedef {Object} ZipCompressionOptions
* @property {number} level [9] - Compression level in range 0..9
* (greater numbers mean better compression, but longer processing time)
*/

/**
* @typedef {Object} ZipSourceOptions
* @property {!string} pattern ['**\/*'] - GLOB pattern for compression
* @property {!string} cwd - The source root folder (the parent folder of
* the destination file by default)
* @property {?Array<string>} ignore - The list of ignored patterns
*/

/**
* Creates an archive based on the given glob pattern
*
* @param {string} dstPath - The resulting archive path
* @param {ZipSourceOptions} src - Source options
* @param {ZipCompressionOptions} opts - Compression options
* @throws {Error} If there was an error while creating the archive
*/
async function toArchive (dstPath, src = {}, opts = {}) {
const {
level = 9,
} = opts;
const {
pattern = '**/*',
cwd = path.dirname(dstPath),
ignore = [],
} = src;
const archive = archiver('zip', { zlib: { level }});
const stream = fs.createWriteStream(dstPath);
return await new B((resolve, reject) => {
archive
.glob(pattern, {
cwd,
ignore,
})
.on('error', reject)
.pipe(stream);
stream.on('close', resolve);
archive.finalize();
});
}

export { extractAllTo, readEntries, toInMemoryZip, _extractEntryTo,
assertValidZip, toArchive };
export default { extractAllTo, readEntries, toInMemoryZip, assertValidZip, toArchive };
19 changes: 19 additions & 0 deletions test/zip-e2e-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,23 @@ describe('#zip', function () {
});
});

describe('toArchive', function () {
it('should zip all files into an archive', async function () {
const testFolder = path.resolve(assetsPath, 'unzipped');
const dstPath = path.resolve(tmpRoot, 'test.zip');
await zip.toArchive(dstPath, {
cwd: testFolder,
});

// Unzip the file and test that it has the same contents as the directory that was zipped
await zip.extractAllTo(dstPath, path.resolve(tmpRoot, 'output'));
await fs.readFile(path.resolve(tmpRoot, 'output', 'test-dir', 'a.txt'), {
encoding: 'utf8'
}).should.eventually.equal('Hello World');
await fs.readFile(path.resolve(tmpRoot, 'output', 'test-dir', 'b.txt'), {
encoding: 'utf8'
}).should.eventually.equal('Foo Bar');
});
});

});