Skip to content

Commit a1dcccb

Browse files
committed
prune, shrinkwrap, list, fixes
Fixes: - `cli-prompt` replaces deprecated `prompt` method of `commander` - Use absolute junctions for XP, pending nodejs/node-v0.x-archive#8813 New commands: - `rnpm prune [--production]` - `rnpm shrinkwrap` - `rnpm list --depth=n` New aliases and shorthands: - `i`: install - `ls`: list - `--prod`: --production
1 parent 3f94eba commit a1dcccb

File tree

8 files changed

+157
-17
lines changed

8 files changed

+157
-17
lines changed

bin/rnpm

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,40 @@ app
99
.version(JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8')).version);
1010

1111
app
12-
.option('--production', 'Ignore `devDependencies`.')
12+
.option('--prod, --production', 'Ignore `devDependencies`.')
1313
.option('--strict', 'Fail on inconsistent dependencies.')
1414

1515
app
1616
.command('install')
17+
.alias('i')
1718
.description('Recursively install dependencies')
1819
.action(function() {
1920
rnpm.install({ production: app.production, strict: app.strict })
2021
});
2122

23+
app
24+
.command('prune')
25+
.description('Recursive npm prune')
26+
.action(function() {
27+
rnpm.prune({ production: app.production })
28+
});
29+
30+
app
31+
.command('shrinkwrap')
32+
.description('Recursive npm shrinkwrap')
33+
.action(function() {
34+
rnpm.custom('shrinkwrap')
35+
});
36+
37+
app
38+
.command('list')
39+
.alias('ls')
40+
.option('--depth [n]', 'Max display depth of the dependency tree', parseInt)
41+
.description('Recursive npm list')
42+
.action(function(opts) {
43+
rnpm.custom('list', {depth: opts.depth || 0})
44+
});
45+
2246
app
2347
.command('analyze')
2448
.description('Analyze dependencies recursively and warn about any inconsistencies')

lib/analyze.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ module.exports = function analyze(options, callback) {
99
, depsPerDir = {
1010
'.': {}
1111
}
12-
, inconsistencies = {
13-
}
12+
, inconsistencies = {}
13+
, consolidated = []
1414
, done = false
1515
, pending = 0
1616

@@ -24,7 +24,16 @@ module.exports = function analyze(options, callback) {
2424
return
2525
}
2626

27-
// Check for existance of package.json and read it
27+
var relative = path.relative(cwd, dir)
28+
29+
// Check for existence of previous .rnpm
30+
pending++;
31+
fs.exists(path.join(dir, '.rnpm', 'package.json'), function(exists) {
32+
if (exists) consolidated.push(relative || '.')
33+
--pending; checkReady()
34+
})
35+
36+
// Check for existence of package.json and read it
2837
var pkgjson = path.join(dir, 'package.json')
2938
pending++;
3039
fs.exists(pkgjson, function(exists) {
@@ -34,10 +43,10 @@ module.exports = function analyze(options, callback) {
3443
var data = JSON.parse(json);
3544

3645
// Extract dependencies
37-
addDependencies(data.dependencies, path.relative(cwd, dir), 'production')
46+
addDependencies(data.dependencies, relative, 'production')
3847

3948
// Extract development dependencies
40-
addDependencies(data.devDependencies, path.relative(cwd, dir), 'development')
49+
addDependencies(data.devDependencies, relative, 'development')
4150

4251
--pending
4352
checkReady();
@@ -97,7 +106,7 @@ module.exports = function analyze(options, callback) {
97106
// Check if all package.json files were read
98107
function checkReady() {
99108
if (done && !pending) {
100-
callback && callback(depsPerDir, inconsistencies)
109+
callback && callback(depsPerDir, inconsistencies, consolidated)
101110
}
102111
}
103112
}

lib/custom.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
var path = require('path')
2+
, npm = require('npm')
3+
, analyze = require('./analyze')
4+
, util = require('./util')
5+
, after = require('after')
6+
7+
module.exports = function custom(command, options, callback) {
8+
var cwd = process.cwd()
9+
10+
if (!options) options = {}
11+
12+
// Initialize NPM as a lib
13+
npm.load({}, function() {
14+
// analyze dependencies
15+
analyze(options, function (depsPerDir, _, consolidated) {
16+
var next = after(consolidated.length, function(err){
17+
if (err) throw err
18+
// util.log(command, 'Done.');
19+
return callback && callback()
20+
})
21+
22+
consolidated.forEach(function(dir){
23+
util.log(command, dir)
24+
25+
// run command inside the `.rpnm` directory
26+
npm.prefix = path.join(cwd, dir, '.rnpm');
27+
for(var k in options) npm.config.set(k, options[k])
28+
npm.commands[command]([], next)
29+
})
30+
})
31+
})
32+
}

lib/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ exports.install = require('./install')
22
exports.analyze = require('./analyze')
33
exports.updateDep = require('./update-dep')
44
exports.normalize = require('./normalize')
5+
exports.prune = require('./prune')
6+
exports.custom = require('./custom')

lib/install.js

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ var fs = require('fs')
22
, path = require('path')
33
, npm = require('npm')
44
, analyze = require('./analyze')
5-
, util = require('./util');
5+
, util = require('./util')
6+
, os = require('os')
7+
8+
// Use junctions on Windows < Vista (6.0),
9+
// Vista and later support regular symlinks.
10+
if (os.platform()=='win32' && parseInt(os.release())<6) {
11+
var symlinkType = 'junction'
12+
} else {
13+
symlinkType = 'dir'
14+
}
615

716
module.exports = function install(options, callback) {
817

@@ -48,9 +57,7 @@ module.exports = function install(options, callback) {
4857
}
4958
fs.mkdirSync(dotrnpm);
5059
fs.mkdirSync(path.join(dotrnpm, 'node_modules'));
51-
fs.symlinkSync('.rnpm/node_modules',
52-
path.join(cwd, dir, 'node_modules'),
53-
'junction');
60+
symlink('.rnpm/node_modules', path.join(cwd, dir, 'node_modules'));
5461
// avoid npm warning, and provide some info
5562
// on the nature of the `.rnpm` dir
5663
fs.writeFileSync(path.join(dotrnpm, 'Readme.md'),
@@ -59,9 +66,7 @@ module.exports = function install(options, callback) {
5966
'utf-8');
6067
} else {
6168
if (!fs.existsSync(path.join(cwd, dir, 'node_modules'))) {
62-
fs.symlinkSync('.rnpm/node_modules',
63-
path.join(cwd, dir, 'node_modules'),
64-
'junction');
69+
symlink('.rnpm/node_modules', path.join(cwd, dir, 'node_modules'));
6570
}
6671
}
6772

@@ -100,3 +105,11 @@ module.exports = function install(options, callback) {
100105
})
101106
}
102107

108+
function symlink(target, link) {
109+
// Junction points must be absolute
110+
if (symlinkType=='junction') {
111+
target = path.resolve(link, '..', target)
112+
}
113+
114+
fs.symlinkSync(target, link, symlinkType)
115+
}

lib/normalize.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ var commander = require('commander')
22
, analyze = require('./analyze')
33
, updateDep = require('./update-dep')
44
, util = require('./util')
5+
, prompt = require('cli-prompt')
56

67
module.exports = function(options, callback) {
78
// analyze dependencies
@@ -21,7 +22,7 @@ module.exports = function(options, callback) {
2122
}
2223

2324
// ask the user for the right version
24-
commander.prompt('(' + (i+1) + '/' + deps.length + ') New version for `' + deps[i] + '` [' + inconsistencies[deps[i]].sort().join(', ') + ']: ', function(version) {
25+
prompt('(' + (i+1) + '/' + deps.length + ') New version for `' + deps[i] + '` [' + inconsistencies[deps[i]].sort().join(', ') + ']: ', function(version) {
2526
if (!version) {
2627
util.log('normalize', 'Skipping dependency `' + deps[i] + '`.');
2728
return normalizeOne(i+1);

lib/prune.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
var path = require('path')
2+
, npm = require('npm')
3+
, analyze = require('./analyze')
4+
, util = require('./util')
5+
, after = require('after')
6+
, rimraf = require('rimraf')
7+
8+
module.exports = function prune(options, callback) {
9+
10+
var cwd = process.cwd()
11+
12+
// Initialize NPM as a lib
13+
npm.load({}, function() {
14+
15+
// analyze dependencies
16+
analyze(options, function (depsPerDir, _, consolidated) {
17+
18+
var next = after(consolidated.length, function(err){
19+
if (err) throw err
20+
// util.log('prune', 'Done.');
21+
return callback && callback()
22+
})
23+
24+
consolidated.forEach(function(dir){
25+
// If dir has no overriding dependencies,
26+
// remove .rnpm (root is skipped)
27+
if (dir!='.' && !depsPerDir[dir]) {
28+
var _next = after(2, next)
29+
30+
remove('.rnpm')
31+
remove('node_modules')
32+
33+
function remove(sub) {
34+
var full = path.join(cwd, dir, sub)
35+
rimraf(full, function(err){
36+
if (err) {
37+
util.error('prune', dir + ': could not remove `'+full+'`')
38+
} else {
39+
util.log('prune', dir + ': removed '+sub)
40+
}
41+
_next()
42+
})
43+
}
44+
} else {
45+
util.log('prune', dir)
46+
47+
// prune deps inside the `.rpnm` directory
48+
npm.prefix = path.join(cwd, dir, '.rnpm');
49+
npm.config.set('production', !!options.production);
50+
npm.commands.prune([], next)
51+
}
52+
})
53+
})
54+
})
55+
}
56+

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
"dependencies": {
1212
"commander": "~2.5.0",
1313
"dive": "~0.3.0",
14-
"npm": "~2.1.11",
15-
"ansi": "~0.3.0"
14+
"npm": "~2.1.0",
15+
"ansi": "~0.3.0",
16+
"rimraf": "~2.2.8",
17+
"after": "~0.8.1",
18+
"cli-prompt": "~0.4.1"
1619
},
1720
"bin": {
1821
"rnpm": "./bin/rnpm"

0 commit comments

Comments
 (0)