summaryrefslogtreecommitdiff
path: root/deps/npm/lib/submodule.js
blob: 9a2cffa9e13797f22ab5907b42a30b30ec2fe9b4 (plain)
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
// npm submodule <pkg>
// Check the package contents for a git repository url.
// If there is one, then create a git submodule in the node_modules folder.

module.exports = submodule

var npm = require("./npm.js")
  , readJson = require("./utils/read-json.js")
  , exec = require("./utils/exec.js")
  , output = require("./utils/output.js")
  , cache = require("./cache.js")
  , asyncMap = require("slide").asyncMap
  , chain = require("slide").chain

submodule.usage = "npm submodule <pkg>"

submodule.completion = require("./docs.js").completion

function submodule (args, cb) {
  if (npm.config.get("global")) {
    return cb(new Error("Cannot use submodule command in global mode."))
  }

  if (args.length === 0) return cb(submodule.usage)

  asyncMap(args, function (arg, cb) {
    cache.add(arg, cb)
  }, function (er, pkgs) {
    if (er) return cb(er)
    chain(pkgs.map(function (pkg) { return function (cb) {
      submodule_(pkg, cb)
    }}), cb)
  })

}

function submodule_ (pkg, cb) {
  if (!pkg.repository
      || pkg.repository.type !== "git"
      || !pkg.repository.url) {
    return cb(new Error(pkg._id + ": No git repository listed"))
  }

  // prefer https:// github urls
  pkg.repository.url = pkg.repository.url
    .replace(/^(git:\/\/)?(git@)?github.com[:\/]/, "https://github.com/")

  // first get the list of submodules, and update if it's already there.
  getSubmodules(function (er, modules) {
    if (er) return cb(er)
    // if there's already a submodule, then just update it.
    if (modules.indexOf(pkg.name) !== -1) {
      return updateSubmodule(pkg.name, cb)
    }
    addSubmodule(pkg.name, pkg.repository.url, cb)
  })
}

function updateSubmodule (name, cb) {
  exec( npm.config.get("git"), [ "submodule", "update", "--init"
               , "node_modules/" + name ]
      , null, true, npm.prefix, cb)
}

function addSubmodule (name, url, cb) {
  exec( npm.config.get("git"), [ "submodule", "add", url
               , "node_modules/" + name ]
      , null, true, npm.prefix, function (er) {
    if (er) return cb(er)
    updateSubmodule(name, cb)
  })
}


var getSubmodules = function getSubmodules (cb) {
  exec( npm.config.get("git"), ["submodule", "status"], null, false
      , npm.prefix, function (er, code, stdout, stderr) {
    if (er) return cb(er)
    res = stdout.trim().split(/\n/).map(function (line) {
      return line.trim().split(/\s+/)[1]
    }).filter(function (line) {
      // only care about submodules in the node_modules folder.
      return line && line.match(/^node_modules\//)
    }).map(function (line) {
      return line.replace(/^node_modules\//g, "")
    })

    // memoize.
    getSubmodules = function (cb) { return cb(null, res) }

    cb(null, res)
  })
}