-
-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathindex.js
executable file
·126 lines (101 loc) · 3.1 KB
/
index.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
module.exports = zelda
var cp = require('child_process')
var findRoot = require('find-root')
var fs = require('fs')
var path = require('path')
var rimraf = require('rimraf')
var NPM_EXEC = process.platform === 'win32'
? 'npm.cmd'
: 'npm'
function zelda (rootPath, opts) {
if (!opts) opts = {}
// Use folder with nearest package.json as root
rootPath = findRoot(rootPath)
var rootName = require(path.join(rootPath, 'package.json')).name
var codePath = path.resolve(rootPath, '..')
if (!rootName) throw new Error('root package must have a name ')
// add node_modules symlink in code folder - magic!
try {
console.log('[zelda] cd ' + codePath + ' && ln -s . node_modules')
if (!opts['dry-run']) fs.symlinkSync('.', path.join(codePath, 'node_modules'), 'dir')
} catch (err) {
// ignore err (symlink already exists)
}
// get packages in code folder
var codePkgs = getCodePkgs(codePath)
if (opts.install) npmInstall(rootPath)
var pkgsToPurge = {}
pkgsToPurge[rootName] = true
traverseNodeModules(rootPath, function (pkgName, pkgPath) {
if (codePkgs[pkgName]) {
pkgsToPurge[pkgName] = true
if (opts.install) npmInstall(path.join(codePath, pkgName))
}
})
traverseNodeModules(rootPath, function (pkgName, pkgPath) {
if (pkgsToPurge[pkgName]) {
rmDir(pkgPath)
}
})
Object.keys(pkgsToPurge).forEach(function (pkgToPurge) {
if (pkgToPurge === rootName) return
var pkgPath = path.join(codePath, pkgToPurge)
traverseNodeModules(pkgPath, function (pkgName, pkgPath) {
if (pkgsToPurge[pkgName]) rmDir(pkgPath)
})
})
function rmDir (dirPath) {
console.log('[zelda] rm -rf ' + dirPath)
if (!opts['dry-run']) rimraf.sync(dirPath)
}
function npmInstall (pkgPath) {
console.log('[zelda] cd ' + pkgPath + ' && rm node_modules/ && npm install')
var args = ['install']
if (opts.production) args.push('--production')
if (!opts['dry-run']) {
rimraf.sync(path.join(pkgPath, 'node_modules'))
cp.spawnSync(NPM_EXEC, args, {
cwd: pkgPath,
stdio: 'inherit'
})
}
}
}
function getCodePkgs (codePath) {
var entries
try {
entries = fs.readdirSync(codePath)
} catch (err) {
throw new Error('Could not find ' + codePath + '. ' + err.message)
}
var pkgs = {}
entries.forEach(function (entry) {
var pkgPath = path.join(codePath, entry)
var pkg
try {
pkg = require(path.join(pkgPath, 'package.json'))
} catch (err) {
return // ignore folders without package.json
}
pkgs[pkg.name] = pkgPath
})
return pkgs
}
function traverseNodeModules (pkgPath, fn) {
var modulesPath = path.join(pkgPath, 'node_modules')
var entries
try {
entries = fs.readdirSync(modulesPath)
} catch (err) {
return // nothing to traverse (no node_modules)
}
entries = entries.filter(function (entry) {
var stat = fs.lstatSync(path.join(modulesPath, entry))
return !stat.isSymbolicLink()
})
entries.forEach(function (entry) {
var entryPath = path.join(modulesPath, entry)
traverseNodeModules(entryPath, fn)
fn(entry, entryPath)
})
}