diff --git a/packages/node-plop/src/generator-runner.js b/packages/node-plop/src/generator-runner.js index 961978e9..d79664c8 100644 --- a/packages/node-plop/src/generator-runner.js +++ b/packages/node-plop/src/generator-runner.js @@ -42,6 +42,7 @@ export default function (plopfileApi, flags) { onSuccess = noop, // runs after each successful action onFailure = noop, // runs after each failed action onComment = noop, // runs for each comment line in the actions array + onProgress = noop, // runs when custom actions update progress text } = hooks; const changes = []; // array of changed made by the actions const failures = []; // array of actions that failed @@ -77,7 +78,7 @@ export default function (plopfileApi, flags) { } const actionIsFunction = typeof action === "function"; - const actionCfg = actionIsFunction ? { type: "function" } : action; + const actionCfg = actionIsFunction ? { type: "function", onComment, onProgress } : action; const actionLogic = actionIsFunction ? action : actionTypes[actionCfg.type]; diff --git a/packages/node-plop/tests/lifecycle-hooks/lifecycle-hooks.spec.js b/packages/node-plop/tests/lifecycle-hooks/lifecycle-hooks.spec.js index 68964962..7eec6997 100644 --- a/packages/node-plop/tests/lifecycle-hooks/lifecycle-hooks.spec.js +++ b/packages/node-plop/tests/lifecycle-hooks/lifecycle-hooks.spec.js @@ -55,7 +55,7 @@ describe("lifecycle-hooks", function () { expect(onFailure.called).toBe(0); }); - test("Lifecycle hook test (onComment)", async function () { + test("Lifecycle hook test (onComment/onProgress)", async function () { const plop = await nodePlop(); const onSuccess = () => onSuccess.called++; onSuccess.called = 0; @@ -63,13 +63,24 @@ describe("lifecycle-hooks", function () { onFailure.called = 0; const onComment = () => onComment.called++; onComment.called = 0; + const onProgress = () => onProgress.called++; + onProgress.called = 0; await plop - .setGenerator("", { actions: ["yes", () => "yes", errAction, "yes"] }) - .runActions({}, { onSuccess, onFailure, onComment }); + .setGenerator("", { actions: [ + "yes", + () => "yes", + (_, { onProgress } )=>{ + onProgress(`progress`) + return "yes" + }, + errAction, "yes"] + }) + .runActions({}, { onSuccess, onFailure, onComment, onProgress }); - expect(onSuccess.called).toBe(1); + expect(onSuccess.called).toBe(2); expect(onFailure.called).toBe(1); expect(onComment.called).toBe(1); + expect(onProgress.called).toBe(1); }); }); diff --git a/packages/node-plop/types/index.d.ts b/packages/node-plop/types/index.d.ts index 377f6ac4..566b3bce 100644 --- a/packages/node-plop/types/index.d.ts +++ b/packages/node-plop/types/index.d.ts @@ -119,6 +119,7 @@ interface PlopActionHooksChanges { } interface PlopActionHooks { + onProgress?: (msg: string) => void; onComment?: (msg: string) => void; onSuccess?: (change: PlopActionHooksChanges) => void; onFailure?: (failure: PlopActionHooksFailures) => void; @@ -192,9 +193,25 @@ export interface CustomActionConfig [key: string]: any; } + export interface CustomActionConfigMaterialized extends CustomActionConfig { + /** + * Output a comment + * @param msg + * @returns + */ + onComment: (msg: string)=>void + + /** + * Output a progess update on the same line as the active spinner + * @param msg + * @returns + */ + onProgress: (msg: string)=>void +} + export type CustomActionFunction = ( answers: Answers, - config: CustomActionConfig, + config: CustomActionConfigMaterialized, plopfileApi: NodePlopAPI, ) => Promise | string; diff --git a/packages/node-plop/types/test.ts b/packages/node-plop/types/test.ts index 6abf1735..77666a9f 100644 --- a/packages/node-plop/types/test.ts +++ b/packages/node-plop/types/test.ts @@ -31,6 +31,9 @@ generator.runPrompts(["test"]).then((answers) => { const onComment = (): void => { console.log("Start"); }; + const onProgress = (): void => { + // console.log("Progress"); + }; const onSuccess = (): void => { console.log("This worked!"); }; @@ -38,7 +41,7 @@ generator.runPrompts(["test"]).then((answers) => { console.log("Failed"); }; return generator - .runActions(answers, { onSuccess, onFailure, onComment }) + .runActions(answers, { onSuccess, onFailure, onComment, onProgress }) .then(() => { console.log("Done"); }); @@ -348,6 +351,9 @@ _ = async () => { onComment: (msg) => { console.log(msg); }, + onProgress: (msg) => { + console.log(msg); + }, }) .then(() => { console.log("Test"); diff --git a/packages/node-plop/types/tsconfig.json b/packages/node-plop/types/tsconfig.json index 5be4a9dd..faa32828 100644 --- a/packages/node-plop/types/tsconfig.json +++ b/packages/node-plop/types/tsconfig.json @@ -11,5 +11,6 @@ "esModuleInterop": true, "allowSyntheticDefaultImports": true, "moduleResolution": "Node" - } + }, + "include": ["*.ts"] } diff --git a/packages/plop/src/plop.js b/packages/plop/src/plop.js index 251c75eb..d407e917 100644 --- a/packages/plop/src/plop.js +++ b/packages/plop/src/plop.js @@ -127,6 +127,13 @@ function doThePlop(generator, bypassArr) { }) .then((answers) => { const noMap = argv["show-type-names"] || argv.t; + const onProgress = (msg) => { + if(argv.progress!==false) { + progressSpinner.text = msg + } else { + console.log(msg) + } + } const onComment = (msg) => { progressSpinner.info(msg); progressSpinner.start(); @@ -160,7 +167,7 @@ function doThePlop(generator, bypassArr) { }; progressSpinner.start(); return generator - .runActions(answers, { onSuccess, onFailure, onComment }) + .runActions(answers, { onSuccess, onFailure, onComment, onProgress }) .then(() => { progressSpinner.stop(); if (failedActions) process.exit(1);