Skip to content

Commit b476edb

Browse files
committed
added methods to extract only selected files
1 parent 03a592f commit b476edb

File tree

4 files changed

+164
-19
lines changed

4 files changed

+164
-19
lines changed

lib/index.d.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export = SevenZip;
1111
* @param filepath {string} Path to the archive.
1212
* @param files {string|array} Files to add.
1313
* @param options {Object} An object of acceptable 7-zip switch options.
14-
* @param useBinary {string} binary to use.
1514
* @param override {boolean} should binary directory change?
1615
*
1716
* @resolve {array} Arguments passed to the child-process.
@@ -28,29 +27,21 @@ export function createArchive(filepath: string, files: string | array, options?:
2827
* @param filepath {string} Path to the archive.
2928
* @param files {string|array} Files to remove.
3029
* @param options {Object} An object of acceptable 7-zip switch options.
31-
* @param useBinary {string} binary to use.
3230
* @param override {boolean} should binary directory change?
3331
*
3432
* @resolve {array} Arguments passed to the child-process.
3533
* @reject {Error} The error as issued by 7-Zip.
3634
*
3735
* @returns {Promise} Promise
3836
*/
39-
export function deleteArchive(
40-
filepath: string,
41-
files: string | array,
42-
options?: object,
43-
useBinary?: string,
44-
override?: boolean
45-
): Promise<any>;
37+
export function deleteArchive(filepath: string, files: string | array, options?: object, override?: boolean): Promise<any>;
4638

4739
/**
4840
* Extract an archive.
4941
*
50-
* @param {string} archive Path to the archive.
42+
* @param {string} filepath Path to the archive.
5143
* @param {string} dest Destination.
5244
* @param options {Object} An object of acceptable 7-zip switch options.
53-
* @param useBinary {string} binary to use.
5445
* @param override {boolean} should binary directory change?
5546
*
5647
* @resolve {array} Arguments passed to the child-process.
@@ -59,13 +50,24 @@ export function deleteArchive(
5950
*
6051
* @returns {Promise} Promise
6152
*/
62-
export function extractArchive(
63-
filepath: string,
64-
dest: string | array,
65-
options?: object,
66-
useBinary?: string,
67-
override?: boolean
68-
): Promise<any>;
53+
export function extractArchive(filepath: string, dest: string, options?: object, override?: boolean): Promise<any>;
54+
55+
/**
56+
* Extract only selected files from archive.
57+
*
58+
* @param {string} filepath Path to the archive.
59+
* @param {string} dest Destination.
60+
* @param {string|array} files Files in archive to extract.
61+
* @param options {Object} An object of acceptable 7-zip switch options.
62+
* @param override {boolean} should binary directory change?
63+
*
64+
* @resolve {array} Arguments passed to the child-process.
65+
* @progress {array} Extracted files and directories.
66+
* @reject {Error} The error as issued by 7-Zip.
67+
*
68+
* @returns {Promise} Promise
69+
*/
70+
export function onlyArchive(filepath: string, dest: string, files: string | array, options?: object, override?: boolean): Promise<any>;
6971

7072
export function fullArchive(filepath: string, files: string | array, options?: object, useBinary?: string, override?: boolean): Promise<any>;
7173
export function listArchive(filepath: string, files: string | array, options?: object, useBinary?: string, override?: boolean): Promise<any>;

lib/index.mjs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import _deleteArchive from './deleteArchive.mjs';
55
import _extractArchive from './extractArchive.mjs';
66
import _fullArchive from './fullArchive.mjs';
77
import _listArchive from './listArchive.mjs';
8+
import _onlyArchive from './onlyArchive.mjs';
89
import _renameArchive from './renameArchive.mjs';
910
import _testArchive from './testArchive.mjs';
1011
import _updateArchive from './updateArchive.mjs';
1112
import createSfx from './createSfx.mjs';
1213

1314
class SevenZip {
14-
constructor() {}
15+
constructor() { }
1516
}
1617

1718
export default SevenZip;
@@ -20,6 +21,23 @@ export const deleteArchive = SevenZip.deleteArchive = _deleteArchive;
2021
export const extractArchive = SevenZip.extractArchive = _extractArchive;
2122
export const fullArchive = SevenZip.fullArchive = _fullArchive;
2223
export const listArchive = SevenZip.listArchive = _listArchive;
24+
25+
/**
26+
* Extract only selected files from archive.
27+
*
28+
* @param {string} filepath Path to the archive.
29+
* @param {string} dest Destination.
30+
* @param {string|array} files Files in archive to extract.
31+
* @param options {Object} An object of acceptable 7-zip switch options.
32+
* @param override {boolean} should binary directory change?
33+
*
34+
* @resolve {array} Arguments passed to the child-process.
35+
* @progress {array} Extracted files and directories.
36+
* @reject {Error} The error as issued by 7-Zip.
37+
*
38+
* @returns {Promise} Promise
39+
*/
40+
export const onlyArchive = SevenZip.onlyArchive = _onlyArchive;
2341
export const renameArchive = SevenZip.renameArchive = _renameArchive;
2442
export const testArchive = SevenZip.testArchive = _testArchive;
2543
export const updateArchive = SevenZip.updateArchive = _updateArchive;

lib/onlyArchive.mjs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use strict';
2+
3+
import when from 'when';
4+
import Files from '../util/files.mjs';
5+
import ReplaceNativeSeparator from '../util/replaceNativeSeparator.mjs';
6+
import Run from '../util/run.mjs';
7+
8+
/**
9+
* Extract only selected files from archive.
10+
*
11+
* @param {string} filepath Path to the archive.
12+
* @param {string} dest Destination.
13+
* @param {string|array} files Files in archive to extract.
14+
* @param options {Object} An object of acceptable 7-zip switch options.
15+
* @param override {boolean} should binary directory change?
16+
*
17+
* @resolve {array} Arguments passed to the child-process.
18+
* @progress {array} Extracted files and directories.
19+
* @reject {Error} The error as issued by 7-Zip.
20+
*
21+
* @returns {Promise} Promise
22+
*/
23+
export default function (filepath, dest = '*', files = [], options = {}, override = false) {
24+
return when.promise(function (resolve, reject, progress) {
25+
/**
26+
* When a stdout is emitted, parse each line and search for a pattern.When
27+
* the pattern is found, extract the file (or directory) name from it and
28+
* pass it to an array. Finally returns this array.
29+
*/
30+
function onprogress(data) {
31+
let entries = [];
32+
data.split('\n').forEach(function (line) {
33+
if (line.substr(0, 1) === '-') {
34+
entries.push(ReplaceNativeSeparator(line.substr(2, line.length)));
35+
}
36+
});
37+
return entries;
38+
}
39+
40+
// Convert array of files into a string if needed.
41+
files = Files(files);
42+
43+
// Create a string that can be parsed by `run`.
44+
let command = 'e "' + filepath + '" -o"' + dest + '" -r -aos ' + files;
45+
46+
// Start the command
47+
Run('7z', command, options, override)
48+
.progress(function (data) {
49+
return progress(onprogress(data));
50+
})
51+
52+
// When all is done resolve the Promise.
53+
.then(function (args) {
54+
return resolve(args);
55+
})
56+
57+
// Catch the error and pass it to the reject function of the Promise.
58+
.catch(function () {
59+
console.error('OnlyArchive failed using `7z`, retying with `7za`.');
60+
Run('7za', command, options, override)
61+
.progress(function (data) {
62+
return progress(onprogress(data));
63+
})
64+
.then(function (args) {
65+
return resolve(args);
66+
})
67+
.catch(function (err) {
68+
return reject(err);
69+
});
70+
});
71+
});
72+
};

test/lib/onlyArchive.test.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*global describe, it */
2+
'use strict';
3+
import chai from 'chai';
4+
import fs from 'fs-extra';
5+
import {
6+
onlyArchive
7+
} from '../../lib/index.mjs';
8+
const expect = chai.expect;
9+
10+
describe('Method: `onlyArchive`', function () {
11+
12+
it('should return an error on 7z error', function (done) {
13+
onlyArchive('test/nothere.7z', '.tmp/test')
14+
.catch(function (err) {
15+
expect(err).to.be.an.instanceof(Error);
16+
done();
17+
});
18+
});
19+
20+
it('should return an error on output duplicate', function (done) {
21+
onlyArchive('test/zip.7z', '.tmp/test', '', {
22+
o: '.tmp/test/duplicate'
23+
})
24+
.catch(function (err) {
25+
expect(err).to.be.an.instanceof(Error);
26+
done();
27+
});
28+
});
29+
30+
it('should return entries on progress', function (done) {
31+
onlyArchive('test/zip.7z', '.tmp/test', ['zip/file1.txt', 'zip/file2.txt'])
32+
.progress(function (entries) {
33+
expect(entries.length).to.be.at.least(1);
34+
done();
35+
});
36+
});
37+
38+
it('should extract only on the right path', function (done) {
39+
onlyArchive('test/zip.7z', '.tmp/test', ['zip/folder/file0.txt', 'zip/file2.txt', 'zip/file3.txt'])
40+
.then(function () {
41+
// expect(fs.existsSync('.tmp/test/file3.txt')).to.be.eql(true);
42+
expect(fs.existsSync('.tmp/test/file0.txt')).to.be.eql(true);
43+
expect(fs.existsSync('.tmp/test/file1.txt')).to.be.eql(false);
44+
expect(fs.existsSync('.tmp/test/file2.txt')).to.be.eql(true);
45+
done();
46+
})
47+
.catch((err) => {
48+
console.log(err);
49+
done();
50+
});
51+
});
52+
53+
});

0 commit comments

Comments
 (0)