diff --git a/src/index.ts b/src/index.ts index 0286ad7..162cd12 100644 --- a/src/index.ts +++ b/src/index.ts @@ -142,15 +142,22 @@ function logHelpMessage( async function getTools( { tools, dir, template }: Argv, extraTools?: ExtraTool[], + templateName?: string, ) { // Check if tools are specified via CLI options const parsedTools = parseToolsOption(tools); + // Filter extraTools based on templateName + const filteredExtraTools = extraTools?.filter((tool) => { + const when = tool.when ?? (() => true); + return templateName ? when(templateName) : true; + }); + if (parsedTools !== null) { const toolsArr = parsedTools.filter( (tool) => BUILTIN_TOOLS.includes(tool) || - extraTools?.some((extraTool) => extraTool.value === tool), + filteredExtraTools?.some((extraTool) => extraTool.value === tool), ); return toolsArr; } @@ -165,17 +172,21 @@ async function getTools( { value: 'prettier', label: 'Prettier - formatting' }, ]; - if (extraTools) { + if (filteredExtraTools) { const normalize = (tool: ExtraTool) => ({ value: tool.value, label: tool.label, hint: tool.command, }); options.unshift( - ...extraTools.filter((tool) => tool.order === 'pre').map(normalize), + ...filteredExtraTools + .filter((tool) => tool.order === 'pre') + .map(normalize), ); options.push( - ...extraTools.filter((tool) => tool.order !== 'pre').map(normalize), + ...filteredExtraTools + .filter((tool) => tool.order !== 'pre') + .map(normalize), ); } @@ -252,6 +263,12 @@ type ExtraTool = { * If undefined, the tool will be displayed after built-in tools. */ order?: 'pre' | 'post'; + /** + * Condition to determine whether this tool should be displayed. + * If returns false, the tool will not be shown in the selection. + * @default () => true + */ + when?: (templateName: string) => boolean; }; function runCommand(command: string, cwd: string, packageManager: string) { @@ -385,7 +402,7 @@ export async function create({ } const templateName = await getTemplateName(argv); - const tools = await getTools(argv, extraTools); + const tools = await getTools(argv, extraTools, templateName); const srcFolder = path.join(root, `template-${templateName}`); const commonFolder = path.join(root, 'template-common'); diff --git a/test/custom-tools.test.ts b/test/custom-tools.test.ts index 3d31ae2..40620fb 100644 --- a/test/custom-tools.test.ts +++ b/test/custom-tools.test.ts @@ -90,3 +90,62 @@ test('should run extra tool command', async () => { expect(fs.existsSync(testFile)).toBe(false); }); + +test('should filter extra tools based on template name', async () => { + const projectDir = path.join(testDir, 'extra-tool-filter'); + let filteredToolCalled = false; + let allowedToolCalled = false; + let noFilterToolCalled = false; + + await create({ + name: 'test', + root: fixturesDir, + templates: ['vanilla'], + getTemplateName: async () => 'vanilla', + extraTools: [ + { + value: 'filtered-tool', + label: 'Filtered Tool', + // This tool should be filtered out for 'vanilla' template + when: (templateName) => templateName !== 'vanilla', + action: () => { + filteredToolCalled = true; + }, + }, + { + value: 'allowed-tool', + label: 'Allowed Tool', + // This tool should be allowed for 'vanilla' template + when: (templateName) => templateName === 'vanilla', + action: () => { + allowedToolCalled = true; + }, + }, + { + value: 'no-filter-tool', + label: 'No Filter Tool', + // No `when` property - should always be available + action: () => { + noFilterToolCalled = true; + }, + }, + ], + argv: [ + 'node', + 'test', + '--dir', + projectDir, + '--template', + 'vanilla', + '--tools', + 'filtered-tool,allowed-tool,no-filter-tool', + ], + }); + + // filtered-tool should not run because `when` returns false + expect(filteredToolCalled).toBe(false); + // allowed-tool should run because `when` returns true + expect(allowedToolCalled).toBe(true); + // no-filter-tool should run because it has no `when` + expect(noFilterToolCalled).toBe(true); +});