You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

create.js 2.3KB

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