-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
70 lines (63 loc) · 1.94 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
'use strict';
const gunzipMaybe = require('gunzip-maybe');
const fstream = require('fstream');
const pify = require('pify');
const pathExists = require('path-exists');
const mem = require('mem');
const mkdirp = require('make-dir');
// rewired in test
let which = pify(require('which'));
let execa = require('execa');
let tar = require('tar-fs');
/**
* Check if the system has a tar binary.
* @returns {Promise.<Boolean>}
*/
let hasBinaryTar = mem(function () {
if (process.platform === 'win32') return Promise.resolve(false);
else return which('tar').then(() => true, () => false);
});
/**
* Extract using built-in tar binary with the node.js implementation as a fallback
* @param {string} archive
* @param {string} extractTo
* @returns {Promise.<T>}
*/
const extrakt = function (archive, extractTo) {
return Promise.all([
pathExists(archive),
hasBinaryTar()
]).then(([exists, hasBinaryTar]) => {
if (!exists) throw new Error(`No file at ${archive}`);
return hasBinaryTar;
})
.then(sys => sys ? extrakt.system(archive, extractTo) : extrakt.native(archive, extractTo));
};
/**
* Extract using the system's built-in tar binary
* @param {string} archive
* @param {string} extractTo
* @returns {Promise}
*/
extrakt.system = function (archive, extractTo) {
return mkdirp(extractTo).then(() => execa('tar', ['-xf', archive, '-C', extractTo]));
};
/**
* Extract using the tar-fs module
* @param {string} archive
* @param {string} extractTo
* @returns {Promise}
*/
extrakt.native = function (archive, extractTo) {
// note the tar module takes care of mkdirp'ing the destination directory
let extract = tar.extract(extractTo);
fstream
.Reader(archive)
.pipe(gunzipMaybe())
.pipe(extract);
return new Promise((resolve, reject) => {
extract.on('finish', resolve);
extract.on('error', reject);
});
};
module.exports = extrakt;