• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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