diff --git a/package.json b/package.json index 9e093da6e..d5fd7678f 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,8 @@ "repository": "oclif/core", "oclif": { "bin": "oclif", - "plugins": [ + "devPlugins": [ + "@oclif/plugin-help", "@oclif/plugin-plugins" ] }, diff --git a/src/main.ts b/src/main.ts index 3f610dcc2..d595ba927 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,53 +1,63 @@ +import {format, inspect} from 'util' + import * as Interfaces from './interfaces' -import {HelpBase, getHelpClass} from './help' -import Command from './command' +import {Config} from './config' +import {getHelpClass} from './help' const ROOT_INDEX_CMD_ID = '' -export class Main extends Command { - static run(argv = process.argv.slice(2), options?: Interfaces.LoadOptions) { - return super.run(argv, options || (module.parent && module.parent.parent && module.parent.parent.filename) || __dirname) - } +const log = (message = '', ...args: any[]) => { + // tslint:disable-next-line strict-type-predicates + message = typeof message === 'string' ? message : inspect(message) + process.stdout.write(format(message, ...args) + '\n') +} - async init() { - const [id, ...argv] = this.argv - await this.config.runHook('init', {id, argv}) - return super.init() +const helpOverride = (argv: string[], config: Interfaces.Config): boolean => { + if (['-h', 'help'].includes(argv[0])) return true + if (argv.length === 0 && !config.findCommand(ROOT_INDEX_CMD_ID)) return true + for (const arg of argv) { + if (arg === '--help') return true + if (arg === '--') return false } + return false +} - async run() { - let [id, ...argv] = this.argv - this.parse({strict: false, '--': false, ...this.ctor as any}) - if (!this.config.findCommand(id)) { - const topic = this.config.findTopic(id) - if (topic) return this._help() - if (this.config.findCommand(ROOT_INDEX_CMD_ID)) { - id = ROOT_INDEX_CMD_ID - argv = this.argv - } - } - await this.config.runCommand(id, argv) - } +const versionOverride = (argv: string[]): boolean => { + if (['-v', '--version', 'version'].includes(argv[0])) return true + return false +} - protected _helpOverride(): boolean { - if (['-v', '--version', 'version'].includes(this.argv[0])) return this._version() as any - if (['-h', 'help'].includes(this.argv[0])) return true - if (this.argv.length === 0 && !this.config.findCommand(ROOT_INDEX_CMD_ID)) return true - for (const arg of this.argv) { - if (arg === '--help') return true - if (arg === '--') return false - } - return false +export async function run(argv = process.argv.slice(2), options?: Interfaces.LoadOptions) { + // return Main.run(argv, options) + const config = await Config.load(options || (module.parent && module.parent.parent && module.parent.parent.filename) || __dirname) as Config + + // run init hook + let [id, ...argvSlice] = argv + await config.runHook('init', {id, argv: argvSlice}) + + // display version if applicable + if (versionOverride(argv)) { + log(config.userAgent) + return } - protected _help() { - const HelpClass = getHelpClass(this.config) - const help: HelpBase = new HelpClass(this.config) - help.showHelp(this.argv) - return this.exit(0) + // display help version if applicable + if (helpOverride(argv, config)) { + const Help = getHelpClass(config) + const help = new Help(config) + const helpArgv = config.findCommand(ROOT_INDEX_CMD_ID) ? ['', ...argv] : argv + help.showHelp(helpArgv) + return } -} -export function run(argv = process.argv.slice(2), options?: Interfaces.LoadOptions) { - return Main.run(argv, options) + // find & run command + if (!config.findCommand(id)) { + const topic = config.findTopic(id) + if (topic) return config.runCommand('help', [id]) + if (config.findCommand(ROOT_INDEX_CMD_ID)) { + id = ROOT_INDEX_CMD_ID + argvSlice = argv + } + } + await config.runCommand(id, argvSlice) } diff --git a/test/command/main.test.ts b/test/command/main.test.ts index 8de34f1af..ac72f2a3a 100644 --- a/test/command/main.test.ts +++ b/test/command/main.test.ts @@ -1,9 +1,7 @@ import {expect, fancy} from 'fancy-test' import path = require('path') -import {Main} from '../../src/main' -import {Config} from '../../src' -import {TestHelpClassConfig} from './helpers/test-help-in-src/src/test-help-plugin' +import {run} from '../../src/main' const root = path.resolve(__dirname, '../../package.json') const pjson = require(root) @@ -12,21 +10,19 @@ const version = `@oclif/core/${pjson.version} ${process.platform}-${process.arch describe('main', () => { fancy .stdout() - .do(() => Main.run(['plugins'], root)) + .do(() => run(['plugins'], root)) .do((output: any) => expect(output.stdout).to.equal('no plugins installed\n')) .it('runs plugins') fancy .stdout() - .do(() => Main.run(['-v'], root)) - .catch('EEXIT: 0') + .do(() => run(['-v'], root)) .do((output: any) => expect(output.stdout).to.equal(version + '\n')) .it('runs -v') fancy .stdout() - .do(() => Main.run(['-h'], root)) - .catch('EEXIT: 0') + .do(() => run(['-h'], root)) .do((output: any) => expect(output.stdout).to.equal(`base library for oclif CLIs VERSION @@ -39,42 +35,9 @@ TOPICS plugins list installed plugins COMMANDS + help display help for oclif plugins list installed plugins `)) .it('runs -h') - - describe('with an alternative help class', async () => { - const getMainWithHelpClass = async () => { - const config: TestHelpClassConfig = await Config.load(root) - config.pjson.oclif.helpClass = './test/command/helpers/test-help-in-src/src/test-help-plugin' - - class MainWithHelpClass extends Main { - config = config - } - - return MainWithHelpClass - } - - fancy - .stdout() - .do(async () => (await getMainWithHelpClass()).run(['-h'])) - .catch('EEXIT: 0') - .do((output: any) => expect(output.stdout).to.equal('hello showHelp\n')) - .it('works with -h') - - fancy - .stdout() - .do(async () => (await getMainWithHelpClass()).run(['--help'])) - .catch('EEXIT: 0') - .do((output: any) => expect(output.stdout).to.equal('hello showHelp\n')) - .it('works with --help') - - fancy - .stdout() - .do(async () => (await getMainWithHelpClass()).run(['help'])) - .catch('EEXIT: 0') - .do((output: any) => expect(output.stdout).to.equal('hello showHelp\n')) - .it('works with help') - }) })