Skip to content

Commit b624e45

Browse files
committed
refactor: improve CLI override handling in project prompts
- Updated test cases to require exact CLI override names and prevent mapping of similar substring overrides. - Refactored promptUser function to streamline answer merging and removed unnecessary functions related to identifier matching. - Enhanced clarity in variable mapping by ensuring undefined values are handled correctly.
1 parent 72d78b4 commit b624e45

File tree

2 files changed

+10
-119
lines changed

2 files changed

+10
-119
lines changed

packages/create-gen-app/__tests__/create-gen.test.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ module.exports = {
284284
);
285285
});
286286

287-
it("should map CLI overrides with similar names to project questions", async () => {
287+
it("should require exact CLI override names", async () => {
288288
const { Inquirerer } = require("inquirerer");
289289
const mockPrompt = jest.fn().mockResolvedValue({});
290290

@@ -312,10 +312,11 @@ module.exports = {
312312
await promptUser(extractedVariables, argv, false);
313313

314314
const passedArgv = mockPrompt.mock.calls[0][0];
315-
expect(passedArgv.fullName).toBe("CLI User");
315+
expect(passedArgv.fullName).toBeUndefined();
316+
expect(passedArgv.USERFULLNAME).toBe("CLI User");
316317
});
317318

318-
it("should match CLI overrides sharing substrings", async () => {
319+
it("should not map CLI overrides sharing substrings", async () => {
319320
const { Inquirerer } = require("inquirerer");
320321
const mockPrompt = jest.fn().mockResolvedValue({});
321322

@@ -343,7 +344,8 @@ module.exports = {
343344
await promptUser(extractedVariables, argv, false);
344345

345346
const passedArgv = mockPrompt.mock.calls[0][0];
346-
expect(passedArgv.description).toBe("CLI description");
347+
expect(passedArgv.description).toBeUndefined();
348+
expect(passedArgv.MODULEDESC).toBe("CLI description");
347349
});
348350

349351
it("should hydrate template variables from alias answers", async () => {

packages/create-gen-app/src/template/prompt.ts

Lines changed: 4 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,10 @@ export async function promptUser(
9393

9494
try {
9595
const promptAnswers = await prompter.prompt(preparedArgv, questions);
96-
const mergedAnswers = {
96+
return {
9797
...argv,
9898
...promptAnswers,
9999
};
100-
return expandAnswersForVariables(mergedAnswers, extractedVariables);
101100
} finally {
102101
if (typeof (prompter as any).close === "function") {
103102
(prompter as any).close();
@@ -122,121 +121,11 @@ function mapArgvToQuestions(
122121
continue;
123122
}
124123

125-
const matchValue = findMatchingArgValue(name, argvEntries);
126-
if (matchValue !== null) {
127-
prepared[name] = matchValue;
128-
}
129-
}
130-
131-
return prepared;
132-
}
133-
134-
function findMatchingArgValue(
135-
targetName: string,
136-
argvEntries: [string, any][]
137-
): any | null {
138-
const normalizedTarget = normalizeIdentifier(targetName);
139-
140-
for (const [key, value] of argvEntries) {
141-
if (value === undefined || value === null) {
142-
continue;
143-
}
144-
145-
if (key === targetName) {
146-
return value;
147-
}
148-
149-
const normalizedKey = normalizeIdentifier(key);
150-
if (identifiersMatch(normalizedTarget, normalizedKey)) {
151-
return value;
152-
}
153-
}
154-
155-
return null;
156-
}
157-
158-
function normalizeIdentifier(value: string): string {
159-
return value.replace(/[^a-z0-9]/gi, "").toLowerCase();
160-
}
161-
162-
function identifiersMatch(a: string, b: string): boolean {
163-
if (a === b) {
164-
return true;
165-
}
166-
if (a.includes(b) || b.includes(a)) {
167-
return true;
168-
}
169-
return hasSignificantOverlap(a, b);
170-
}
171-
172-
function hasSignificantOverlap(a: string, b: string): boolean {
173-
const minLength = 4;
174-
if (a.length < minLength || b.length < minLength) {
175-
return false;
176-
}
177-
178-
const shorter = a.length <= b.length ? a : b;
179-
const longer = shorter === a ? b : a;
180-
181-
for (let i = 0; i <= shorter.length - minLength; i++) {
182-
const slice = shorter.slice(i, i + minLength);
183-
if (longer.includes(slice)) {
184-
return true;
185-
}
186-
}
187-
188-
return false;
189-
}
190-
191-
function expandAnswersForVariables(
192-
answers: Record<string, any>,
193-
extractedVariables: ExtractedVariables
194-
): Record<string, any> {
195-
const expanded = { ...answers };
196-
const variables = collectVariableNames(extractedVariables);
197-
const answerEntries = Object.entries(expanded).map(([key, value]) => ({
198-
key,
199-
value,
200-
normalized: normalizeIdentifier(key),
201-
}));
202-
203-
for (const variable of variables) {
204-
if (expanded[variable] !== undefined) {
205-
continue;
206-
}
207-
208-
const normalizedVar = normalizeIdentifier(variable);
209-
const match = answerEntries.find(({ normalized }) =>
210-
identifiersMatch(normalizedVar, normalized)
211-
);
212-
124+
const match = argvEntries.find(([key]) => key === name);
213125
if (match) {
214-
expanded[variable] = match.value;
215-
answerEntries.push({
216-
key: variable,
217-
value: match.value,
218-
normalized: normalizedVar,
219-
});
126+
prepared[name] = match[1];
220127
}
221128
}
222129

223-
return expanded;
224-
}
225-
226-
function collectVariableNames(
227-
extractedVariables: ExtractedVariables
228-
): Set<string> {
229-
const names = new Set<string>();
230-
for (const replacer of extractedVariables.fileReplacers) {
231-
names.add(replacer.variable);
232-
}
233-
for (const replacer of extractedVariables.contentReplacers) {
234-
names.add(replacer.variable);
235-
}
236-
if (extractedVariables.projectQuestions) {
237-
for (const question of extractedVariables.projectQuestions.questions) {
238-
names.add(normalizeQuestionName(question.name));
239-
}
240-
}
241-
return names;
130+
return prepared;
242131
}

0 commit comments

Comments
 (0)