From c19c9db2bf547076125a65f866b1502acc70e2e8 Mon Sep 17 00:00:00 2001 From: Melvin Chia Date: Mon, 6 Oct 2025 09:14:36 +0800 Subject: [PATCH] feat(scripts): integrate commander for improved command handling in forge script and update dependencies Former-commit-id: 8b4e1ae331a8102be9fd4a84ccfc1b89227e4f20 [formerly 4086c345dd8ba0b6d10e61f9969159f3463d3efc] [formerly aeed3a1da5ad02d14384186d1c21232f58e56b5b [formerly ceb98f1bf92429b811e4da6d6469ae9858504d45]] Former-commit-id: 3ac12d35101d9625f0d0cab1ebf3044bf91eb60b [formerly 8df12141977205413f4a5b6b319917c3146bafe4] Former-commit-id: 228f4741a22781e51f9d103855d3ca14e869dc97 --- bun.lock | 5 ++- package.json | 1 + scripts/forge.ts | 112 ++++++++++++++++++++++++++--------------------- 3 files changed, 67 insertions(+), 51 deletions(-) diff --git a/bun.lock b/bun.lock index 62db210f0..48c5d463d 100644 --- a/bun.lock +++ b/bun.lock @@ -23,6 +23,7 @@ "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "bun-types": "latest", + "commander": "^14.0.1", "concurrently": "^9.1.2", "eslint": "^9.26.0", "eslint-config-standard-with-typescript": "^40.0.0", @@ -1877,7 +1878,7 @@ "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], - "commander": ["commander@5.1.0", "", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="], + "commander": ["commander@14.0.1", "", {}, "sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A=="], "component-emitter": ["component-emitter@1.3.1", "", {}, "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ=="], @@ -4541,6 +4542,8 @@ "epub/xml2js": ["xml2js@0.4.23", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug=="], + "epub-wordcount/commander": ["commander@5.1.0", "", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="], + "epub-wordcount/debug": ["debug@4.1.1", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw=="], "error-ex/is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], diff --git a/package.json b/package.json index d081b5e52..ddc481421 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "bun-types": "latest", + "commander": "^14.0.1", "concurrently": "^9.1.2", "eslint": "^9.26.0", "eslint-config-standard-with-typescript": "^40.0.0", diff --git a/scripts/forge.ts b/scripts/forge.ts index ca941486a..6563ea6aa 100644 --- a/scripts/forge.ts +++ b/scripts/forge.ts @@ -1,10 +1,11 @@ import { execSync } from 'child_process' +import { program } from 'commander' import fs from 'fs' import path from 'path' const TOOLS_DIR = path.join(__dirname, '../tools') -const PROCESS_ALLOWED = ['build', 'dev', 'types', 'lint'] +const PROCESS_ALLOWED = ['build', 'dev', 'types', 'lint'] as const const PROJECTS_ALLOWED = Object.assign( { @@ -21,61 +22,72 @@ const PROJECTS_ALLOWED = Object.assign( ) ) -const processType = process.argv[2] +type ProcessType = (typeof PROCESS_ALLOWED)[number] +type ProjectType = keyof typeof PROJECTS_ALLOWED -const projectTypes = process.argv.slice(3) +function executeCommand( + processType: ProcessType, + projects: ProjectType[] +): void { + const isAll = projects.includes('all' as ProjectType) -if (!PROCESS_ALLOWED.includes(processType)) { - console.error( - `Invalid process type: ${processType}. Allowed types are: ${PROCESS_ALLOWED.join(', ')}` + const finalProjects = isAll + ? (Object.keys(PROJECTS_ALLOWED) as ProjectType[]) + : projects + + const commands = finalProjects.map( + projectType => + `cd ${PROJECTS_ALLOWED[projectType]} && bun run ${processType}` ) - process.exit(1) -} -if (projectTypes.length === 0) { - console.error( - `No project type specified. Allowed projects are: all, ${Object.keys( - PROJECTS_ALLOWED - ).join(', ')}` - ) - process.exit(1) -} + console.log(`Running ${processType} for ${finalProjects.length} projects...`) -if ( - JSON.stringify(projectTypes) !== '["all"]' && - !projectTypes.every(projectType => - Object.keys(PROJECTS_ALLOWED).includes(projectType) - ) -) { - console.error( - `Invalid project type: ${projectTypes.find(projectType => !Object.keys(PROJECTS_ALLOWED).includes(projectType))}. Allowed projects are: all, ${Object.keys(PROJECTS_ALLOWED).join(', ')}` - ) - process.exit(1) -} + for (const command of commands) { + console.log(`Executing command: ${command}`) -const isAll = JSON.stringify(projectTypes) === '["all"]' - -const finalProjects = isAll ? Object.keys(PROJECTS_ALLOWED) : projectTypes - -const commands = finalProjects.map( - projectType => - `cd ${PROJECTS_ALLOWED[projectType as keyof typeof PROJECTS_ALLOWED]} && bun run ${processType}` -) - -console.log(`Running ${processType} for ${finalProjects.length} projects...`) - -for (const command of commands) { - console.log(`Executing command: ${command}`) - - try { - execSync(command, { stdio: 'inherit' }) - - console.log(`Command completed: ${command}`) - } catch { - console.error(`Command failed: ${command}`) - process.exit(1) + try { + execSync(command, { stdio: 'inherit' }) + console.log(`Command completed: ${command}`) + } catch { + console.error(`Command failed: ${command}`) + process.exit(1) + } } + + console.log(`All projects ${processType} completed successfully.`) } -console.log(`All projects ${processType} completed successfully.`) -process.exit(0) +program + .name('Lifeforge Forge') + .description('Build and manage Lifeforge projects') + .version('25w41') + +// Add individual commands for each process type +for (const processType of PROCESS_ALLOWED) { + program + .command(processType) + .description(`Run ${processType} for specified projects`) + .argument( + '', + `Project names to run ${processType} on. Use 'all' for all projects. Available: all, ${Object.keys(PROJECTS_ALLOWED).join(', ')}` + ) + .action((projects: string[]) => { + // Validate projects + const validProjects = [...Object.keys(PROJECTS_ALLOWED), 'all'] + + const invalidProjects = projects.filter( + project => !validProjects.includes(project) + ) + + if (invalidProjects.length > 0) { + console.error( + `Invalid project(s): ${invalidProjects.join(', ')}. Allowed projects are: all, ${Object.keys(PROJECTS_ALLOWED).join(', ')}` + ) + process.exit(1) + } + + executeCommand(processType, projects as ProjectType[]) + }) +} + +program.parse()