-
Notifications
You must be signed in to change notification settings - Fork 0
feat: ✨ enhance README, refactor CLI code #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughRefactors the CLI scaffold into focused modules: constants, utils, template setup, and git initialization; reduces main orchestration to lightweight helpers; updates README and CHANGELOG with new documentation and badges. (50 words) Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User as CLI
participant Main as index.ts
participant Template as template.ts
participant FS as Filesystem
participant Bun as bun
participant Git as git
CLI->>Main: start create command (choose template, name)
Main->>Template: setupTemplate(projectType, targetDir)
Template->>FS: copyRecursive(templatePath → targetDir)
alt monorepo template
Template->>FS: copy backend biome to target path
end
Template->>Bun: run "bun install" in targetDir
Bun-->>Template: exit code (success/fail)
Template-->>Main: setup complete / error
Main->>Git: initializeGit(targetDir)
Git->>Git: check git availability
Git->>FS: git init / git add .
Git->>Git: git commit -m "Initial commit"
Git-->>Main: git initialized / skipped
Main-->>User: print next-steps message
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (5)
src/git.ts (1)
89-94: Consider logging the caught error for debugging.The catch block suppresses error details, which could make troubleshooting difficult for users. Consider logging the error before showing the warning.
🔎 Proposed improvement
- } catch { + } catch (error) { gitSpinner.stop('Git initialization failed'); + console.error('Error details:', error); clack.log.warn( 'An error occurred during git initialization. You can initialize manually later.', );src/utils.ts (2)
16-42: Add error handling for filesystem operations.The function doesn't handle errors from
statSync,mkdirSync, orcopyFileSync. If these operations fail (e.g., permission denied, disk full), the error will propagate as an unhandled exception with a potentially cryptic message.🔎 Proposed improvement
export function copyRecursive( src: string, dest: string, exclude: string[] = [], ): void { + try { const stats = statSync(src); if (stats.isDirectory()) { if (!existsSync(dest)) { mkdirSync(dest, { recursive: true }); } for (const entry of readdirSync(src)) { if (exclude.includes(entry) || entry.endsWith('.template')) continue; const srcPath = join(src, entry); const destPath = join(dest, entry); copyRecursive(srcPath, destPath, exclude); } } else { const destDir = dirname(dest); if (!existsSync(destDir)) { mkdirSync(destDir, { recursive: true }); } copyFileSync(src, dest); } + } catch (error) { + throw new Error(`Failed to copy ${src} to ${dest}: ${error}`); + } }
49-64: Consider extracting the regex to a constant.The validation regex is hardcoded inline. Extracting it to a constant in
src/constants.tswould improve maintainability and allow reuse if needed elsewhere.🔎 Suggested approach
In
src/constants.ts:export const PROJECT_NAME_REGEX = /^[a-z0-9-]+$/;Then in
src/utils.ts:+import { PROJECT_NAME_REGEX } from './constants.ts'; + export function validateProjectName(value: string): string | undefined { if (!value || value.trim() === '') { return 'Project name is required'; } const trimmed = value.trim(); - if (!/^[a-z0-9-]+$/.test(trimmed)) { + if (!PROJECT_NAME_REGEX.test(trimmed)) { return 'Project name must contain only lowercase letters, numbers, and hyphens'; }src/constants.ts (1)
8-8: DRY violation: Duplicate regex invalidateProjectName.The same regex pattern is hardcoded in
src/utils.ts(line 54). Consider importingPROJECT_NAME_REGEXinvalidateProjectNameto avoid drift if the pattern ever changes.🔎 Suggested fix in src/utils.ts
+import { PROJECT_NAME_REGEX } from './constants.ts'; + export function validateProjectName(value: string): string | undefined { if (!value || value.trim() === '') { return 'Project name is required'; } const trimmed = value.trim(); - if (!/^[a-z0-9-]+$/.test(trimmed)) { + if (!PROJECT_NAME_REGEX.test(trimmed)) { return 'Project name must contain only lowercase letters, numbers, and hyphens'; } // ... }src/index.ts (1)
20-26: Consider notifying user when CLI argument is rejected.If a user provides an invalid project name via CLI (e.g.,
bun create ely My-Project), the function silently falls through to the interactive prompt. Adding a warning would improve UX clarity.🔎 Optional enhancement
async function getProjectName(args: string[]): Promise<string> { const projectNameArg = args[0]; // If project name was provided as argument and is valid, use it if (projectNameArg && PROJECT_NAME_REGEX.test(projectNameArg)) { return projectNameArg; } + if (projectNameArg) { + clack.log.warn(`Invalid project name "${projectNameArg}". Must contain only lowercase letters, numbers, and hyphens.`); + } + // Otherwise, prompt for it with default value
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
assets/demo.mp4is excluded by!**/*.mp4
📒 Files selected for processing (7)
CHANGELOG.mdREADME.mdsrc/constants.tssrc/git.tssrc/index.tssrc/template.tssrc/utils.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Usebun <file>instead ofnode <file>orts-node <file>
Bun automatically loads .env files, so don't use the dotenv package
UseBun.serve()with built-in WebSocket, HTTPS, and route support instead ofexpress
Usebun:sqlitefor SQLite instead ofbetter-sqlite3
UseBun.redisfor Redis instead ofioredis
UseBun.sqlfor Postgres instead ofpgorpostgres.js
Use built-inWebSocketinstead ofwspackage
PreferBun.fileovernode:fsreadFile/writeFile for file operations
UseBun.$template literals for shell commands instead of execa
Files:
src/utils.tssrc/index.tssrc/git.tssrc/constants.tssrc/template.ts
**/*.{ts,tsx,css,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Use
bun build <file.html|file.ts|file.css>instead ofwebpackoresbuild
Files:
src/utils.tssrc/index.tssrc/git.tssrc/constants.tssrc/template.ts
**/*.{html,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use HTML imports with
Bun.serve()and don't usevitefor frontend bundling
Files:
src/utils.tssrc/index.tssrc/git.tssrc/constants.tssrc/template.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use
bun --hot <file.ts>to run TypeScript files with hot module reloading enabled
Files:
src/utils.tssrc/index.tssrc/git.tssrc/constants.tssrc/template.ts
🧠 Learnings (1)
📚 Learning: 2026-01-03T07:00:32.832Z
Learnt from: truehazker
Repo: truehazker/create-elysiajs PR: 2
File: templates/backend:1-1
Timestamp: 2026-01-03T07:00:32.832Z
Learning: In git diffs, symlinks (mode 120000) appear as added files containing the link target (e.g., +monorepo/apps/backend). Do not flag symlinks as placeholder files or accidental commits. This applies broadly; when reviewing files like templates/backend, verify whether it is a symlink and treat accordingly.
Applied to files:
CHANGELOG.mdREADME.md
🧬 Code graph analysis (2)
src/index.ts (4)
src/constants.ts (4)
PROJECT_NAME_REGEX(8-8)DEFAULT_PROJECT_NAME(6-6)TEMPLATE_TYPES(1-4)PORTS(12-15)src/utils.ts (1)
validateProjectName(49-64)src/template.ts (1)
setupTemplate(17-62)src/git.ts (1)
initializeGit(8-95)
src/template.ts (2)
src/utils.ts (1)
copyRecursive(16-42)src/constants.ts (3)
EXCLUDED_COPY_PATTERNS(10-10)TEMPLATE_TYPES(1-4)TEMPLATE_PATHS(17-20)
🪛 GitHub Actions: Lint
src/index.ts
[error] 159-164: File content differs from formatting output. Biome formatting check detected differences in src/index.ts during 'biome ci .' run.
🔇 Additional comments (7)
CHANGELOG.md (1)
10-19: LGTM! Well-documented refactoring changes.The changelog clearly documents the modularization work with specific details about what was extracted and the impact on code complexity.
src/template.ts (1)
17-62: LGTM! Clean template setup implementation.The function properly uses constants, handles errors appropriately, and follows Bun best practices with
Bun.spawn(). The inherited stdio ensures users see installation progress and errors directly.src/constants.ts (1)
1-20: Well-structured constants module.The centralization of configuration values with
as constassertions provides good type safety and maintainability for the CLI scaffolding logic.src/index.ts (4)
1-13: Clean modular imports.Good separation of concerns with dedicated modules for constants, git operations, template setup, and utilities.
51-77: Safe directory handling with proper user confirmation.Good defensive design: non-empty directory overwrite requires explicit confirmation with a safe default of
false.
86-114: Clear success message generation.Dynamic next steps based on project type with appropriate use of centralized constants.
116-175: Well-orchestrated main flow.The refactored main function is clean and readable with clear step-by-step progression. Proper error handling at both function and global levels ensures graceful failure modes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
README.mdsrc/index.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Usebun <file>instead ofnode <file>orts-node <file>
Bun automatically loads .env files, so don't use the dotenv package
UseBun.serve()with built-in WebSocket, HTTPS, and route support instead ofexpress
Usebun:sqlitefor SQLite instead ofbetter-sqlite3
UseBun.redisfor Redis instead ofioredis
UseBun.sqlfor Postgres instead ofpgorpostgres.js
Use built-inWebSocketinstead ofwspackage
PreferBun.fileovernode:fsreadFile/writeFile for file operations
UseBun.$template literals for shell commands instead of execa
Files:
src/index.ts
**/*.{ts,tsx,css,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Use
bun build <file.html|file.ts|file.css>instead ofwebpackoresbuild
Files:
src/index.ts
**/*.{html,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use HTML imports with
Bun.serve()and don't usevitefor frontend bundling
Files:
src/index.ts
**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use
bun --hot <file.ts>to run TypeScript files with hot module reloading enabled
Files:
src/index.ts
🧠 Learnings (1)
📚 Learning: 2026-01-03T07:00:32.832Z
Learnt from: truehazker
Repo: truehazker/create-elysiajs PR: 2
File: templates/backend:1-1
Timestamp: 2026-01-03T07:00:32.832Z
Learning: In git diffs, symlinks (mode 120000) appear as added files containing the link target (e.g., +monorepo/apps/backend). Do not flag symlinks as placeholder files or accidental commits. This applies broadly; when reviewing files like templates/backend, verify whether it is a symlink and treat accordingly.
Applied to files:
README.md
🧬 Code graph analysis (1)
src/index.ts (4)
src/constants.ts (4)
PROJECT_NAME_REGEX(8-8)DEFAULT_PROJECT_NAME(6-6)TEMPLATE_TYPES(1-4)PORTS(12-15)src/utils.ts (1)
validateProjectName(49-64)src/template.ts (1)
setupTemplate(17-62)src/git.ts (1)
initializeGit(8-95)
🔇 Additional comments (8)
README.md (4)
3-10: LGTM! Well-structured badges.The badges provide clear project status and technology stack information using standard shields.io formats.
14-14: Previous HTML video tag issue resolved.The demo now uses proper markdown image syntax that GitHub's renderer supports. Good fix!
16-50: LGTM! Clear and comprehensive documentation.The Quick Start instructions and template descriptions accurately reflect the refactored CLI structure and available project types.
51-55: LGTM! Important submodule warning.The git submodule warning and clone instructions are essential for contributors working with template repositories.
src/index.ts (4)
45-77: LGTM! Proper directory handling.The function correctly checks for directory existence, prompts for overwrite confirmation, and handles directory removal safely with the force option.
79-114: LGTM! Clear and helpful success message.The function provides appropriate next steps based on project type with correct port numbers and command examples.
116-168: LGTM! Well-structured orchestration flow.The main function is cleanly refactored with proper separation of concerns, using modular helpers for each step. Error handling is centralized and appropriate.
157-161: The code at lines 157-161 is already correctly formatted according to the Biome configuration (2-space indentation, proper semicolons, compliant line lengths). No formatting action is required.
| async function getProjectName(args: string[]): Promise<string> { | ||
| const projectNameArg = args[0]; | ||
|
|
||
| // If project name was provided as argument and is valid, use it | ||
| if (projectNameArg && PROJECT_NAME_REGEX.test(projectNameArg)) { | ||
| return projectNameArg; | ||
| } | ||
|
|
||
| // Otherwise, prompt for it with default value | ||
| const projectName = await clack.text({ | ||
| message: 'Project name:', | ||
| placeholder: DEFAULT_PROJECT_NAME, | ||
| initialValue: DEFAULT_PROJECT_NAME, | ||
| validate: validateProjectName, | ||
| }); | ||
|
|
||
| if (clack.isCancel(projectName)) { | ||
| clack.cancel('Operation cancelled'); | ||
| process.exit(0); | ||
| } | ||
|
|
||
| // Trim and normalize the project name | ||
| return projectName.trim(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix validation inconsistency for command-line arguments.
The validation at line 24 only checks PROJECT_NAME_REGEX but doesn't enforce the hyphen position rules that validateProjectName checks (lines starting/ending with hyphens). This means passing "-my-project" or "my-project-" as a CLI argument would be accepted here but would be rejected if entered via the prompt.
🔎 Proposed fix to use consistent validation
async function getProjectName(args: string[]): Promise<string> {
const projectNameArg = args[0];
- // If project name was provided as argument and is valid, use it
- if (projectNameArg && PROJECT_NAME_REGEX.test(projectNameArg)) {
- return projectNameArg;
+ // If project name was provided as argument, validate it
+ if (projectNameArg) {
+ const validationError = validateProjectName(projectNameArg);
+ if (!validationError) {
+ return projectNameArg.trim();
+ }
}
// Otherwise, prompt for it with default value🤖 Prompt for AI Agents
In src/index.ts around lines 20 to 43, the CLI-argument validation only uses
PROJECT_NAME_REGEX and thus accepts names that the prompt validator would reject
(e.g. names starting or ending with a hyphen); replace the single regex check
with the same validation used for prompt input by calling
validateProjectName(projectNameArg) (and ensure you trim the arg before
validating) so CLI arguments and interactive input are validated consistently,
returning the trimmed projectNameArg when it passes.
Summary by CodeRabbit
Documentation
New Features
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.