mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-28 21:33:24 +03:00
Consistent interface and response
- Creating a better, more long-term API here - compress and extract are opposite, neat terms - Use new Promise to get rid of callback argument when using archiver to compress a folder - Add options argument, and make a couple of key details configurable - Make the response intelligable - Ensure both functions are consistent - Updated tests to match
This commit is contained in:
parent
62c2fce6cc
commit
adfb3fe499
@ -11,6 +11,17 @@ or
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
const zip = require('@tryghost/zip');
|
||||
|
||||
// Create a zip from a folder
|
||||
|
||||
let res = await zip.compress('path/to/a/folder', 'path/to/archive.zip', [options])
|
||||
|
||||
// Extract a zip to a folder
|
||||
|
||||
let res = await zip.extract('path/to/archive.zip', 'path/to/files', [options])
|
||||
```
|
||||
|
||||
## Develop
|
||||
|
||||
@ -34,6 +45,6 @@ Follow the instructions for the top-level repo.
|
||||
|
||||
|
||||
|
||||
# Copyright & License
|
||||
# Copyright & License
|
||||
|
||||
Copyright (c) 2020 Ghost Foundation - Released under the [MIT license](LICENSE).
|
@ -1,7 +1,4 @@
|
||||
const extract = require('extract-zip');
|
||||
const zipFolder = require('./lib/zip-folder');
|
||||
|
||||
module.exports = {
|
||||
extract,
|
||||
zipFolder
|
||||
extract: require('./lib/extract'),
|
||||
compress: require('./lib/compress')
|
||||
};
|
||||
|
50
ghost/zip/lib/compress.js
Normal file
50
ghost/zip/lib/compress.js
Normal file
@ -0,0 +1,50 @@
|
||||
const fs = require('fs-extra');
|
||||
const Promise = require('bluebird');
|
||||
|
||||
const defaultOptions = {
|
||||
type: 'zip',
|
||||
glob: '**/*',
|
||||
ignore: ['node_modules/**']
|
||||
};
|
||||
|
||||
/**
|
||||
* Compress
|
||||
*
|
||||
* - Create a zip file from a folder
|
||||
*
|
||||
* @param {String} folderToZip - full path to the folder to be zipped
|
||||
* @param {String} destination - full path to the resulting zip file
|
||||
* @param {Object} [options]
|
||||
* @param {String} options.type - zip by default see archiver for other options
|
||||
* @param {String} options.glob - the files to include, defaults to all files and folders
|
||||
* @param {Array} options.ignore - any paths that should be ignored, sets node_modules by default
|
||||
*/
|
||||
module.exports = (folderToZip, destination, options = {}) => {
|
||||
const opts = Object.assign({}, defaultOptions, options);
|
||||
|
||||
const archiver = require('archiver');
|
||||
const output = fs.createWriteStream(destination);
|
||||
const archive = archiver.create(opts.type, {});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// If folder to zip is a symlink, we want to get the target
|
||||
// of the link and zip that instead of zipping the symlink
|
||||
if (fs.lstatSync(folderToZip).isSymbolicLink()) {
|
||||
folderToZip = fs.realpathSync(folderToZip);
|
||||
}
|
||||
|
||||
output.on('close', function () {
|
||||
resolve({path: destination, size: archive.pointer()});
|
||||
});
|
||||
|
||||
archive.on('error', function (err) {
|
||||
reject(err);
|
||||
});
|
||||
archive.glob(opts.glob, {
|
||||
cwd: folderToZip,
|
||||
ignore: opts.ignore
|
||||
});
|
||||
archive.pipe(output);
|
||||
archive.finalize();
|
||||
});
|
||||
};
|
25
ghost/zip/lib/extract.js
Normal file
25
ghost/zip/lib/extract.js
Normal file
@ -0,0 +1,25 @@
|
||||
const defaultOptions = {};
|
||||
|
||||
/**
|
||||
* Extract
|
||||
*
|
||||
* - Unzip an archive to a folder
|
||||
*
|
||||
* @param {String} zipToExtract - full path to zip file that should be extracted
|
||||
* @param {String} destination - full path of the extraction target
|
||||
* @param {Object} [options]
|
||||
* @param {Integer} options.defaultDirMode - Directory Mode (permissions), defaults to 0o755
|
||||
* @param {Integer} options.defaultFileMode - File Mode (permissions), defaults to 0o644
|
||||
* @param {Function} options.onEntry - if present, will be called with (entry, zipfile) for every entry in the zip
|
||||
*/
|
||||
module.exports = (zipToExtract, destination, options) => {
|
||||
const opts = Object.assign({}, defaultOptions, options);
|
||||
|
||||
const extract = require('extract-zip');
|
||||
|
||||
opts.dir = destination;
|
||||
|
||||
return extract(zipToExtract, opts).then(() => {
|
||||
return {path: destination};
|
||||
});
|
||||
};
|
@ -1,30 +0,0 @@
|
||||
const fs = require('fs-extra');
|
||||
const Promise = require('bluebird');
|
||||
|
||||
const zipFolder = (folderToZip, destination, callback) => {
|
||||
var archiver = require('archiver'),
|
||||
output = fs.createWriteStream(destination),
|
||||
archive = archiver.create('zip', {});
|
||||
|
||||
// If folder to zip is a symlink, we want to get the target
|
||||
// of the link and zip that instead of zipping the symlink
|
||||
if (fs.lstatSync(folderToZip).isSymbolicLink()) {
|
||||
folderToZip = fs.realpathSync(folderToZip);
|
||||
}
|
||||
|
||||
output.on('close', function () {
|
||||
callback(null, archive.pointer());
|
||||
});
|
||||
|
||||
archive.on('error', function (err) {
|
||||
callback(err, null);
|
||||
});
|
||||
archive.glob(`**/*`, {
|
||||
cwd: folderToZip,
|
||||
ignore: ['node_modules/**']
|
||||
});
|
||||
archive.pipe(output);
|
||||
archive.finalize();
|
||||
};
|
||||
|
||||
module.exports = Promise.promisify(zipFolder);
|
@ -6,9 +6,9 @@ const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
// Mimic how we expect this to be required
|
||||
const {zipFolder, extract} = require('../');
|
||||
const {compress, extract} = require('../');
|
||||
|
||||
describe('lib/fs: read csv', function () {
|
||||
describe('Compress and Extract should be opposite functions', function () {
|
||||
let symlinkPath, folderToSymlink, zipDestination, unzipDestination;
|
||||
|
||||
const cleanUp = () => {
|
||||
@ -33,10 +33,17 @@ describe('lib/fs: read csv', function () {
|
||||
it('ensure symlinks work', function (done) {
|
||||
fs.symlink(folderToSymlink, symlinkPath);
|
||||
|
||||
zipFolder(symlinkPath, zipDestination)
|
||||
.then(() => {
|
||||
extract(zipDestination, {dir: unzipDestination})
|
||||
.then(() => {
|
||||
compress(symlinkPath, zipDestination)
|
||||
.then((res) => {
|
||||
res.should.be.an.Object().with.properties('path', 'size');
|
||||
res.path.should.eql(zipDestination);
|
||||
res.size.should.eql(321775);
|
||||
|
||||
extract(zipDestination, unzipDestination)
|
||||
.then((res) => {
|
||||
res.should.be.an.Object().with.properties('path');
|
||||
res.path.should.eql(unzipDestination);
|
||||
|
||||
fs.readdir(unzipDestination, function (err, files) {
|
||||
if (err) {
|
||||
return done(err);
|
Loading…
Reference in New Issue
Block a user