Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
"dependencies": {
"chalk": "^1.1.1",
"commander": "^2.9.0",
"commander": "^2.19.0",
"compression": "^1.7.1",
"connect": "^3.6.5",
"denodeify": "^1.2.1",
Expand Down
72 changes: 28 additions & 44 deletions packages/cli/src/cliEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,19 @@
import chalk from 'chalk';
import childProcess from 'child_process';
import commander from 'commander';
import minimist from 'minimist';
import path from 'path';
import type {CommandT, ContextT} from './tools/types.flow';
import getLegacyConfig from './tools/getLegacyConfig';
import {getCommands} from './commands';
import init from './commands/init/init';
import assertRequiredOptions from './tools/assertRequiredOptions';
import logger from './tools/logger';
import pkg from '../package.json';

commander
.version(pkg.version)
.option('--version', 'Print CLI version')
.option('--projectRoot [string]', 'Path to the root of the project')
.option('--reactNativePath [string]', 'Path to React Native');
.option('--reactNativePath [string]', 'Path to React Native')
.parse(process.argv);

commander.on('command:*', () => {
printUnknownCommand(commander.args.join(' '));
Expand All @@ -39,35 +38,34 @@ const handleError = err => {

// Custom printHelpInformation command inspired by internal Commander.js
// one modified to suit our needs
function printHelpInformation() {
function printHelpInformation(examples) {
let cmdName = this._name;
if (this._alias) {
cmdName = `${cmdName}|${this._alias}`;
}

const sourceInformation = this.pkg
? [` ${chalk.bold('Source:')} ${this.pkg.name}@${this.pkg.version}`, '']
? [`${chalk.bold('Source:')} ${this.pkg.name}@${this.pkg.version}`, '']
: [];

let output = [
chalk.bold(`react-native ${cmdName} ${this.usage()}`),
'',
chalk.bold(chalk.cyan(` react-native ${cmdName} ${this.usage()}`)),
this._description ? ` ${this._description}` : '',
this._description ? `${this._description}` : '',
'',
...sourceInformation,
` ${chalk.bold('Options:')}`,
'',
this.optionHelp().replace(/^/gm, ' '),
`${chalk.bold('Options:')}`,
'',
this.optionHelp().replace(/^/gm, ' '),
];

if (this.examples && this.examples.length > 0) {
const formattedUsage = this.examples
.map(example => ` ${example.desc}: \n ${chalk.cyan(example.cmd)}`)
if (examples && examples.length > 0) {
const formattedUsage = examples
.map(example => ` ${example.desc}: \n ${chalk.cyan(example.cmd)}`)
.join('\n\n');

output = output.concat([
chalk.bold(' Example usage:'),
chalk.bold('\nExample usage:'),
'',
formattedUsage,
]);
Expand All @@ -93,26 +91,18 @@ const addCommand = (command: CommandT, ctx: ContextT) => {
const options = command.options || [];

const cmd = commander
.command(command.name, undefined, {
noHelp: !command.description,
})
.command(command.name, undefined, {noHelp: !command.description})
.description(command.description)
.action(function handleAction(...args) {
const passedOptions = this.opts();
const argv: Array<string> = Array.from(args).slice(0, -1);

Promise.resolve()
.then(() => {
assertRequiredOptions(options, passedOptions);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commander validation actually works and commands fail when required arguments are not passed, so this fn was never called?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one checks for required options, see the linked issue in assertRequiredOptions.js file. It allows to require options, when the: "required: true" is set.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we use required: true in any of the options for built-in commands, but it's a breaking change (potentially) for other users that provide 3rd party commands. Would consider leaving it as it's a nice feature - we can always work upstream.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh didn't realise that :<

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You definitely need to document stuff like that 😛

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's all documented in the assertRequiredOptions file description! I wouldn't remember that myself otherwise

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean documenting plugins to CLI and how they work

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, CLI was historically missing some documentation, but it's finally improving!

return command.func(argv, ctx, passedOptions);
})
.then(() => command.func(argv, ctx, passedOptions))
.catch(handleError);
});

cmd.helpInformation = printHelpInformation.bind(cmd);
cmd.examples = command.examples;
// $FlowFixMe: This is either null or not
cmd.pkg = command.pkg;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like it's not used anywhere, @grabbou ideas?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pkg is still used on line 48. You may consider passing it to bind too

cmd.helpInformation = printHelpInformation.bind(cmd, command.examples);

options.forEach(opt =>
cmd.option(
Expand All @@ -122,11 +112,6 @@ const addCommand = (command: CommandT, ctx: ContextT) => {
opt.default,
),
);

// Redefined here to appear in the `--help` section
cmd
.option('--projectRoot [string]', 'Path to the root of the project')
.option('--reactNativePath [string]', 'Path to React Native');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once removed, they will not appear in the --help for a command, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we can tweak printHelpInformation a bit to render global options too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like they show up just right:

Screenshot 2019-03-08 at 13 54 48

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, it's not right, I've added extra .parse() call and it skips commands. Gonna work on it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but this was to handle react-native start --help (help for a command) where they don't show up anymore.

Screenshot 2019-03-11 at 10 41 07

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, just removed this extra call and help is complete:

Screenshot 2019-03-11 at 10 43 30

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ugh

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

brought it back with (imho) more appropriate comment

};

async function run() {
Expand Down Expand Up @@ -157,20 +142,12 @@ async function setupAndRun() {
}
}

/**
* Read passed `options` and take the "global" settings
*
* @todo(grabbou): Consider unifying this by removing either `commander`
* or `minimist`
*/
const options = minimist(process.argv.slice(2));

const root = options.projectRoot
? path.resolve(options.projectRoot)
const root = commander.projectRoot
? path.resolve(commander.projectRoot)
: process.cwd();

const reactNativePath = options.reactNativePath
? path.resolve(options.reactNativePath)
const reactNativePath = commander.reactNativePath
? path.resolve(commander.reactNativePath)
: (() => {
try {
return path.dirname(
Expand Down Expand Up @@ -198,9 +175,16 @@ async function setupAndRun() {

commander.parse(process.argv);

if (!options._.length) {
if (commander.rawArgs.length === 2) {
commander.outputHelp();
}

// We handle --version as a special case like this because both `commander`
// and `yargs` append it to every command and we don't want to do that.
// E.g. outside command `init` has --version flag and we want to preserve it.
if (commander.args.length === 0 && commander.version === true) {
console.log(pkg.version);
}
}

export default {
Expand Down
31 changes: 0 additions & 31 deletions packages/cli/src/tools/assertRequiredOptions.js

This file was deleted.

5 changes: 4 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2381,17 +2381,20 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"

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

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

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

compare-func@^1.3.1:
version "1.3.2"
Expand Down