diff --git a/src/interfaces/hooks.ts b/src/interfaces/hooks.ts index 015995ea..81c533b1 100644 --- a/src/interfaces/hooks.ts +++ b/src/interfaces/hooks.ts @@ -26,6 +26,10 @@ export interface Hooks { options: {argv?: string[]; id: string} return: unknown } + finally: { + options: {argv: string[]; id: string} + return: void + } init: { options: {argv: string[]; id: string | undefined} return: void @@ -75,6 +79,10 @@ export type Hook = ( ) => Promise export namespace Hook { + /** + * Runs at the end of the CLI lifecycle - regardless of success or failure. + */ + export type Finally = Hook<'finally'> /** * Runs when the CLI is initialized before a command is executed. */ diff --git a/src/main.ts b/src/main.ts index ba2d312f..2d80ed92 100644 --- a/src/main.ts +++ b/src/main.ts @@ -32,13 +32,6 @@ export async function run(argv?: string[], options?: Interfaces.LoadOptions): Pr const initMarker = Performance.mark(OCLIF_MARKER_OWNER, 'main.run#init') - const collectPerf = async () => { - marker?.stop() - if (!initMarker?.stopped) initMarker?.stop() - await Performance.collect() - Performance.debug() - } - const showHelp = async (argv: string[]) => { const Help = await loadHelpClass(config) const help = new Help(config, config.pjson.oclif.helpOptions ?? config.pjson.helpOptions) @@ -67,20 +60,28 @@ export async function run(argv?: string[], options?: Interfaces.LoadOptions): Pr const [id, ...argvSlice] = normalizeArgv(config, argv) + const runFinally = async () => { + marker?.stop() + if (!initMarker?.stopped) initMarker?.stop() + await Performance.collect() + Performance.debug() + await config.runHook('finally', {argv: argvSlice, id}) + } + // run init hook await config.runHook('init', {argv: argvSlice, id}) // display version if applicable if (versionAddition(argv, config)) { ux.stdout(config.userAgent) - await collectPerf() + await runFinally() return } // display help version if applicable if (helpAddition(argv, config)) { await showHelp(argv) - await collectPerf() + await runFinally() return } @@ -90,7 +91,7 @@ export async function run(argv?: string[], options?: Interfaces.LoadOptions): Pr const topic = config.flexibleTaxonomy ? null : config.findTopic(id) if (topic) { await showHelp([id]) - await collectPerf() + await runFinally() return } } @@ -100,6 +101,6 @@ export async function run(argv?: string[], options?: Interfaces.LoadOptions): Pr try { return await config.runCommand(id, argvSlice, cmd) } finally { - await collectPerf() + await runFinally() } }