GeezerVison is showing github.com — feat: support strip for all archive `uncompress` (#117) · node-modules/compressing@15d24cd
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: README.md +2Lines changed: 2 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -280,6 +280,7 @@ Params | 280 | 280 | - Korean: cp949, euc-kr | 281 | 281 | - Japanese: sjis (shift_jis), cp932, euc-jp | 282 | 282 | - Chinese: gbk, gb18030, gb2312, cp936, hkscs, big5, cp950 | | 283 | + - opts.strip {Number} - Strip leading path segments when extracting (tar/tgz/zip). Default is 0. | 283 | 284 |
| 284 | 285 | ### FileStream | 285 | 286 |
| @@ -359,6 +360,7 @@ __Constructor__ | 359 | 360 | Common params: | 360 | 361 |
| 361 | 362 | - opts.source {String|Buffer|Stream} - source to be uncompressed, could be a file path, buffer, or a readable stream. | | 363 | +- opts.strip {Number} - Strip leading path segments when extracting (tar/tgz/zip). Default is 0. | 362 | 364 |
| 363 | 365 | __CAUTION for zip.UncompressStream__ | 364 | 366 |
| |
Collapse file Copy file name to clipboardExpand all lines: lib/utils.js +5-1Lines changed: 5 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -104,6 +104,10 @@ exports.makeUncompressFn = StreamClass => { | 104 | 104 | throw error; | 105 | 105 | } | 106 | 106 |
| | 107 | + const strip = opts.strip ? Number(opts.strip) : 0; | | 108 | + // Strip is handled here in makeUncompressFn, so remove it from opts to avoid passing to UncompressStream | | 109 | + delete opts.strip; | | 110 | + | 107 | 111 | return new Promise((resolve, reject) => { | 108 | 112 | fs.mkdir(destDir, { recursive: true }, err => { | 109 | 113 | if (err) return reject(err); | @@ -127,7 +131,7 @@ exports.makeUncompressFn = StreamClass => { | 127 | 131 | .on('error', reject) | 128 | 132 | .on('entry', (header, stream, next) => { | 129 | 133 | stream.on('end', next); | 130 | | - const destFilePath = path.join(resolvedDestDir, header.name); | | 134 | + const destFilePath = path.join(resolvedDestDir, stripFileName(strip, header.name, header.type)); | 131 | 135 | const resolvedDestPath = path.resolve(destFilePath); | 132 | 136 |
| 133 | 137 | // Security: Validate that the entry path doesn't escape the destination directory | |
Collapse file Copy file name to clipboardExpand all lines: test/tar/index.test.js +23Lines changed: 23 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -226,5 +226,28 @@ describe('test/tar/index.test.js', () => { | 226 | 226 | assert(originStat.mode); | 227 | 227 | assert(destStat.mode); | 228 | 228 | }); | | 229 | + | | 230 | + it('tar.uncompress(sourceFile, destDir) with strip 1', async () => { | | 231 | + const sourceFile = path.join(__dirname, '..', 'fixtures', 'xxx.tar'); | | 232 | + const destDir = path.join(os.tmpdir(), uuid.v4()); | | 233 | + const originalDir = path.join(__dirname, '..', 'fixtures', 'xxx'); | | 234 | + await compressing.tar.uncompress(sourceFile, destDir, { strip: 1 }); | | 235 | + const res = dircompare.compareSync(originalDir, destDir); | | 236 | + assert.equal(res.distinct, 0, 'distinct files count mismatch'); | | 237 | + assert.equal(res.equal, 5, 'equal files count mismatch'); | | 238 | + assert(res.totalFiles === 4); | | 239 | + assert(res.totalDirs === 1); | | 240 | + }); | | 241 | + | | 242 | + it('tar.uncompress(sourceFile, destDir) with strip 2', async () => { | | 243 | + const sourceFile = path.join(__dirname, '..', 'fixtures', 'xxx.tar'); | | 244 | + const destDir = path.join(os.tmpdir(), uuid.v4()); | | 245 | + await compressing.tar.uncompress(sourceFile, destDir, { strip: 2 }); | | 246 | + const res = dircompare.compareSync(path.join(__dirname, '..', 'fixtures', 'xxx-strip2'), destDir); | | 247 | + assert.equal(res.distinct, 0); | | 248 | + assert.equal(res.equal, 4); | | 249 | + assert(res.totalFiles === 4); | | 250 | + assert(res.totalDirs === 0); | | 251 | + }); | 229 | 252 | }); | 230 | 253 | }); |
Collapse file Copy file name to clipboardExpand all lines: test/tgz/index.test.js +23Lines changed: 23 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -221,5 +221,28 @@ describe('test/tgz/index.test.js', () => { | 221 | 221 | assert(res.totalFiles === 4); | 222 | 222 | assert(res.totalDirs === 1); | 223 | 223 | }); | | 224 | + | | 225 | + it('tgz.uncompress(sourceFile, destDir) with strip 1', async () => { | | 226 | + const sourceFile = path.join(__dirname, '..', 'fixtures', 'xxx.tgz'); | | 227 | + const destDir = path.join(os.tmpdir(), uuid.v4()); | | 228 | + const originalDir = path.join(__dirname, '..', 'fixtures', 'xxx'); | | 229 | + await compressing.tgz.uncompress(sourceFile, destDir, { strip: 1 }); | | 230 | + const res = dircompare.compareSync(originalDir, destDir); | | 231 | + assert.equal(res.distinct, 0, 'distinct files count mismatch'); | | 232 | + assert.equal(res.equal, 5, 'equal files count mismatch'); | | 233 | + assert(res.totalFiles === 4); | | 234 | + assert(res.totalDirs === 1); | | 235 | + }); | | 236 | + | | 237 | + it('tgz.uncompress(sourceFile, destDir) with strip 2', async () => { | | 238 | + const sourceFile = path.join(__dirname, '..', 'fixtures', 'xxx.tgz'); | | 239 | + const destDir = path.join(os.tmpdir(), uuid.v4()); | | 240 | + await compressing.tgz.uncompress(sourceFile, destDir, { strip: 2 }); | | 241 | + const res = dircompare.compareSync(path.join(__dirname, '..', 'fixtures', 'xxx-strip2'), destDir); | | 242 | + assert.equal(res.distinct, 0); | | 243 | + assert.equal(res.equal, 4); | | 244 | + assert(res.totalFiles === 4); | | 245 | + assert(res.totalDirs === 0); | | 246 | + }); | 224 | 247 | }); | 225 | 248 | }); |
Collapse file Copy file name to clipboardExpand all lines: test/zip/index.test.js +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -288,7 +288,7 @@ describe('test/zip/index.test.js', () => { | 288 | 288 | fs.mkdirSync(destDir, { recursive: true }); | 289 | 289 | await compressing.zip.uncompress(destFile, destDir); | 290 | 290 | const stat = fs.statSync(path.join(destDir, 'bin')); | 291 | | - assert(stat.mode === originStat.mode); | | 291 | + assert.equal(stat.mode, originStat.mode, 'file mode should be same after uncompress'); | 292 | 292 | // console.log(destDir); | 293 | 293 | }); | 294 | 294 | }); |
|