| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- 'use strict';
- const fs = require('fs');
- const path = require('path');
- const stream = require('stream');
- const tar = require('tar-stream');
- const utils = require('../utils');
- const ready = require('get-ready');
- class TarFileStream extends stream.Transform {
- constructor(opts) {
- super(opts);
- const pack = tar.pack();
- pack.on('data', chunk => this.push(chunk));
- pack.on('end', () => this.ready(true));
- const sourceType = utils.sourceType(opts.source);
- if (sourceType === 'file') {
- // stat file to get file size
- fs.stat(opts.source, (err, stat) => {
- if (err) return this.emit('error', err);
- this.entry = pack.entry({ name: opts.relativePath || path.basename(opts.source), size: stat.size, mode: stat.mode & 0o777 }, err => {
- if (err) return this.emit('error', err);
- pack.finalize();
- });
- const stream = fs.createReadStream(opts.source, opts.fs);
- stream.on('error', err => this.emit('error', err));
- stream.pipe(this);
- });
- } else if (sourceType === 'buffer') {
- if (!opts.relativePath) return this.emit('error', 'opts.relativePath is required if opts.source is a buffer');
- pack.entry({ name: opts.relativePath }, opts.source);
- pack.finalize();
- this.end();
- } else { // stream or undefined
- if (!opts.relativePath) return process.nextTick(() => this.emit('error', 'opts.relativePath is required'));
- if (opts.size) {
- this.entry = pack.entry({ name: opts.relativePath, size: opts.size }, err => {
- if (err) return this.emit('error', err);
- pack.finalize();
- });
- } else {
- if (!opts.suppressSizeWarning) {
- console.warn('You should specify the size of streamming data by opts.size to prevent all streaming data from loading into memory. If you are sure about memory cost, pass opts.suppressSizeWarning: true to suppress this warning');
- }
- const buf = [];
- this.entry = new stream.Writable({
- write(chunk, _, callback) {
- buf.push(chunk);
- callback();
- },
- });
- this.entry.on('finish', () => {
- pack.entry({ name: opts.relativePath }, Buffer.concat(buf));
- pack.finalize();
- });
- }
- if (sourceType === 'stream') {
- opts.source.on('error', err => this.emit('error', err));
- opts.source.pipe(this);
- }
- }
- }
- _transform(chunk, encoding, callback) {
- if (this.entry) {
- this.entry.write(chunk, encoding, callback);
- }
- }
- _flush(callback) {
- if (this.entry) {
- this.entry.end();
- }
- this.ready(callback);
- }
- }
- ready.mixin(TarFileStream.prototype);
- module.exports = TarFileStream;
|