Skip to content

Commit f3ff44e

Browse files
authored
Merge pull request #80 from bertdeblock/support-running-generators-interactively
Support running generators interactively
2 parents 72b3b2c + f7ed95d commit f3ff44e

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ yarn add -D @bertdeblock/gember
4747

4848
## Usage
4949

50+
> 💡 Run `pnpm gember` to run generators interactively.
51+
5052
> 💡 Run `pnpm gember --help` for all available generators.
5153
5254
> 💡 Run `pnpm gember <generator-name> --help` for all available generator options.

src/cli.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ import { dirname, join } from "node:path";
99
import { fileURLToPath } from "node:url";
1010
// eslint-disable-next-line n/no-missing-import
1111
import type { PackageJson } from "type-fest";
12-
import { logGemberErrors } from "./errors.js";
12+
import { GemberError, logGemberErrors } from "./errors.js";
1313
import { generators } from "./generators.js";
14+
import { logger } from "./logger.js";
1415

1516
const { description, name, version }: PackageJson = readJsonSync(
1617
join(dirname(fileURLToPath(import.meta.url)), "..", "package.json"),
@@ -23,6 +24,62 @@ const main = defineCommand({
2324
version,
2425
},
2526

27+
run: (context): void => {
28+
if (context.rawArgs.length > 0) {
29+
return;
30+
}
31+
32+
logGemberErrors(async () => {
33+
// @ts-expect-error: The `multiselect` return type is incorrect:
34+
const selectedGeneratorNames: string[] | undefined = await logger.prompt(
35+
"Which generators would you like to run?",
36+
{
37+
options: generators.map((generator) => ({
38+
hint: generator.description,
39+
label: generator.name,
40+
value: generator.name,
41+
})),
42+
type: "multiselect",
43+
},
44+
);
45+
46+
if (selectedGeneratorNames === undefined) {
47+
// The user probably cancelled the interactive flow:
48+
return;
49+
}
50+
51+
let entityName: string | undefined;
52+
53+
for (const selectedGeneratorName of selectedGeneratorNames.sort()) {
54+
const selectedGenerator = generators.find(
55+
(generator) => generator.name === selectedGeneratorName,
56+
);
57+
58+
if (selectedGenerator === undefined) {
59+
throw new GemberError(
60+
`[BUG] Could not find generator \`${selectedGeneratorName}\`.`,
61+
);
62+
}
63+
64+
entityName = await logger.prompt(
65+
`Please provide a name for generator \`${selectedGenerator.name}\`:`,
66+
{
67+
initial: entityName,
68+
type: "text",
69+
},
70+
);
71+
72+
if (entityName === undefined) {
73+
throw new GemberError(
74+
`A name must be provided for generator \`${selectedGenerator.name}\`.`,
75+
);
76+
}
77+
78+
await selectedGenerator.run({ name: entityName });
79+
}
80+
});
81+
},
82+
2683
subCommands: generators.reduce((subCommands: SubCommandsDef, generator) => {
2784
subCommands[generator.name] = {
2885
args: generator.args.reduce((args: ArgsDef, arg) => {

src/generator.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ export function defineGenerator({
158158
{ type: "confirm" },
159159
);
160160

161+
logger.log("");
162+
161163
if (response === false) {
162164
return;
163165
}
@@ -211,7 +213,7 @@ export function defineTestGenerator(
211213
return defineGenerator({
212214
...options,
213215
modifyTargetFile: (targetFile, args) => {
214-
if (args.path === undefined) {
216+
if (args.path === undefined && env.GEMBER_PATH === undefined) {
215217
targetFile.subDir = join(
216218
"tests",
217219
options.testsDir,

0 commit comments

Comments
 (0)