yargs 1.3.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,22 +1,21 @@
1
1
  yargs
2
2
  ========
3
3
 
4
- Yargs be a node.js library fer hearties tryin' ter parse optstrings against their will where even the boo box be not enough to coerce them. This here module is fer scallywags lookin' ter plunder all the sunken -shipz of their --treasures thru program usage but be tired of optstrings disincling to acquiesce to yer requests.
4
+ Yargs be a node.js library fer hearties tryin' ter parse optstrings.
5
5
 
6
6
  With yargs, ye be havin' a map that leads straight to yer treasure! Treasure of course, being a simple option hash.
7
7
 
8
8
  [![Build Status](https://travis-ci.org/chevex/yargs.png)](https://travis-ci.org/chevex/yargs)
9
9
  [![Dependency Status](https://gemnasium.com/chevex/yargs.png)](https://gemnasium.com/chevex/yargs)
10
10
  [![NPM version](https://badge.fury.io/js/yargs.png)](http://badge.fury.io/js/yargs)
11
+ [![Coverage Status](https://coveralls.io/repos/chevex/yargs/badge.svg?branch=)](https://coveralls.io/r/chevex/yargs?branch=)
11
12
 
12
- > ~~NOTE: Yargs is a fork of [optimist](https://github.com/substack/node-optimist) by [substack (James Halliday)](https://github.com/substack). It is obvious that substack is stretched pretty thin maintaining over 300 modules on npm at the time of this writing. So rather than complain in the project issue tracker I thought I'd just pick up the torch and maintain a proper fork. Currently the project is totally backward compatible with optimist but this may change in the future (if it does I will update this notice to inform you of this). For now though, enjoy optimist with about 5 months worth of fixes and updates rolled in, most of them pulled from optimist's own [stale pull requests](https://github.com/substack/node-optimist/pulls).~~
13
-
14
- > UPDATE: Yargs is now the official successor to optimist. Please feel free to submit issues and pull requests. While I personally don't have the time to pore over all the issues and fix all of them on a regular basis, I'm more than happy to look over pull requests, test them, and merge them in. If you'd like to contribute and don't know where to start, have a look at [the issue list](https://github.com/chevex/yargs/issues) :)
13
+ > Yargs is the official successor to optimist. Please feel free to submit issues and pull requests. If you'd like to contribute and don't know where to start, have a look at [the issue list](https://github.com/chevex/yargs/issues) :)
15
14
 
16
15
  examples
17
16
  ========
18
17
 
19
- With yargs, the options be just a hash! No optstrings be attached.
18
+ With yargs, the options be just a hash!
20
19
  -------------------------------------------------------------------
21
20
 
22
21
  xup.js:
@@ -37,15 +36,15 @@ else {
37
36
 
38
37
  $ ./xup.js --rif=55 --xup=9.52
39
38
  Plunder more riffiwobbles!
40
-
39
+
41
40
  $ ./xup.js --rif 12 --xup 8.1
42
41
  Drop the xupptumblers!
43
42
 
44
43
  ![Joe was one optimistic pirate.](http://i.imgur.com/4WFGVJ9.png)
45
44
 
46
- But don' walk the plank jus' yet! Ther' be more! Ye can do short options:
45
+ But don't walk the plank just yet! There be more! You can do short options:
47
46
  -------------------------------------------------
48
-
47
+
49
48
  short.js:
50
49
 
51
50
  ````javascript
@@ -59,7 +58,7 @@ console.log('(%d,%d)', argv.x, argv.y);
59
58
  $ ./short.js -x 10 -y 21
60
59
  (10,21)
61
60
 
62
- And gold doubooleans, both long an' short (an' grouped!):
61
+ And booleans, both long, short, and even grouped:
63
62
  ----------------------------------
64
63
 
65
64
  bool.js:
@@ -81,7 +80,7 @@ console.log(
81
80
 
82
81
  $ ./bool.js -s
83
82
  The parrot says: squawk
84
-
83
+
85
84
  $ ./bool.js -sp
86
85
  The parrot says: squawk!
87
86
 
@@ -90,7 +89,7 @@ console.log(
90
89
 
91
90
  And non-hyphenated options too! Just use `argv._`!
92
91
  -------------------------------------------------
93
-
92
+
94
93
  nonopt.js:
95
94
 
96
95
  ````javascript
@@ -105,12 +104,12 @@ console.log(argv._);
105
104
  $ ./nonopt.js -x 6.82 -y 3.35 rum
106
105
  (6.82,3.35)
107
106
  [ 'rum' ]
108
-
107
+
109
108
  $ ./nonopt.js "me hearties" -x 0.54 yo -y 1.12 ho
110
109
  (0.54,1.12)
111
110
  [ 'me hearties', 'yo', 'ho' ]
112
111
 
113
- Yargs even counts yer gold doubooleans!
112
+ Yargs even counts your booleans!
114
113
  ----------------------------------------------------------------------
115
114
 
116
115
  count.js
@@ -151,7 +150,7 @@ DEBUG("Extra chatty mode");
151
150
  Showing semi-important stuff too
152
151
  Extra chatty mode
153
152
 
154
- Tell yer friends how ter use yer options and make demands from yer enemies.
153
+ Tell users how to use yer options and make demands.
155
154
  -------------------------------------------------
156
155
 
157
156
  divide.js:
@@ -167,10 +166,10 @@ console.log(argv.x / argv.y);
167
166
  ````
168
167
 
169
168
  ***
170
-
169
+
171
170
  $ ./divide.js -x 55 -y 11
172
171
  5
173
-
172
+
174
173
  $ node ./divide.js -x 4.91 -z 2.51
175
174
  Usage: node ./divide.js -x [num] -y [num]
176
175
 
@@ -238,7 +237,7 @@ console.log(argv.x + argv.y);
238
237
  $ ./default_hash.js -y 7
239
238
  17
240
239
 
241
- And if ye really want ter get all descriptive about it...
240
+ And if you really want to get all descriptive about it...
242
241
  ---------------------------------------------------------
243
242
 
244
243
  boolean_single.js
@@ -258,7 +257,7 @@ console.dir(argv._);
258
257
  $ ./boolean_single.js -v "me hearties" yo ho
259
258
  true
260
259
  [ 'me hearties', 'yo', 'ho' ]
261
-
260
+
262
261
 
263
262
  boolean_double.js
264
263
 
@@ -278,7 +277,7 @@ console.dir(argv._);
278
277
  [ true, false, true ]
279
278
  [ 'one', 'two', 'three' ]
280
279
 
281
- Yargs is here ter help ye...
280
+ Yargs is here to help you...
282
281
  ---------------------------
283
282
 
284
283
  Ye can describe parameters fer help messages and set aliases. Yargs figures
@@ -324,10 +323,10 @@ s.on('end', function () {
324
323
 
325
324
  Missing required arguments: f
326
325
 
327
- $ node line_count.js --file line_count.js
326
+ $ node line_count.js --file line_count.js
328
327
  20
329
-
330
- $ node line_count.js -f line_count.js
328
+
329
+ $ node line_count.js -f line_count.js
331
330
  20
332
331
 
333
332
  methods
@@ -403,6 +402,13 @@ usage information and exit.
403
402
  The default behaviour is to set the value of any key not followed by an
404
403
  option value to `true`.
405
404
 
405
+ .implies(x, y)
406
+ --------------
407
+
408
+ Given the key `x` is set, it is required that the key `y` is set.
409
+
410
+ implies can also accept an object specifying multiple implications.
411
+
406
412
  .describe(key, desc)
407
413
  --------------------
408
414
 
@@ -410,19 +416,24 @@ Describe a `key` for the generated usage information.
410
416
 
411
417
  Optionally `.describe()` can take an object that maps keys to descriptions.
412
418
 
419
+ .option(key, opt)
420
+ -----------------
413
421
  .options(key, opt)
414
422
  ------------------
415
423
 
416
- Instead of chaining together `.alias().demand().default()`, you can specify
424
+ Instead of chaining together `.alias().demand().default().describe().string()`, you can specify
417
425
  keys in `opt` for each of the chainable methods.
418
426
 
419
427
  For example:
420
428
 
421
429
  ````javascript
422
430
  var argv = require('yargs')
423
- .options('f', {
431
+ .option('f', {
424
432
  alias : 'file',
425
- default : '/etc/passwd',
433
+ demand: true,
434
+ default: '/etc/passwd',
435
+ describe: 'x marks the spot',
436
+ type: 'string'
426
437
  })
427
438
  .argv
428
439
  ;
@@ -440,6 +451,21 @@ var argv = require('yargs')
440
451
 
441
452
  Optionally `.options()` can take an object that maps keys to `opt` parameters.
442
453
 
454
+ ````javascript
455
+ var argv = require('yargs')
456
+ .options({
457
+ 'f': {
458
+ alias: 'file',
459
+ demand: true,
460
+ default: '/etc/passwd',
461
+ describe: 'x marks the spot',
462
+ type: 'string'
463
+ }
464
+ })
465
+ .argv
466
+ ;
467
+ ````
468
+
443
469
  .usage(message, opts)
444
470
  ---------------------
445
471
 
@@ -467,14 +493,21 @@ Check that certain conditions are met in the provided arguments.
467
493
  If `fn` throws or returns `false`, show the thrown error, usage information, and
468
494
  exit.
469
495
 
496
+ .fail(fn)
497
+ ---------
498
+
499
+ Method to execute when a failure occurs, rather then printing the failure message.
500
+
501
+ `fn` is called with the failure message that would have been printed.
502
+
470
503
  .boolean(key)
471
504
  -------------
472
505
 
473
506
  Interpret `key` as a boolean. If a non-flag option follows `key` in
474
507
  `process.argv`, that string won't get set as the value of `key`.
475
508
 
476
- If `key` never shows up as a flag in `process.arguments`, `argv[key]` will be
477
- `false`.
509
+ `key` will default to `false`, unless an `default(key, undefined)` is
510
+ explicitly set.
478
511
 
479
512
  If `key` is an Array, interpret all the elements as booleans.
480
513
 
@@ -486,6 +519,9 @@ This can be useful if you need to preserve leading zeros in an input.
486
519
 
487
520
  If `key` is an Array, interpret all the elements as strings.
488
521
 
522
+ `.string('_')` will result in non-hyphenated arguments being interpreted as strings,
523
+ regardless of whether they resemble numbers.
524
+
489
525
  .config(key)
490
526
  ------------
491
527
 
@@ -574,6 +610,11 @@ yargs.showHelp();
574
610
 
575
611
  Later on, ```argv``` can be retrived with ```yargs.argv```
576
612
 
613
+ .exitProcess(enable)
614
+ ----------------------------------
615
+
616
+ By default, yargs exits the process when the user passes a help flag, uses the `.version` functionality or when validation fails. Calling `.exitProcess(false)` disables this behavior, enabling further actions after yargs have been validated.
617
+
577
618
  .parse(args)
578
619
  ------------
579
620
 
@@ -664,17 +705,17 @@ installation
664
705
  With [npm](http://github.com/isaacs/npm), just do:
665
706
 
666
707
  npm install yargs
667
-
708
+
668
709
  or clone this project on github:
669
710
 
670
711
  git clone http://github.com/chevex/yargs.git
671
712
 
672
713
  To run the tests with [expresso](http://github.com/visionmedia/expresso),
673
714
  just do:
674
-
715
+
675
716
  expresso
676
717
 
677
- inspired By
718
+ inspired by
678
719
  ===========
679
720
 
680
721
  This module is loosely inspired by Perl's
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  var path = require('path');
2
- var minimist = require('./lib/minimist');
3
- var wordwrap = require('./lib/wordwrap');
2
+ var parser = require('./lib/parser');
3
+ var wordwrap = require('wordwrap');
4
4
 
5
5
  /* Hack an instance of Argv with process.argv into Argv
6
6
  so people can do
@@ -21,7 +21,7 @@ var exports = module.exports = Argv;
21
21
  function Argv (processArgs, cwd) {
22
22
  var self = {};
23
23
  if (!cwd) cwd = process.cwd();
24
-
24
+
25
25
  self.$0 = process.argv
26
26
  .slice(0,2)
27
27
  .map(function (x) {
@@ -31,7 +31,7 @@ function Argv (processArgs, cwd) {
31
31
  })
32
32
  .join(' ')
33
33
  ;
34
-
34
+
35
35
  if (process.env._ != undefined && process.argv[1] == process.env._) {
36
36
  self.$0 = process.env._.replace(
37
37
  path.dirname(process.execPath) + '/', ''
@@ -44,7 +44,7 @@ function Argv (processArgs, cwd) {
44
44
  boolean: [],
45
45
  string: [],
46
46
  alias: {},
47
- default: [],
47
+ default: {},
48
48
  requiresArg: [],
49
49
  count: [],
50
50
  normalize: [],
@@ -53,7 +53,7 @@ function Argv (processArgs, cwd) {
53
53
  return self;
54
54
  };
55
55
  self.resetOptions();
56
-
56
+
57
57
  self.boolean = function (bools) {
58
58
  options.boolean.push.apply(options.boolean, [].concat(bools));
59
59
  return self;
@@ -74,12 +74,12 @@ function Argv (processArgs, cwd) {
74
74
  examples.push([cmd, description]);
75
75
  return self;
76
76
  };
77
-
77
+
78
78
  self.string = function (strings) {
79
79
  options.string.push.apply(options.string, [].concat(strings));
80
80
  return self;
81
81
  };
82
-
82
+
83
83
  self.default = function (key, value) {
84
84
  if (typeof key === 'object') {
85
85
  Object.keys(key).forEach(function (k) {
@@ -91,7 +91,7 @@ function Argv (processArgs, cwd) {
91
91
  }
92
92
  return self;
93
93
  };
94
-
94
+
95
95
  self.alias = function (x, y) {
96
96
  if (typeof x === 'object') {
97
97
  Object.keys(x).forEach(function (key) {
@@ -108,7 +108,7 @@ function Argv (processArgs, cwd) {
108
108
  options.count.push.apply(options.count, [].concat(counts));
109
109
  return self;
110
110
  };
111
-
111
+
112
112
  var demanded = {};
113
113
  self.demand = self.required = self.require = function (keys, msg) {
114
114
  if (typeof keys == 'number') {
@@ -129,7 +129,7 @@ function Argv (processArgs, cwd) {
129
129
  demanded[keys] = { msg: null };
130
130
  }
131
131
  }
132
-
132
+
133
133
  return self;
134
134
  };
135
135
 
@@ -156,11 +156,11 @@ function Argv (processArgs, cwd) {
156
156
  opts = msg;
157
157
  msg = null;
158
158
  }
159
-
159
+
160
160
  usage = msg;
161
-
161
+
162
162
  if (opts) self.options(opts);
163
-
163
+
164
164
  return self;
165
165
  };
166
166
 
@@ -186,10 +186,14 @@ function Argv (processArgs, cwd) {
186
186
  }
187
187
  console.error(failMessage);
188
188
  }
189
- process.exit(1);
189
+ if (exitProcess){
190
+ process.exit(1);
191
+ }else{
192
+ throw new Error(msg);
193
+ }
190
194
  }
191
195
  }
192
-
196
+
193
197
  var checks = [];
194
198
  self.check = function (f) {
195
199
  checks.push(f);
@@ -210,11 +214,11 @@ function Argv (processArgs, cwd) {
210
214
  }
211
215
  return self;
212
216
  };
213
-
217
+
214
218
  self.parse = function (args) {
215
219
  return parseArgs(args);
216
220
  };
217
-
221
+
218
222
  self.option = self.options = function (key, opt) {
219
223
  if (typeof key === 'object') {
220
224
  Object.keys(key).forEach(function (k) {
@@ -229,10 +233,10 @@ function Argv (processArgs, cwd) {
229
233
  self.demand(key, demand);
230
234
  }
231
235
 
232
- if (typeof opt.default !== 'undefined') {
236
+ if ('default' in opt) {
233
237
  self.default(key, opt.default);
234
238
  }
235
-
239
+
236
240
  if (opt.boolean || opt.type === 'boolean') {
237
241
  self.boolean(key);
238
242
  if (opt.alias) self.boolean(opt.alias);
@@ -269,7 +273,7 @@ function Argv (processArgs, cwd) {
269
273
  strict = true;
270
274
  return self;
271
275
  };
272
-
276
+
273
277
  self.showHelp = function (fn) {
274
278
  if (!fn) fn = console.error.bind(console);
275
279
  fn(self.help());
@@ -296,8 +300,8 @@ function Argv (processArgs, cwd) {
296
300
  var showHelpOnFail = true;
297
301
  self.showHelpOnFail = function (enabled, message) {
298
302
  if (typeof enabled === 'string') {
299
- enabled = true;
300
303
  message = enabled;
304
+ enabled = true;
301
305
  }
302
306
  else if (typeof enabled === 'undefined') {
303
307
  enabled = true;
@@ -307,8 +311,18 @@ function Argv (processArgs, cwd) {
307
311
  return self;
308
312
  };
309
313
 
314
+ var exitProcess = true;
315
+ self.exitProcess = function (enabled) {
316
+ if (typeof enabled !== 'boolean') {
317
+ enabled = true;
318
+ }
319
+ exitProcess = enabled;
320
+ return self;
321
+ };
310
322
 
311
323
  self.help = function () {
324
+ if (!self.parsed) parseArgs(processArgs); // run parser, if it has not already been executed.
325
+
312
326
  if (arguments.length > 0) {
313
327
  return self.addHelpOpt.apply(self, arguments);
314
328
  }
@@ -322,7 +336,7 @@ function Argv (processArgs, cwd) {
322
336
  return acc;
323
337
  }, {})
324
338
  );
325
-
339
+
326
340
  var help = keys.length ? [ 'Options:' ] : [];
327
341
 
328
342
  if (examples.length) {
@@ -351,9 +365,12 @@ function Argv (processArgs, cwd) {
351
365
  help.unshift(usage.replace(/\$0/g, self.$0), '');
352
366
  }
353
367
 
368
+ var aliasKeys = (Object.keys(options.alias) || [])
369
+ .concat(Object.keys(self.parsed.newAliases) || []);
370
+
354
371
  keys = keys.filter(function(key) {
355
- return Object.keys(options.alias).every(function(alias) {
356
- return -1 == options.alias[alias].indexOf(key);
372
+ return !self.parsed.newAliases[key] && aliasKeys.every(function(alias) {
373
+ return -1 == (options.alias[alias] || []).indexOf(key);
357
374
  });
358
375
  });
359
376
  var switches = keys.reduce(function (acc, key) {
@@ -369,40 +386,40 @@ function Argv (processArgs, cwd) {
369
386
  var switchlen = longest(Object.keys(switches).map(function (s) {
370
387
  return switches[s] || '';
371
388
  }));
372
-
373
- var desclen = longest(Object.keys(descriptions).map(function (d) {
389
+
390
+ var desclen = longest(Object.keys(descriptions).map(function (d) {
374
391
  return descriptions[d] || '';
375
392
  }));
376
-
393
+
377
394
  keys.forEach(function (key) {
378
395
  var kswitch = switches[key];
379
396
  var desc = descriptions[key] || '';
380
-
397
+
381
398
  if (wrap) {
382
399
  desc = wordwrap(switchlen + 4, wrap)(desc)
383
400
  .slice(switchlen + 4)
384
401
  ;
385
402
  }
386
-
403
+
387
404
  var spadding = new Array(
388
405
  Math.max(switchlen - kswitch.length + 3, 0)
389
406
  ).join(' ');
390
-
407
+
391
408
  var dpadding = new Array(
392
409
  Math.max(desclen - desc.length + 1, 0)
393
410
  ).join(' ');
394
-
411
+
395
412
  var type = null;
396
-
413
+
397
414
  if (options.boolean[key]) type = '[boolean]';
398
415
  if (options.count[key]) type = '[count]';
399
416
  if (options.string[key]) type = '[string]';
400
417
  if (options.normalize[key]) type = '[string]';
401
-
418
+
402
419
  if (!wrap && dpadding.length > 0) {
403
420
  desc += dpadding;
404
421
  }
405
-
422
+
406
423
  var prelude = ' ' + kswitch + spadding;
407
424
  var extra = [
408
425
  type,
@@ -415,50 +432,70 @@ function Argv (processArgs, cwd) {
415
432
  JSON.stringify : String)(options.default[key]) + ']'
416
433
  : null
417
434
  ].filter(Boolean).join(' ');
418
-
435
+
419
436
  var body = [ desc, extra ].filter(Boolean).join(' ');
420
-
437
+
421
438
  if (wrap) {
422
439
  var dlines = desc.split('\n');
423
440
  var dlen = dlines.slice(-1)[0].length
424
441
  + (dlines.length === 1 ? prelude.length : 0)
425
-
426
- body = desc + (dlen + extra.length > wrap - 2
427
- ? '\n'
428
- + new Array(wrap - extra.length + 1).join(' ')
429
- + extra
430
- : new Array(wrap - extra.length - dlen + 1).join(' ')
431
- + extra
432
- );
442
+
443
+ if (extra.length > wrap) {
444
+ body = desc + '\n' + wordwrap(switchlen + 4, wrap)(extra)
445
+ } else {
446
+ body = desc + (dlen + extra.length > wrap - 2
447
+ ? '\n'
448
+ + new Array(wrap - extra.length + 1).join(' ')
449
+ + extra
450
+ : new Array(wrap - extra.length - dlen + 1).join(' ')
451
+ + extra
452
+ );
453
+ }
433
454
  }
434
-
455
+
435
456
  help.push(prelude + body);
436
457
  });
437
-
458
+
438
459
  if (keys.length) help.push('');
439
460
  return help.join('\n');
440
461
  };
441
-
462
+
442
463
  Object.defineProperty(self, 'argv', {
443
- get : function () { return parseArgs(processArgs) },
464
+ get : function () {
465
+ var args = null;
466
+
467
+ try {
468
+ args = parseArgs(processArgs);
469
+ } catch (err) {
470
+ fail(err.message);
471
+ }
472
+
473
+ return args;
474
+ },
444
475
  enumerable : true
445
476
  });
446
-
477
+
447
478
  function parseArgs (args) {
448
- var parsed = minimist(args, options),
479
+ var parsed = parser(args, options),
449
480
  argv = parsed.argv,
450
481
  aliases = parsed.aliases;
451
482
 
452
483
  argv.$0 = self.$0;
453
484
 
485
+ self.parsed = parsed;
486
+
454
487
  Object.keys(argv).forEach(function(key) {
455
488
  if (key === helpOpt) {
456
489
  self.showHelp(console.log);
457
- process.exit(0);
490
+ if (exitProcess){
491
+ process.exit(0);
492
+ }
458
493
  }
459
494
  else if (key === versionOpt) {
460
- console.log(version);
461
- process.exit(0);
495
+ process.stdout.write(version);
496
+ if (exitProcess){
497
+ process.exit(0);
498
+ }
462
499
  }
463
500
  });
464
501
 
@@ -478,7 +515,7 @@ function Argv (processArgs, cwd) {
478
515
  options.requiresArg.forEach(function(key) {
479
516
  var value = argv[key];
480
517
 
481
- // minimist sets --foo value to true / --no-foo to false
518
+ // parser sets --foo value to true / --no-foo to false
482
519
  if (value === true || value === false) {
483
520
  missingRequiredArgs.push(key);
484
521
  }
@@ -488,11 +525,11 @@ function Argv (processArgs, cwd) {
488
525
  fail("Missing argument value: " + missingRequiredArgs[0]);
489
526
  }
490
527
  else if (missingRequiredArgs.length > 1) {
491
- message = "Missing argument values: " + missingRequiredArgs.join(", ");
528
+ var message = "Missing argument values: " + missingRequiredArgs.join(", ");
492
529
  fail(message);
493
530
  }
494
531
  }
495
-
532
+
496
533
  var missing = null;
497
534
  Object.keys(demanded).forEach(function (key) {
498
535
  if (!argv.hasOwnProperty(key)) {
@@ -500,7 +537,7 @@ function Argv (processArgs, cwd) {
500
537
  missing[key] = demanded[key];
501
538
  }
502
539
  });
503
-
540
+
504
541
  if (missing) {
505
542
  var customMsgs = [];
506
543
  Object.keys(missing).forEach(function(key) {
@@ -602,17 +639,17 @@ function Argv (processArgs, cwd) {
602
639
 
603
640
  fail(msg);
604
641
  }
605
-
642
+
606
643
  return argv;
607
644
  }
608
-
645
+
609
646
  function longest (xs) {
610
647
  return Math.max.apply(
611
648
  null,
612
649
  xs.map(function (x) { return x.length })
613
650
  );
614
651
  }
615
-
652
+
616
653
  return self;
617
654
  };
618
655
 
@@ -620,14 +657,5 @@ function Argv (processArgs, cwd) {
620
657
  // exported for tests
621
658
  exports.rebase = rebase;
622
659
  function rebase (base, dir) {
623
- var ds = path.normalize(dir).split('/').slice(1);
624
- var bs = path.normalize(base).split('/').slice(1);
625
-
626
- for (var i = 0; ds[i] && ds[i] == bs[i]; i++);
627
- ds.splice(0, i); bs.splice(0, i);
628
-
629
- var p = path.normalize(
630
- bs.map(function () { return '..' }).concat(ds).join('/')
631
- ).replace(/\/$/,'').replace(/^$/, '.');
632
- return p.match(/^[.\/]/) ? p : './' + p;
660
+ return path.relative(base, dir);
633
661
  };