Close #1700: accept file arguments in typia generate CLI#1702
Close #1700: accept file arguments in typia generate CLI#1702knoan wants to merge 1 commit intosamchon:masterfrom
Conversation
CLI now accepts .ts files as positional arguments: typia generate file1.ts file2.ts --output dir --project tsconfig.json Changes: - ArgumentParser.ts: use program.opts() for reliable option extraction, capture positional file arguments - TypiaGenerateWizard.ts: add [files...] argument definition, skip --input prompt when files provided - TypiaProgrammer.ts: handle file list mode - use files directly instead of gather(), output to --output with basename 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR adds support for accepting file arguments as an alternative to --input directory in the typia generate CLI command. This allows users to specify individual .ts files for transformation using shell glob patterns, which is useful when template files are spread across multiple subdirectories.
Key changes:
- File arguments are captured as variadic arguments via Commander.js and passed through the option pipeline
- The transformation logic branches based on whether files or a directory is provided
- When using files, output goes directly to the output directory using basenames instead of preserving directory structure
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
src/executable/setup/ArgumentParser.ts |
Modified action handler to capture variadic file arguments from Commander.js and attach them to options |
src/executable/TypiaGenerateWizard.ts |
Added [files...] argument definition and conditional logic to skip --input prompt when files are provided |
src/programmers/TypiaProgrammer.ts |
Implemented dual-mode logic to handle file lists vs directories, including path resolution, TypeScript program creation, filtering, and output path generation |
| const to: string = hasFiles | ||
| ? path.join(location.output, path.basename(file.fileName)) | ||
| : path.resolve(file.fileName).replace(location.input, location.output); |
There was a problem hiding this comment.
When using file arguments mode, the output path can collide if multiple input files have the same basename. For example, src/users/user.typia.ts and src/orders/user.typia.ts would both write to output/user.typia.ts, with the second overwriting the first. Consider adding validation to detect duplicate basenames or implement a conflict resolution strategy.
| const resolvedFiles = hasFiles | ||
| ? location.files!.map((f) => path.resolve(f)) | ||
| : []; | ||
|
|
There was a problem hiding this comment.
Missing validation for file existence and accessibility. When files are provided as arguments, there's no check that they exist or are readable before attempting to create the TypeScript program. This could lead to unclear error messages later in the process. Consider adding validation similar to the directory validation for input paths.
| // Validate provided files (when using explicit file list) | |
| if (hasFiles) { | |
| for (const file of resolvedFiles) { | |
| try { | |
| const stat = await fs.promises.stat(file); | |
| if (stat.isFile() === false) { | |
| throw new URIError( | |
| "Error on TypiaGenerator.generate(): input file path is not a file: " + | |
| file, | |
| ); | |
| } | |
| await fs.promises.access(file, fs.constants.R_OK); | |
| } catch { | |
| throw new URIError( | |
| "Error on TypiaGenerator.generate(): input file does not exist or is not readable: " + | |
| file, | |
| ); | |
| } | |
| } | |
| } |
| // Skip import transformation when processing individual files | ||
| ...(hasFiles | ||
| ? [] | ||
| : [ | ||
| ImportTransformer.transform({ | ||
| from: location.input, | ||
| to: location.output, | ||
| }), | ||
| ]), |
There was a problem hiding this comment.
The comment states "Skip import transformation when processing individual files" but doesn't explain why this is necessary. The ImportTransformer appears to rewrite import paths from the input directory structure to the output directory structure. Skipping this for individual files may cause import paths to break if the generated files have different relative paths. This needs clarification or a more robust solution.
| commander.program.action(async (...args: unknown[]) => { | ||
| try { | ||
| // Commander passes: (positionalArgs..., options, command) | ||
| // Use program.opts() for reliable option extraction | ||
| const options = commander.program.opts() as Partial<T>; | ||
| // If there are positional arguments (files), attach them to options | ||
| if (args.length > 0 && Array.isArray(args[0])) { | ||
| (options as Partial<T> & { files?: string[] }).files = args[0]; | ||
| } |
There was a problem hiding this comment.
The new file arguments feature in the CLI lacks automated test coverage. While the repository has comprehensive testing for transformation features, there are no tests for CLI functionality like the ArgumentParser or TypiaGenerateWizard. Consider adding integration tests that verify file argument parsing, validation, and correct handling of both directory and file modes.
commit: |
Summary
Add support for file arguments as an alternative to
--inputdirectory intypia generateCLI.Changes
ArgumentParser.ts: Useprogram.opts()for reliable option extraction, capture positional file argumentsTypiaGenerateWizard.ts: Add[files...]argument definition, skip--inputprompt when files providedTypiaProgrammer.ts: Handle file list mode - use files directly instead ofgather(), output to--outputwith basenameCLI Interface
Testing
[files...]argumenttypia generate --output dir file.tsworkstypia generate file.ts --output dirworksCloses #1700