flow-typed
Version:
A repository of high quality flow type definitions
117 lines (108 loc) • 3.09 kB
Flow
// @flow
import yargs from 'yargs';
import {fs, path} from './lib/node';
import * as Install from './commands/install';
import * as CreateDef from './commands/create-def';
import * as CreateStub from './commands/create-stub';
import * as Outdated from './commands/outdated';
import * as RunTests from './commands/runTests';
import * as Search from './commands/search';
import * as Update from './commands/update';
import * as UpdateCache from './commands/update-cache';
import * as ValidateDefs from './commands/validateDefs';
import type {Argv} from 'yargs';
import typeof Yargs from 'yargs';
export const install = Install.run;
export const createDef = CreateDef.run;
export const createStub = CreateStub.run;
export const outdated = Outdated.run;
export const runTests = RunTests.run;
export const search = Search.run;
export const update = Update.run;
export const updateCache = UpdateCache.run;
export const validateDefs = ValidateDefs.run;
const identity = <T>(x: T): T => x;
export function runCLI() {
type CommandModule = {
name: string,
description: string,
setup?: (yargs: Yargs) => Yargs,
run: (argv: Argv) => Promise<number>,
...
};
const commands: Array<CommandModule> = [
CreateDef,
CreateStub,
Install,
Outdated,
RunTests,
Search,
Update,
UpdateCache,
ValidateDefs,
];
commands
.reduce(
(cmdYargs, cmd) =>
cmdYargs.command(
cmd.name,
cmd.description,
cmd.setup || identity,
args =>
cmd
// $FlowExpectedError[extra-arg] cmd.run expects only one arg
.run(args, yargs)
.catch(err => {
if (err.stack) {
console.log('UNCAUGHT ERROR: %s', err.stack);
} else if (typeof err === 'object' && err !== null) {
console.log(
'UNCAUGHT ERROR: %s',
JSON.stringify(err, null, 2),
);
} else {
console.log('UNCAUGHT ERROR:', err);
}
process.exit(1);
})
.then(code => process.exit(code)),
),
yargs,
)
.demand(1)
.strict()
.recommendCommands()
.help('h')
.alias('h', 'help').argv;
}
/**
* Look to see if the CWD is within an npm project. If it is, and that project
* has a flow-typed CLI `npm install`ed, use that version instead of the global
* version of the CLI.
*/
if (require.main === module) {
const CWD = process.cwd();
let currDir = CWD;
let lastDir = null;
let run = runCLI;
while (currDir !== lastDir) {
const localCLIPath = path.join(
currDir,
'node_modules',
'.bin',
'flow-typed',
);
try {
if (fs.statSync(localCLIPath).isFile()) {
run = require.call(null, localCLIPath).runCLI;
break;
}
} catch (e) {
/* File doesn't exist, move up a dir... */
}
lastDir = currDir;
currDir = path.resolve(currDir, '..');
}
run();
}