Skip to content

Commit 97def0d

Browse files
refactor(cli): use hooks to avoid DRY
1 parent 180f89c commit 97def0d

File tree

1 file changed

+51
-28
lines changed

1 file changed

+51
-28
lines changed

packages/webpack-cli/src/webpack-cli.ts

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ interface Command extends CommanderCommand {
104104
context: Context;
105105
}
106106

107+
interface CommandUIOptions {
108+
description?: string;
109+
footer?: "global" | "command";
110+
skipIf?: (opts: RecordAny) => boolean;
111+
}
112+
107113
interface CommandOptions<
108114
A = void,
109115
O extends CommanderArgs = CommanderArgs,
@@ -117,6 +123,7 @@ interface CommandOptions<
117123
dependencies?: string[];
118124
pkg?: string;
119125
preload?: () => Promise<C>;
126+
ui?: CommandUIOptions;
120127
options?:
121128
| CommandOption[]
122129
| ((command: Command & { context: C }) => CommandOption[])
@@ -673,6 +680,33 @@ class WebpackCLI {
673680

674681
command.action(options.action);
675682

683+
if (options.ui) {
684+
const { ui } = options;
685+
686+
command.hook("preAction", (_thisCmd, actionCmd) => {
687+
if (ui.skipIf?.(actionCmd.opts())) return;
688+
689+
renderCommandHeader(
690+
{
691+
name: command.name(),
692+
description: ui.description ?? command.description(),
693+
},
694+
this.#renderOptions(),
695+
);
696+
});
697+
698+
command.hook("postAction", (_thisCmd, actionCmd) => {
699+
if (ui.skipIf?.(actionCmd.opts())) return;
700+
701+
const renderOpts = this.#renderOptions();
702+
if (ui.footer === "command") {
703+
renderCommandFooter(renderOpts);
704+
} else {
705+
renderFooter(renderOpts);
706+
}
707+
});
708+
}
709+
676710
return command;
677711
}
678712

@@ -1830,29 +1864,26 @@ class WebpackCLI {
18301864
hidden: false,
18311865
},
18321866
],
1867+
ui: {
1868+
description: "Installed package versions.",
1869+
footer: "global",
1870+
skipIf: (opts) => Boolean(opts.output),
1871+
},
18331872
action: async (options: { output?: string }) => {
1834-
const renderOpts = this.#renderOptions();
1835-
18361873
if (options.output) {
18371874
// Machine-readable output requested, bypass the visual renderer entirely.
18381875
const info = await this.#renderVersion(options);
18391876
this.logger.raw(info);
18401877
return;
18411878
}
18421879

1843-
renderCommandHeader(
1844-
{ name: "version", description: "Installed package versions." },
1845-
renderOpts,
1846-
);
1847-
18481880
const rawInfo = await this.#getInfoOutput({
18491881
information: {
18501882
npmPackages: `{${DEFAULT_WEBPACK_PACKAGES.map((item) => `*${item}*`).join(",")}}`,
18511883
},
18521884
});
18531885

1854-
renderVersionOutput(rawInfo, renderOpts);
1855-
renderFooter(renderOpts);
1886+
renderVersionOutput(rawInfo, this.#renderOptions());
18561887
},
18571888
},
18581889
info: {
@@ -1882,24 +1913,18 @@ class WebpackCLI {
18821913
hidden: false,
18831914
},
18841915
],
1916+
ui: {
1917+
description: "System and environment information.",
1918+
footer: "global",
1919+
skipIf: (opts) => Boolean(opts.output),
1920+
},
18851921
action: async (options: { output?: string; additionalPackage?: string[] }) => {
1886-
const renderOpts = this.#renderOptions();
1887-
1888-
if (!options.output) {
1889-
renderCommandHeader(
1890-
{ name: "info", description: "System and environment information." },
1891-
renderOpts,
1892-
);
1893-
}
1894-
1895-
const info = await this.#getInfoOutput(options);
1896-
18971922
if (options.output) {
1898-
this.logger.raw(info);
1923+
this.logger.raw(await this.#getInfoOutput(options));
18991924
return;
19001925
}
19011926

1902-
renderInfoOutput(info, renderOpts);
1927+
renderInfoOutput(await this.#getInfoOutput(options), this.#renderOptions());
19031928
},
19041929
},
19051930
configtest: {
@@ -1913,6 +1938,10 @@ class WebpackCLI {
19131938
const webpack = await this.loadWebpack();
19141939
return { webpack };
19151940
},
1941+
ui: {
1942+
description: "Validating your webpack configuration.",
1943+
footer: "command",
1944+
},
19161945
action: async (configPath: string | undefined, _options: CommanderArgs, cmd) => {
19171946
const { webpack } = cmd.context;
19181947
const env: Env = {};
@@ -1944,11 +1973,6 @@ class WebpackCLI {
19441973
process.exit(2);
19451974
}
19461975

1947-
renderCommandHeader(
1948-
{ name: "configtest", description: "Validating your webpack configuration." },
1949-
renderOpts,
1950-
);
1951-
19521976
const pathList = [...configPaths].join(", ");
19531977
renderWarning(`Validating: ${pathList}`, renderOpts);
19541978

@@ -1965,7 +1989,6 @@ class WebpackCLI {
19651989
}
19661990

19671991
renderSuccess("No validation errors found.", renderOpts);
1968-
renderCommandFooter(renderOpts);
19691992
},
19701993
},
19711994
};

0 commit comments

Comments
 (0)