# All files / tar/lib create.js

100% Statements 59/59
100% Branches 35/35
100% Functions 12/12
100% Lines 59/59

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106

    2x

    2x
    2x
    2x
    2x
    2x

    2x
    15x
    1x

    15x
    1x

    15x
    2x

    13x

    13x

    13x
    1x

    12x
    1x

    11x

    2x
    4x
    4x

    4x
    4x

    2x
    4x
    4x

    4x

    4x
    4x
    4x
    4x

    4x

    4x

    2x
    5x
    7x
    3x

    7x

    4x

    4x

    2x
    9x
    8x
    8x
    3x

    7x
    3x

    5x

    6x

    2x
    1x
    1x
    1x

    2x
    2x
    2x
    2x

     'use strict'

    // tar -c
    const hlo = require('./high-level-opt.js')

    const Pack = require('./pack.js')
    const fs = require('fs')
    const fsm = require('fs-minipass')
    const t = require('./list.js')
    const path = require('path')

    const c = module.exports = (opt_, files, cb) => {
      if (typeof files === 'function')
        cb = files

      if (Array.isArray(opt_))
        files = opt_, opt_ = {}

      if (!files || !Array.isArray(files) || !files.length)
        throw new TypeError('no files or directories specified')

      files = Array.from(files)

      const opt = hlo(opt_)

      if (opt.sync && typeof cb === 'function')
        throw new TypeError('callback not supported for sync tar functions')

      if (!opt.file && typeof cb === 'function')
        throw new TypeError('callback only supported with file option')

      return opt.file && opt.sync ? createFileSync(opt, files)
        : opt.file ? createFile(opt, files, cb)
        : opt.sync ? createSync(opt, files)
        : create(opt, files)
    }

    const createFileSync = (opt, files) => {
      const p = new Pack.Sync(opt)
      const stream = new fsm.WriteStreamSync(opt.file, {
        mode: opt.mode || 0o666
      })
      p.pipe(stream)
      addFilesSync(p, files)
    }

    const createFile = (opt, files, cb) => {
      const p = new Pack(opt)
      const stream = new fsm.WriteStream(opt.file, {
        mode: opt.mode || 0o666
      })
      p.pipe(stream)

      const promise = new Promise((res, rej) => {
        stream.on('error', rej)
        stream.on('close', res)
        p.on('error', rej)
      })

      addFilesAsync(p, files)

      return cb ? promise.then(cb, cb) : promise
    }

    const addFilesSync = (p, files) => {
      files.forEach(file => {
        if (file.charAt(0) === '@')
          t({
            file: path.resolve(p.cwd, file.substr(1)),
            sync: true,
            noResume: true,
            onentry: entry => p.add(entry)
          })
        else
          p.add(file)
      })
      p.end()
    }

    const addFilesAsync = (p, files) => {
      while (files.length) {
        const file = files.shift()
        if (file.charAt(0) === '@')
          return t({
            file: path.resolve(p.cwd, file.substr(1)),
            noResume: true,
            onentry: entry => p.add(entry)
          }).then(_ => addFilesAsync(p, files))
        else
          p.add(file)
      }
      p.end()
    }

    const createSync = (opt, files) => {
      const p = new Pack.Sync(opt)
      addFilesSync(p, files)
      return p
    }

    const create = (opt, files) => {
      const p = new Pack(opt)
      addFilesAsync(p, files)
      return p
    }