1'use strict' 2 3// tar -c 4const hlo = require('./high-level-opt.js') 5 6const Pack = require('./pack.js') 7const fs = require('fs') 8const fsm = require('fs-minipass') 9const t = require('./list.js') 10const path = require('path') 11 12const c = module.exports = (opt_, files, cb) => { 13 if (typeof files === 'function') 14 cb = files 15 16 if (Array.isArray(opt_)) 17 files = opt_, opt_ = {} 18 19 if (!files || !Array.isArray(files) || !files.length) 20 throw new TypeError('no files or directories specified') 21 22 files = Array.from(files) 23 24 const opt = hlo(opt_) 25 26 if (opt.sync && typeof cb === 'function') 27 throw new TypeError('callback not supported for sync tar functions') 28 29 if (!opt.file && typeof cb === 'function') 30 throw new TypeError('callback only supported with file option') 31 32 return opt.file && opt.sync ? createFileSync(opt, files) 33 : opt.file ? createFile(opt, files, cb) 34 : opt.sync ? createSync(opt, files) 35 : create(opt, files) 36} 37 38const createFileSync = (opt, files) => { 39 const p = new Pack.Sync(opt) 40 const stream = new fsm.WriteStreamSync(opt.file, { 41 mode: opt.mode || 0o666 42 }) 43 p.pipe(stream) 44 addFilesSync(p, files) 45} 46 47const createFile = (opt, files, cb) => { 48 const p = new Pack(opt) 49 const stream = new fsm.WriteStream(opt.file, { 50 mode: opt.mode || 0o666 51 }) 52 p.pipe(stream) 53 54 const promise = new Promise((res, rej) => { 55 stream.on('error', rej) 56 stream.on('close', res) 57 p.on('error', rej) 58 }) 59 60 addFilesAsync(p, files) 61 62 return cb ? promise.then(cb, cb) : promise 63} 64 65const addFilesSync = (p, files) => { 66 files.forEach(file => { 67 if (file.charAt(0) === '@') 68 t({ 69 file: path.resolve(p.cwd, file.substr(1)), 70 sync: true, 71 noResume: true, 72 onentry: entry => p.add(entry) 73 }) 74 else 75 p.add(file) 76 }) 77 p.end() 78} 79 80const addFilesAsync = (p, files) => { 81 while (files.length) { 82 const file = files.shift() 83 if (file.charAt(0) === '@') 84 return t({ 85 file: path.resolve(p.cwd, file.substr(1)), 86 noResume: true, 87 onentry: entry => p.add(entry) 88 }).then(_ => addFilesAsync(p, files)) 89 else 90 p.add(file) 91 } 92 p.end() 93} 94 95const createSync = (opt, files) => { 96 const p = new Pack.Sync(opt) 97 addFilesSync(p, files) 98 return p 99} 100 101const create = (opt, files) => { 102 const p = new Pack(opt) 103 addFilesAsync(p, files) 104 return p 105} 106