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
134
135
136
137
138
139
140
141
142
143
144
|
var fs = require('fs')
var path = require('path')
var util = require('util')
var semver = require('semver')
exports.checkEngine = checkEngine
function checkEngine (target, npmVer, nodeVer, force, strict, cb) {
var nodev = force ? null : nodeVer
var eng = target.engines
if (!eng) return cb()
if (nodev && eng.node && !semver.satisfies(nodev, eng.node) ||
eng.npm && !semver.satisfies(npmVer, eng.npm)) {
var er = new Error(util.format('Unsupported engine for %s: wanted: %j (current: %j)',
target._id, eng, {node: nodev, npm: npmVer}))
er.code = 'ENOTSUP'
er.required = eng
er.pkgid = target._id
if (strict) {
return cb(er)
} else {
return cb(null, er)
}
}
return cb()
}
exports.checkPlatform = checkPlatform
function checkPlatform (target, force, cb) {
var platform = process.platform
var arch = process.arch
var osOk = true
var cpuOk = true
if (force) {
return cb()
}
if (target.os) {
osOk = checkList(platform, target.os)
}
if (target.cpu) {
cpuOk = checkList(arch, target.cpu)
}
if (!osOk || !cpuOk) {
var er = new Error(util.format('Unsupported platform for %s: wanted %j (current: %j)',
target._id, target, {os: platform, cpu: arch}))
er.code = 'EBADPLATFORM'
er.os = target.os || ['any']
er.cpu = target.cpu || ['any']
er.pkgid = target._id
return cb(er)
}
return cb()
}
function checkList (value, list) {
var tmp
var match = false
var blc = 0
if (typeof list === 'string') {
list = [list]
}
if (list.length === 1 && list[0] === 'any') {
return true
}
for (var i = 0; i < list.length; ++i) {
tmp = list[i]
if (tmp[0] === '!') {
tmp = tmp.slice(1)
if (tmp === value) {
return false
}
++blc
} else {
match = match || tmp === value
}
}
return match || blc === list.length
}
exports.checkCycle = checkCycle
function checkCycle (target, ancestors, cb) {
// there are some very rare and pathological edge-cases where
// a cycle can cause npm to try to install a never-ending tree
// of stuff.
// Simplest:
//
// A -> B -> A' -> B' -> A -> B -> A' -> B' -> A -> ...
//
// Solution: Simply flat-out refuse to install any name@version
// that is already in the prototype tree of the ancestors object.
// A more correct, but more complex, solution would be to symlink
// the deeper thing into the new location.
// Will do that if anyone whines about this irl.
//
// Note: `npm install foo` inside of the `foo` package will abort
// earlier if `--force` is not set. However, if it IS set, then
// we need to still fail here, but just skip the first level. Of
// course, it'll still fail eventually if it's a true cycle, and
// leave things in an undefined state, but that's what is to be
// expected when `--force` is used. That is why getPrototypeOf
// is used *twice* here: to skip the first level of repetition.
var p = Object.getPrototypeOf(Object.getPrototypeOf(ancestors))
var name = target.name
var version = target.version
while (p && p !== Object.prototype && p[name] !== version) {
p = Object.getPrototypeOf(p)
}
if (p[name] !== version) return cb()
var er = new Error(target._id + ': Unresolvable cycle detected')
var tree = [target._id, JSON.parse(JSON.stringify(ancestors))]
var t = Object.getPrototypeOf(ancestors)
while (t && t !== Object.prototype) {
if (t === p) t.THIS_IS_P = true
tree.push(JSON.parse(JSON.stringify(t)))
t = Object.getPrototypeOf(t)
}
er.pkgid = target._id
er.code = 'ECYCLE'
return cb(er)
}
exports.checkGit = checkGit
function checkGit (folder, cb) {
// if it's a git repo then don't touch it!
fs.lstat(folder, function (er, s) {
if (er || !s.isDirectory()) return cb()
else checkGit_(folder, cb)
})
}
function checkGit_ (folder, cb) {
fs.stat(path.resolve(folder, '.git'), function (er, s) {
if (!er && s.isDirectory()) {
var e = new Error(folder + ': Appears to be a git repo or submodule.')
e.path = folder
e.code = 'EISGIT'
return cb(e)
}
cb()
})
}
|