Blame view

node_modules/tar/lib/extract.js 2.5 KB
aaac7fed   liuqimichale   add
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
  // give it a tarball and a path, and it'll dump the contents
  
  module.exports = Extract
  
  var tar = require("../tar.js")
    , fstream = require("fstream")
    , inherits = require("inherits")
    , path = require("path")
  
  function Extract (opts) {
    if (!(this instanceof Extract)) return new Extract(opts)
    tar.Parse.apply(this)
  
    if (typeof opts !== "object") {
      opts = { path: opts }
    }
  
    // better to drop in cwd? seems more standard.
    opts.path = opts.path || path.resolve("node-tar-extract")
    opts.type = "Directory"
    opts.Directory = true
  
    // similar to --strip or --strip-components
    opts.strip = +opts.strip
    if (!opts.strip || opts.strip <= 0) opts.strip = 0
  
    this._fst = fstream.Writer(opts)
  
    this.pause()
    var me = this
  
    // Hardlinks in tarballs are relative to the root
    // of the tarball.  So, they need to be resolved against
    // the target directory in order to be created properly.
    me.on("entry", function (entry) {
      // if there's a "strip" argument, then strip off that many
      // path components.
      if (opts.strip) {
        var p = entry.path.split("/").slice(opts.strip).join("/")
        entry.path = entry.props.path = p
        if (entry.linkpath) {
          var lp = entry.linkpath.split("/").slice(opts.strip).join("/")
          entry.linkpath = entry.props.linkpath = lp
        }
      }
      if (entry.type === "Link") {
        entry.linkpath = entry.props.linkpath =
          path.join(opts.path, path.join("/", entry.props.linkpath))
      }
  
      if (entry.type === "SymbolicLink") {
        var dn = path.dirname(entry.path) || ""
        var linkpath = entry.props.linkpath
        var target = path.resolve(opts.path, dn, linkpath)
        if (target.indexOf(opts.path) !== 0) {
          linkpath = path.join(opts.path, path.join("/", linkpath))
        }
        entry.linkpath = entry.props.linkpath = linkpath
      }
    })
  
    this._fst.on("ready", function () {
      me.pipe(me._fst, { end: false })
      me.resume()
    })
  
    this._fst.on('error', function(err) {
      me.emit('error', err)
    })
  
    this._fst.on('drain', function() {
      me.emit('drain')
    })
  
    // this._fst.on("end", function () {
    //   console.error("\nEEEE Extract End", me._fst.path)
    // })
  
    this._fst.on("close", function () {
      // console.error("\nEEEE Extract End", me._fst.path)
      me.emit("finish")
      me.emit("end")
      me.emit("close")
    })
  }
  
  inherits(Extract, tar.Parse)
  
  Extract.prototype._streamEnd = function () {
    var me = this
    if (!me._ended || me._entry) me.error("unexpected eof")
    me._fst.end()
    // my .end() is coming later.
  }