1 | 'use strict'
|
2 |
|
3 | const BB = require('bluebird')
|
4 |
|
5 | const fs = require('fs')
|
6 | const getStream = require('get-stream')
|
7 | const mkdirp = BB.promisify(require('mkdirp'))
|
8 | const npa = require('npm-package-arg')
|
9 | const optCheck = require('./lib/util/opt-check.js')
|
10 | const PassThrough = require('stream').PassThrough
|
11 | const path = require('path')
|
12 | const rimraf = BB.promisify(require('rimraf'))
|
13 | const withTarballStream = require('./lib/with-tarball-stream.js')
|
14 |
|
15 | module.exports = tarball
|
16 | function tarball (spec, opts) {
|
17 | opts = optCheck(opts)
|
18 | spec = npa(spec, opts.where)
|
19 | return withTarballStream(spec, opts, stream => getStream.buffer(stream))
|
20 | }
|
21 |
|
22 | module.exports.stream = tarballStream
|
23 | function tarballStream (spec, opts) {
|
24 | opts = optCheck(opts)
|
25 | spec = npa(spec, opts.where)
|
26 | const output = new PassThrough()
|
27 | let hasTouchedOutput = false
|
28 | let lastError = null
|
29 | withTarballStream(spec, opts, stream => {
|
30 | if (hasTouchedOutput && lastError) {
|
31 | throw lastError
|
32 | } else if (hasTouchedOutput) {
|
33 | throw new Error('abort, abort!')
|
34 | } else {
|
35 | return new BB((resolve, reject) => {
|
36 | stream.on('error', reject)
|
37 | output.on('error', reject)
|
38 | output.on('error', () => { hasTouchedOutput = true })
|
39 | output.on('finish', resolve)
|
40 | stream.pipe(output)
|
41 | stream.once('data', () => { hasTouchedOutput = true })
|
42 | }).catch(err => {
|
43 | lastError = err
|
44 | throw err
|
45 | })
|
46 | }
|
47 | })
|
48 | .catch(err => output.emit('error', err))
|
49 | return output
|
50 | }
|
51 |
|
52 | module.exports.toFile = tarballToFile
|
53 | function tarballToFile (spec, dest, opts) {
|
54 | opts = optCheck(opts)
|
55 | spec = npa(spec, opts.where)
|
56 | return mkdirp(path.dirname(dest))
|
57 | .then(() => withTarballStream(spec, opts, stream => {
|
58 | return rimraf(dest)
|
59 | .then(() => new BB((resolve, reject) => {
|
60 | const writer = fs.createWriteStream(dest)
|
61 | stream.on('error', reject)
|
62 | writer.on('error', reject)
|
63 | writer.on('close', resolve)
|
64 | stream.pipe(writer)
|
65 | }))
|
66 | }))
|
67 | }
|