Skip to content

Commit 5564634

Browse files
thymikeegrabbou
authored andcommitted
chore: simplify commander/minimist usage (#209)
* chore: simplify commander/minimist usage * feedback * remove extra parse * add options back * rephrase comment * remove excess whitespace
1 parent ccc1797 commit 5564634

File tree

3 files changed

+43
-46
lines changed

3 files changed

+43
-46
lines changed

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
},
2121
"dependencies": {
2222
"chalk": "^1.1.1",
23-
"commander": "^2.9.0",
23+
"commander": "^2.19.0",
2424
"compression": "^1.7.1",
2525
"connect": "^3.6.5",
2626
"denodeify": "^1.2.1",

packages/cli/src/cliEntry.js

Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,17 @@
1010
import chalk from 'chalk';
1111
import childProcess from 'child_process';
1212
import commander from 'commander';
13-
import minimist from 'minimist';
1413
import path from 'path';
1514
import type {CommandT, ContextT} from './tools/types.flow';
1615
import getLegacyConfig from './tools/getLegacyConfig';
1716
import {getCommands} from './commands';
1817
import init from './commands/init/init';
1918
import assertRequiredOptions from './tools/assertRequiredOptions';
2019
import logger from './tools/logger';
21-
import pkg from '../package.json';
20+
import pkgJson from '../package.json';
2221

2322
commander
24-
.version(pkg.version)
23+
.option('--version', 'Print CLI version')
2524
.option('--projectRoot [string]', 'Path to the root of the project')
2625
.option('--reactNativePath [string]', 'Path to React Native');
2726

@@ -39,41 +38,33 @@ const handleError = err => {
3938

4039
// Custom printHelpInformation command inspired by internal Commander.js
4140
// one modified to suit our needs
42-
function printHelpInformation() {
41+
function printHelpInformation(examples, pkg) {
4342
let cmdName = this._name;
4443
if (this._alias) {
4544
cmdName = `${cmdName}|${this._alias}`;
4645
}
4746

48-
const sourceInformation = this.pkg
49-
? [` ${chalk.bold('Source:')} ${this.pkg.name}@${this.pkg.version}`, '']
47+
const sourceInformation = pkg
48+
? [`${chalk.bold('Source:')} ${pkg.name}@${pkg.version}`, '']
5049
: [];
5150

5251
let output = [
53-
'',
54-
chalk.bold(chalk.cyan(` react-native ${cmdName} ${this.usage()}`)),
55-
this._description ? ` ${this._description}` : '',
56-
'',
52+
chalk.bold(`react-native ${cmdName} ${this.usage()}`),
53+
this._description ? `\n${this._description}\n` : '',
5754
...sourceInformation,
58-
` ${chalk.bold('Options:')}`,
59-
'',
60-
this.optionHelp().replace(/^/gm, ' '),
61-
'',
55+
`${chalk.bold('Options:')}`,
56+
this.optionHelp().replace(/^/gm, ' '),
6257
];
6358

64-
if (this.examples && this.examples.length > 0) {
65-
const formattedUsage = this.examples
66-
.map(example => ` ${example.desc}: \n ${chalk.cyan(example.cmd)}`)
59+
if (examples && examples.length > 0) {
60+
const formattedUsage = examples
61+
.map(example => ` ${example.desc}: \n ${chalk.cyan(example.cmd)}`)
6762
.join('\n\n');
6863

69-
output = output.concat([
70-
chalk.bold(' Example usage:'),
71-
'',
72-
formattedUsage,
73-
]);
64+
output = output.concat([chalk.bold('\nExample usage:'), formattedUsage]);
7465
}
7566

76-
return output.concat(['', '']).join('\n');
67+
return output.join('\n');
7768
}
7869

7970
function printUnknownCommand(cmdName) {
@@ -93,9 +84,7 @@ const addCommand = (command: CommandT, ctx: ContextT) => {
9384
const options = command.options || [];
9485

9586
const cmd = commander
96-
.command(command.name, undefined, {
97-
noHelp: !command.description,
98-
})
87+
.command(command.name, undefined, {noHelp: !command.description})
9988
.description(command.description)
10089
.action(function handleAction(...args) {
10190
const passedOptions = this.opts();
@@ -109,10 +98,12 @@ const addCommand = (command: CommandT, ctx: ContextT) => {
10998
.catch(handleError);
11099
});
111100

112-
cmd.helpInformation = printHelpInformation.bind(cmd);
113-
cmd.examples = command.examples;
114-
// $FlowFixMe: This is either null or not
115-
cmd.pkg = command.pkg;
101+
cmd.helpInformation = printHelpInformation.bind(
102+
cmd,
103+
command.examples,
104+
// $FlowFixMe - we know pkg may be missing...
105+
command.pkg,
106+
);
116107

117108
options.forEach(opt =>
118109
cmd.option(
@@ -123,7 +114,11 @@ const addCommand = (command: CommandT, ctx: ContextT) => {
123114
),
124115
);
125116

126-
// Redefined here to appear in the `--help` section
117+
/**
118+
* We want every command (like "start", "link") to accept below options.
119+
* To achieve that we append them to regular options of each command here.
120+
* This way they'll be displayed in the commands --help menus.
121+
*/
127122
cmd
128123
.option('--projectRoot [string]', 'Path to the root of the project')
129124
.option('--reactNativePath [string]', 'Path to React Native');
@@ -157,20 +152,12 @@ async function setupAndRun() {
157152
}
158153
}
159154

160-
/**
161-
* Read passed `options` and take the "global" settings
162-
*
163-
* @todo(grabbou): Consider unifying this by removing either `commander`
164-
* or `minimist`
165-
*/
166-
const options = minimist(process.argv.slice(2));
167-
168-
const root = options.projectRoot
169-
? path.resolve(options.projectRoot)
155+
const root = commander.projectRoot
156+
? path.resolve(commander.projectRoot)
170157
: process.cwd();
171158

172-
const reactNativePath = options.reactNativePath
173-
? path.resolve(options.reactNativePath)
159+
const reactNativePath = commander.reactNativePath
160+
? path.resolve(commander.reactNativePath)
174161
: (() => {
175162
try {
176163
return path.dirname(
@@ -198,9 +185,16 @@ async function setupAndRun() {
198185

199186
commander.parse(process.argv);
200187

201-
if (!options._.length) {
188+
if (commander.rawArgs.length === 2) {
202189
commander.outputHelp();
203190
}
191+
192+
// We handle --version as a special case like this because both `commander`
193+
// and `yargs` append it to every command and we don't want to do that.
194+
// E.g. outside command `init` has --version flag and we want to preserve it.
195+
if (commander.args.length === 0 && commander.version === true) {
196+
console.log(pkgJson.version);
197+
}
204198
}
205199

206200
export default {

yarn.lock

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2381,17 +2381,20 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
23812381
dependencies:
23822382
delayed-stream "~1.0.0"
23832383

2384-
commander@^2.9.0:
2384+
commander@^2.19.0:
23852385
version "2.19.0"
23862386
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
2387+
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
23872388

23882389
commander@~2.13.0:
23892390
version "2.13.0"
23902391
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
2392+
integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==
23912393

23922394
commander@~2.17.1:
23932395
version "2.17.1"
23942396
resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
2397+
integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
23952398

23962399
compare-func@^1.3.1:
23972400
version "1.3.2"

0 commit comments

Comments
 (0)