Skip to content

Commit 336fa8f

Browse files
JamieMageeisaacs
authored andcommitted
refactor: dry and other pr comments
PR-URL: #391 Credit: @JamieMagee Close: #391 Reviewed-by: @isaacs
1 parent eeba222 commit 336fa8f

File tree

5 files changed

+65
-36
lines changed

5 files changed

+65
-36
lines changed

lib/pack.js

+16-14
Original file line numberDiff line numberDiff line change
@@ -79,23 +79,25 @@ const Pack = warner(class Pack extends Minipass {
7979

8080
this.portable = !!opt.portable
8181
this.zip = null
82-
if (opt.gzip) {
83-
if (typeof opt.gzip !== 'object') {
84-
opt.gzip = {}
82+
if (opt.gzip || opt.brotli) {
83+
if (opt.gzip && opt.brotli) {
84+
throw new TypeError('gzip and brotli are mutually exclusive')
8585
}
86-
if (this.portable) {
87-
opt.gzip.portable = true
86+
if (opt.gzip) {
87+
if (typeof opt.gzip !== 'object') {
88+
opt.gzip = {}
89+
}
90+
if (this.portable) {
91+
opt.gzip.portable = true
92+
}
93+
this.zip = new zlib.Gzip(opt.gzip)
8894
}
89-
this.zip = new zlib.Gzip(opt.gzip)
90-
this.zip.on('data', chunk => super.write(chunk))
91-
this.zip.on('end', _ => super.end())
92-
this.zip.on('drain', _ => this[ONDRAIN]())
93-
this.on('resume', _ => this.zip.resume())
94-
} else if (opt.brotli) {
95-
if (typeof opt.brotli !== 'object') {
96-
opt.brotli = {}
95+
if (opt.brotli) {
96+
if (typeof opt.brotli !== 'object') {
97+
opt.brotli = {}
98+
}
99+
this.zip = new zlib.BrotliCompress(opt.brotli)
97100
}
98-
this.zip = new zlib.BrotliCompress(opt.brotli)
99101
this.zip.on('data', chunk => super.write(chunk))
100102
this.zip.on('end', _ => super.end())
101103
this.zip.on('drain', _ => this[ONDRAIN]())

lib/parse.js

+4-18
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ module.exports = warner(class Parser extends EE {
9999
this.filter = typeof opt.filter === 'function' ? opt.filter : noop
100100
// Unlike gzip, brotli doesn't have any magic bytes to identify it
101101
// Users need to explicitly tell us they're extracting a brotli file
102-
this.brotli = opt.brotli
102+
// Or we infer from the file extension
103+
this.brotli = opt.brotli || (opt.file && (opt.file.endsWith('.tar.br') || opt.file.endsWith('.tbr')))
103104

104105
// have to set this so that streams are ok piping into it
105106
this.writable = true
@@ -359,30 +360,15 @@ module.exports = warner(class Parser extends EE {
359360
this[BUFFER] = chunk
360361
return true
361362
}
362-
if (this[UNZIP] === null && this.brotli) {
363-
const ended = this[ENDED]
364-
this[ENDED] = false
365-
this[UNZIP] = new zlib.BrotliDecompress()
366-
this[UNZIP].on('data', chunk => this[CONSUMECHUNK](chunk))
367-
this[UNZIP].on('error', er => this.abort(er))
368-
this[UNZIP].on('end', _ => {
369-
this[ENDED] = true
370-
this[CONSUMECHUNK]()
371-
})
372-
this[WRITING] = true
373-
const ret = this[UNZIP][ended ? 'end' : 'write'](chunk)
374-
this[WRITING] = false
375-
return ret
376-
}
377363
for (let i = 0; this[UNZIP] === null && i < gzipHeader.length; i++) {
378364
if (chunk[i] !== gzipHeader[i]) {
379365
this[UNZIP] = false
380366
}
381367
}
382-
if (this[UNZIP] === null) {
368+
if (this[UNZIP] === null || (this[UNZIP] === false && this.brotli)) {
383369
const ended = this[ENDED]
384370
this[ENDED] = false
385-
this[UNZIP] = new zlib.Unzip()
371+
this[UNZIP] = this.brotli ? new zlib.BrotliDecompress() : new zlib.Unzip()
386372
this[UNZIP].on('data', chunk => this[CONSUMECHUNK](chunk))
387373
this[UNZIP].on('error', er => this.abort(er))
388374
this[UNZIP].on('end', _ => {

test/extract.js

+17-4
Original file line numberDiff line numberDiff line change
@@ -323,12 +323,25 @@ t.test('brotli', async t => {
323323
await rimraf(dir)
324324
})
325325

326-
t.test('fails if brotli', async t => {
327-
const expect = new Error("TAR_BAD_ARCHIVE: Unrecognized archive format")
328-
t.throws(_ => x({ sync: true, file: file }), expect)
326+
t.test('fails if unknown file extension', async t => {
327+
const filename = path.resolve(__dirname, 'brotli/example.unknown')
328+
const f = fs.openSync(filename, 'a')
329+
fs.closeSync(f)
330+
331+
const expect = new Error('TAR_BAD_ARCHIVE: Unrecognized archive format')
332+
333+
t.throws(_ => x({ sync: true, file: filename }), expect)
334+
})
335+
336+
t.test('succeeds based on file extension', t => {
337+
x({ sync: true, file: file, C: dir })
338+
339+
t.same(fs.readdirSync(dir + '/x').sort(),
340+
['1', '10', '2', '3', '4', '5', '6', '7', '8', '9'])
341+
t.end()
329342
})
330343

331-
t.test('succeeds', t => {
344+
t.test('succeeds when passed explicit option', t => {
332345
x({ sync: true, file: file, C: dir, brotli: true })
333346

334347
t.same(fs.readdirSync(dir + '/x').sort(),

test/pack.js

+6
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,12 @@ t.test('if brotli is truthy, make it an object', t => {
382382
t.end()
383383
})
384384

385+
t.test('throws if both gzip and brotli are truthy', t => {
386+
const opt = { gzip: true, brotli: true }
387+
t.throws(_ => new Pack(opt), new TypeError('gzip and brotli are mutually exclusive'))
388+
t.end()
389+
})
390+
385391
t.test('gzip, also a very deep path', t => {
386392
const out = []
387393

test/parse.js

+22
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,28 @@ t.test('fixture tests', t => {
125125
bs.end(zlib.gzipSync(tardata))
126126
})
127127

128+
t.test('compress with brotli based on filename .tar.br', t => {
129+
const p = new Parse({
130+
maxMetaEntrySize: maxMeta,
131+
filter: filter ? (path, entry) => entry.size % 2 !== 0 : null,
132+
strict: strict,
133+
file: 'example.tar.br',
134+
})
135+
trackEvents(t, expect, p)
136+
p.end(zlib.brotliCompressSync(tardata))
137+
})
138+
139+
t.test('compress with brotli based on filename .tbr', t => {
140+
const p = new Parse({
141+
maxMetaEntrySize: maxMeta,
142+
filter: filter ? (path, entry) => entry.size % 2 !== 0 : null,
143+
strict: strict,
144+
file: 'example.tbr',
145+
})
146+
trackEvents(t, expect, p)
147+
p.end(zlib.brotliCompressSync(tardata))
148+
})
149+
128150
t.test('compress with brotli all at once', t => {
129151
const p = new Parse({
130152
maxMetaEntrySize: maxMeta,

0 commit comments

Comments
 (0)