From 7e5607f443a0822c4a1a5f2026fb867cac3d40ed Mon Sep 17 00:00:00 2001 From: RecuencoJones Date: Sat, 21 Mar 2020 11:34:19 +0100 Subject: [PATCH] ADD unzip support --- __test__/actions/install.spec.js | 13 +++++++++ __test__/assets/unzip.spec.js | 50 ++++++++++++++++++++++++++++++++ package.json | 3 +- src/actions/install.js | 2 ++ src/assets/untar.js | 3 -- src/assets/unzip.js | 19 ++++++++++++ 6 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 __test__/assets/unzip.spec.js create mode 100644 src/assets/unzip.js diff --git a/__test__/actions/install.spec.js b/__test__/actions/install.spec.js index 9bfaaaf..88d46e5 100644 --- a/__test__/actions/install.spec.js +++ b/__test__/actions/install.spec.js @@ -4,6 +4,7 @@ const common = require('../../src/common'); const install = require('../../src/actions/install'); const move = require('../../src/assets/move'); const untar = require('../../src/assets/untar'); +const unzip = require('../../src/assets/unzip'); const verifyAndPlaceCallback = require('../../src/assets/binary'); jest.mock('fs'); @@ -12,6 +13,7 @@ jest.mock('request'); jest.mock('../../src/common'); jest.mock('../../src/assets/move'); jest.mock('../../src/assets/untar'); +jest.mock('../../src/assets/unzip'); jest.mock('../../src/assets/binary'); describe('install()', () => { @@ -77,6 +79,17 @@ describe('install()', () => { expect(untar).toHaveBeenCalled(); }); + it('should pick unzip strategy if url ends with .zip', () => { + request.mockReturnValueOnce(requestEvents); + common.parsePackageJson.mockReturnValueOnce({ url: 'http://url.zip' }); + + install(callback); + + requestEvents.emit('response', { statusCode: 200 }); + + expect(unzip).toHaveBeenCalled(); + }); + it('should call verifyAndPlaceCallback on success', () => { request.mockReturnValueOnce(requestEvents); common.parsePackageJson.mockReturnValueOnce({ url: 'http://url', binName: 'command', binPath: './bin' }); diff --git a/__test__/assets/unzip.spec.js b/__test__/assets/unzip.spec.js new file mode 100644 index 0000000..e6b4040 --- /dev/null +++ b/__test__/assets/unzip.spec.js @@ -0,0 +1,50 @@ +const { EventEmitter } = require('events'); +const unzipper = require('unzipper'); +const unzip = require('../../src/assets/unzip'); + +jest.mock('unzipper', () => ({ + Extract: jest.fn() +})); + +describe('unzip()', () => { + + let unzipEvents, pipe, onSuccess, onError; + + beforeEach(() => { + unzipEvents = new EventEmitter(); + + pipe = jest.fn(); + onSuccess = jest.fn(); + onError = jest.fn(); + + pipe.mockReturnValueOnce({ pipe }); + unzipper.Extract.mockReturnValueOnce(unzipEvents); + }); + + it('should download resource and unzip to given binPath', () => { + + unzip({ opts: { binPath: './bin', binName: 'command' }, req: { pipe }, onSuccess, onError }); + + expect(unzipper.Extract).toHaveBeenCalledWith({ path: './bin' }); + }); + + it('should call onSuccess on unzip close', () => { + + unzip({ opts: { binPath: './bin', binName: 'command' }, req: { pipe }, onSuccess, onError }); + + unzipEvents.emit('close'); + + expect(onSuccess).toHaveBeenCalled(); + }); + + it('should call onError with error on unzip error', () => { + + const error = new Error(); + + unzip({ opts: { binPath: './bin', binName: 'command' }, req: { pipe }, onSuccess, onError }); + + unzipEvents.emit('error', error); + + expect(onError).toHaveBeenCalledWith(error); + }); +}); diff --git a/package.json b/package.json index 424a622..13dd73a 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "dependencies": { "mkdirp": "^0.5.1", "request": "^2.81.0", - "tar": "^2.2.2" + "tar": "^2.2.2", + "unzipper": "0.10.10" }, "repository": { "type": "git", diff --git a/src/actions/install.js b/src/actions/install.js index f1e928a..dfef0e0 100644 --- a/src/actions/install.js +++ b/src/actions/install.js @@ -10,6 +10,8 @@ function getStrategy({ url }) { if (url.endsWith('.tar.gz')) { return require('../assets/untar'); + } else if (url.endsWith('.zip')) { + return require('../assets/unzip'); } else { return require('../assets/move'); } diff --git a/src/assets/untar.js b/src/assets/untar.js index 1272cdf..cb080af 100644 --- a/src/assets/untar.js +++ b/src/assets/untar.js @@ -14,9 +14,6 @@ function untar({ opts, req, onSuccess, onError }) { ungz.on('error', onError); untar.on('error', onError); - - // First we will Un-GZip, then we will untar. So once untar is completed, - // binary is downloaded into `binPath`. Verify the binary and call it good untar.on('end', onSuccess); req.pipe(ungz).pipe(untar); diff --git a/src/assets/unzip.js b/src/assets/unzip.js new file mode 100644 index 0000000..4cb030e --- /dev/null +++ b/src/assets/unzip.js @@ -0,0 +1,19 @@ +const unzipper = require('unzipper'); + +/** + * Unzip strategy for resources using `.zip`. + * + * Once unzip is completed, binary is downloaded into `binPath`. + * Verify the binary and call it good. + */ +function unzip({ opts, req, onSuccess, onError }) { + + const unzip = unzipper.Extract({ path: opts.binPath }); + + unzip.on('error', onError); + unzip.on('close', onSuccess); + + req.pipe(unzip); +} + +module.exports = unzip;