forked from npm/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlink.js
133 lines (120 loc) · 3.84 KB
/
link.js
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// link with no args: symlink the folder to the global location
// link with package arg: symlink the global to the local
var npm = require("../npm")
, symlink = require("./utils/link")
, fs = require("./utils/graceful-fs")
, log = require("./utils/log")
, asyncMap = require("./utils/async-map")
, chain = require("./utils/chain")
, path = require("path")
, relativize = require("./utils/relativize")
, rm = require("./utils/rm-rf")
, output = require("./utils/output")
module.exports = link
link.usage = "npm link (in package dir)"
+ "\nnpm link <pkg> (link global into local)"
link.completion = function (opts, cb) {
var dir = path.join(npm.config.get("prefix"), "lib", "node_modules")
fs.readdir(dir, function (er, files) {
cb(er, files.filter(function (f) {
return f.charAt(0) !== "."
}))
})
}
function link (args, cb) {
if (npm.config.get("global")) {
return cb(new Error("link should never be --global.\n"
+"Please re-run this command with --local"))
}
if (args.length) return linkInstall(args, cb)
linkPkg(npm.prefix, cb)
}
function linkInstall (pkgs, cb) {
var gp = npm.config.get("prefix")
asyncMap(pkgs, function (pkg, cb) {
function n (er, data) {
if (er) return cb(er, data)
pp = data[0][0]
pkg = path.basename(pp)
target = path.resolve(npm.dir, pkg)
next()
}
var t = path.resolve(gp, "lib")
, pp = path.resolve(t, "node_modules", pkg)
, rp = null
, target = path.resolve(npm.dir, pkg)
// if it's a folder or a random not-installed thing, then
// link or install it first
if (pkg.indexOf("/") !== -1 || pkg.indexOf("\\") !== -1) {
return fs.lstat(path.resolve(pkg), function (er, st) {
if (er || !st.isDirectory()) {
npm.commands.install(t, pkg, n)
} else {
rp = path.resolve(pkg)
linkPkg(rp, n)
}
})
}
fs.lstat(pp, function (er, st) {
if (er) {
log.error(pkg, "not installed globally")
rp = pp
return npm.commands.install(t, pkg, n)
} else if (!st.isSymbolicLink()) {
rp = pp
next()
} else {
return fs.realpath(pp, function (er, real) {
if (er) log.warn(pkg, "invalid symbolic link")
else rp = real
next()
})
}
})
function next () {
chain
( [npm.commands, "unbuild", [target]]
, [log.verbose, "symlinking " + pp + " to "+target, "link"]
, [symlink, pp, target]
, rp && [npm.commands, "build", [target]]
, [ resultPrinter, pkg, pp, target, rp ]
, cb )
}
}, cb)
}
function linkPkg (folder, cb_) {
var gp = npm.config.get("prefix")
, me = folder || npm.prefix
, readJson = require("./utils/read-json")
readJson(path.resolve(me, "package.json"), function (er, d) {
function cb (er) {
return cb_(er, [[target, d && d._id]])
}
if (er) return cb(er)
var target = path.resolve(gp, "lib", "node_modules", d.name)
rm(target, function (er) {
if (er) return cb(er)
symlink(me, target, function (er) {
if (er) return cb(er)
log.verbose(target, "link: build target")
// also install missing dependencies.
npm.commands.install(me, [], function (er, installed) {
if (er) return cb(er)
npm.commands.build([target], true, function (er) {
if (er) return cb(er)
resultPrinter(path.basename(me), me, target, cb)
})
})
})
})
})
}
function resultPrinter (pkg, src, dest, rp, cb) {
if (typeof cb !== "function") cb = rp, rp = null
var where = relativize(dest, path.resolve(process.cwd(),"x"))
rp = (rp || "").trim()
src = (src || "").trim()
if (rp === src) rp = null
output.write(where+" -> "+(src.trim())
+(rp ? " -> "+rp: ""), cb)
}