11cb0ef41Sopenharmony_ci'use strict'
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci// tar -c
41cb0ef41Sopenharmony_ciconst hlo = require('./high-level-opt.js')
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ciconst Pack = require('./pack.js')
71cb0ef41Sopenharmony_ciconst fsm = require('fs-minipass')
81cb0ef41Sopenharmony_ciconst t = require('./list.js')
91cb0ef41Sopenharmony_ciconst path = require('path')
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_cimodule.exports = (opt_, files, cb) => {
121cb0ef41Sopenharmony_ci  if (typeof files === 'function') {
131cb0ef41Sopenharmony_ci    cb = files
141cb0ef41Sopenharmony_ci  }
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci  if (Array.isArray(opt_)) {
171cb0ef41Sopenharmony_ci    files = opt_, opt_ = {}
181cb0ef41Sopenharmony_ci  }
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci  if (!files || !Array.isArray(files) || !files.length) {
211cb0ef41Sopenharmony_ci    throw new TypeError('no files or directories specified')
221cb0ef41Sopenharmony_ci  }
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci  files = Array.from(files)
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci  const opt = hlo(opt_)
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci  if (opt.sync && typeof cb === 'function') {
291cb0ef41Sopenharmony_ci    throw new TypeError('callback not supported for sync tar functions')
301cb0ef41Sopenharmony_ci  }
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  if (!opt.file && typeof cb === 'function') {
331cb0ef41Sopenharmony_ci    throw new TypeError('callback only supported with file option')
341cb0ef41Sopenharmony_ci  }
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci  return opt.file && opt.sync ? createFileSync(opt, files)
371cb0ef41Sopenharmony_ci    : opt.file ? createFile(opt, files, cb)
381cb0ef41Sopenharmony_ci    : opt.sync ? createSync(opt, files)
391cb0ef41Sopenharmony_ci    : create(opt, files)
401cb0ef41Sopenharmony_ci}
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ciconst createFileSync = (opt, files) => {
431cb0ef41Sopenharmony_ci  const p = new Pack.Sync(opt)
441cb0ef41Sopenharmony_ci  const stream = new fsm.WriteStreamSync(opt.file, {
451cb0ef41Sopenharmony_ci    mode: opt.mode || 0o666,
461cb0ef41Sopenharmony_ci  })
471cb0ef41Sopenharmony_ci  p.pipe(stream)
481cb0ef41Sopenharmony_ci  addFilesSync(p, files)
491cb0ef41Sopenharmony_ci}
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ciconst createFile = (opt, files, cb) => {
521cb0ef41Sopenharmony_ci  const p = new Pack(opt)
531cb0ef41Sopenharmony_ci  const stream = new fsm.WriteStream(opt.file, {
541cb0ef41Sopenharmony_ci    mode: opt.mode || 0o666,
551cb0ef41Sopenharmony_ci  })
561cb0ef41Sopenharmony_ci  p.pipe(stream)
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci  const promise = new Promise((res, rej) => {
591cb0ef41Sopenharmony_ci    stream.on('error', rej)
601cb0ef41Sopenharmony_ci    stream.on('close', res)
611cb0ef41Sopenharmony_ci    p.on('error', rej)
621cb0ef41Sopenharmony_ci  })
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  addFilesAsync(p, files)
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  return cb ? promise.then(cb, cb) : promise
671cb0ef41Sopenharmony_ci}
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ciconst addFilesSync = (p, files) => {
701cb0ef41Sopenharmony_ci  files.forEach(file => {
711cb0ef41Sopenharmony_ci    if (file.charAt(0) === '@') {
721cb0ef41Sopenharmony_ci      t({
731cb0ef41Sopenharmony_ci        file: path.resolve(p.cwd, file.slice(1)),
741cb0ef41Sopenharmony_ci        sync: true,
751cb0ef41Sopenharmony_ci        noResume: true,
761cb0ef41Sopenharmony_ci        onentry: entry => p.add(entry),
771cb0ef41Sopenharmony_ci      })
781cb0ef41Sopenharmony_ci    } else {
791cb0ef41Sopenharmony_ci      p.add(file)
801cb0ef41Sopenharmony_ci    }
811cb0ef41Sopenharmony_ci  })
821cb0ef41Sopenharmony_ci  p.end()
831cb0ef41Sopenharmony_ci}
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ciconst addFilesAsync = (p, files) => {
861cb0ef41Sopenharmony_ci  while (files.length) {
871cb0ef41Sopenharmony_ci    const file = files.shift()
881cb0ef41Sopenharmony_ci    if (file.charAt(0) === '@') {
891cb0ef41Sopenharmony_ci      return t({
901cb0ef41Sopenharmony_ci        file: path.resolve(p.cwd, file.slice(1)),
911cb0ef41Sopenharmony_ci        noResume: true,
921cb0ef41Sopenharmony_ci        onentry: entry => p.add(entry),
931cb0ef41Sopenharmony_ci      }).then(_ => addFilesAsync(p, files))
941cb0ef41Sopenharmony_ci    } else {
951cb0ef41Sopenharmony_ci      p.add(file)
961cb0ef41Sopenharmony_ci    }
971cb0ef41Sopenharmony_ci  }
981cb0ef41Sopenharmony_ci  p.end()
991cb0ef41Sopenharmony_ci}
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ciconst createSync = (opt, files) => {
1021cb0ef41Sopenharmony_ci  const p = new Pack.Sync(opt)
1031cb0ef41Sopenharmony_ci  addFilesSync(p, files)
1041cb0ef41Sopenharmony_ci  return p
1051cb0ef41Sopenharmony_ci}
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ciconst create = (opt, files) => {
1081cb0ef41Sopenharmony_ci  const p = new Pack(opt)
1091cb0ef41Sopenharmony_ci  addFilesAsync(p, files)
1101cb0ef41Sopenharmony_ci  return p
1111cb0ef41Sopenharmony_ci}
112