Welcome to mirror list, hosted at ThFree Co, Russian Federation.

lifecycle.js « utils « lib - github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 66b94f699cf5ed16dce7f92d5f8a5f6260d61ffb (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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

exports = module.exports = lifecycle
exports.cmd = cmd

var log = require("./log")
  , exec = require("./exec")
  , npm = require("../../npm")
  , path = require("path")
  , readJson = require("./read-json")
  , fs = require("./graceful-fs")

function lifecycle (pkg, stage, cb) {
  while (pkg && pkg._data) pkg = pkg._data
  if (!pkg) return cb(new Error("Invalid package data"))
  log.verbose(pkg._id, "lifecycle "+stage)
  if (!pkg.scripts || !(stage in pkg.scripts)) return cb()

  // run package lifecycle scripts in the package root, or the nearest parent.
  var d = path.join(npm.dir, pkg.name, pkg.version, "package")
  while (d) {
    try {
      process.chdir(d)
      break
    } catch (ex) {
      d = path.dirname(d)
    }
  }
  log(pkg._id, stage)

  // set the env variables, then run the script as a child process.
  // NOTE: The env vars won't work until node supports env hashes for child procs
  var env = makeEnv(pkg)
  env.npm_lifecycle_event = stage
  env.npm_lifecycle_script = pkg.scripts[stage]
  log.silly(env, "lifecycle env")
  exec("sh", ["-c", env.npm_lifecycle_script], env, function (er) {
    if (er && !npm.ROLLBACK) {
      log("Failed to exec "+stage+" script", pkg._id)
      er.message = pkg._id + " " + stage + ": `" + env.npm_lifecycle_script+"`\n"
                 + er.message
      return cb(er)
    } else if (er) {
      log.error(er, pkg._id+"."+stage+" failed")
    }
    // check for a hook script
    var hook = path.join(npm.dir, ".hooks", stage)
    fs.stat(hook, function (er) {
      if (er) return cb()
      exec(hook, env, function (er) {
        if (er) log("Failed to exec "+stage+" hook script", pkg._id)
        if (npm.ROLLBACK) return cb()
        cb(er)
      })
    })
  })
}

function makeEnv (data, prefix, env) {
  if (data._lifecycleEnv) return data._lifecycleEnv
  prefix = prefix || "npm_package_"
  if (!env) {
    env = {}
    for (var i in process.env) env[i] = process.env[i]
  } else {
    Object.defineProperty(data, "_lifecycleEnv",
      { value : env
      , enumerable : false
      })
  }

  for (var i in data) if (i.charAt(0) !== "_") {
    var envKey = (prefix+i).replace(/[^a-zA-Z0-9_]/g, '_')
    if (data[i] && typeof(data[i]) === "object") {
      env[envKey] = JSON.stringify(data[i])
      makeEnv(data[i], envKey+"_", env)
    } else {
      env[envKey] = String(data[i])
    }
  }
  if (prefix !== "npm_package_") return env
  prefix = "npm_config_"
  var conf = npm.config.get()
  for (var i in conf) if (i.charAt(0) !== "_") {
    var envKey = (prefix+i).replace(/[^a-zA-Z0-9_]/g, '_')
    env[envKey] = String(conf[i])
  }
  return env
}

function cmd (stage, req) { return function (args, cb_) {
  var d = args.length
  function cb (er) {
    if (er) return cb_(er)
    if (-- d === 0) return cb_()
  }
  args.forEach(function (arg) {
    var pkg = arg.split("@")
      , name = pkg.shift()
      , ver = pkg.join("@")
      , json = path.join(npm.dir, name, ver || "active", "package/package.json")
    readJson(json, function (er, data) {
      if (er) return log.er(cb, "Couldn't find "+name + "@" + ver)(er)
      if (ver && ver !== data.version) {
        data.version = ver
        data._id = data.name+"-"+ver
      }
      if ( !data.scripts
          || !(stage in data.scripts)
          && !("pre"+stage in data.scripts)) {
        log("Nothing to do", stage)
        return cb(req ? new Error("Nothing to do") : null)
      }
      lifecycle(data, "pre"+stage, function (er) {
        if (er) return log.er(cb, "Failed pre"+stage)(er)
        lifecycle(data, stage, cb)
      })
    })
  })
}}