Implement cx new project template scaffolding#765
Conversation
CLA Verification FailedThe following contributors have not signed the Contributor License Agreement:
How to Sign
This check runs automatically. Maintainers can update |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe ChangesProject Scaffolding Implementation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Implements the cx new CLI command to scaffold new projects from a set of built-in templates.
Changes:
- Replaces the prior stub with functional project scaffolding (templated file writing, directory validation, and optional Python venv creation).
- Adds CLI ergonomics: positional project name,
--listtemplate listing, and default-template inference. - Adds unit tests covering template registration, name validation, rendering, and basic command execution.
| // CX Terminal: Create new projects from templates. | ||
| // | ||
| // This module provides the `new` command for creating new projects | ||
| // from predefined templates. Templates include common project types | ||
| // like Rust, Python, Node.js, and more. |
| }, | ||
| TemplateFile { | ||
| path: "src/{{python_module}}/__init__.py", | ||
| contents: r#""""{{project_name}} package.""" |
| fn create_python_venv(target_dir: &Path) -> Result<()> { | ||
| let venv_dir = target_dir.join(".venv"); | ||
| let status = Command::new("python3") | ||
| .args(["-m", "venv", ".venv"]) | ||
| .current_dir(target_dir) | ||
| .status(); | ||
|
|
||
| match status { | ||
| Ok(status) if status.success() => Ok(()), | ||
| _ => { | ||
| fs::create_dir_all(&venv_dir) | ||
| .with_context(|| format!("failed to create {}", venv_dir.display()))?; | ||
| fs::write( | ||
| venv_dir.join("README.md"), | ||
| "Create the virtual environment with:\n\n```bash\npython3 -m venv .venv\n```\n", |
| /// cx-terminal new rust my-project | ||
| /// cx-terminal new python --name my-project --dir /path/to/projects | ||
| /// cx-terminal new --list |
| } else if current_dir.join("package.json").exists() { | ||
| "node" |
There was a problem hiding this comment.
Code Review
This pull request implements the new command, transitioning it from a stub to a functional project scaffolding tool. It introduces a template system supporting various languages and frameworks (Rust, Python, Node, etc.), project name validation, and automatic directory setup. Feedback focused on improving documentation syntax, optimizing template storage using lazy initialization, ensuring consistency in virtual environment creation for Python-based templates, and clarifying placeholder usage in Docker configurations.
| // CX Terminal: Create new projects from templates. | ||
| // | ||
| // This module provides the `new` command for creating new projects | ||
| // from predefined templates. Templates include common project types | ||
| // like Rust, Python, Node.js, and more. |
There was a problem hiding this comment.
The module-level comments should use the //! syntax for documentation that applies to the entire module, which will be picked up by rustdoc. This was also the style used previously in this file.
| // CX Terminal: Create new projects from templates. | |
| // | |
| // This module provides the `new` command for creating new projects | |
| // from predefined templates. Templates include common project types | |
| // like Rust, Python, Node.js, and more. | |
| //! CX Terminal: Create new projects from templates. | |
| //! | |
| //! This module provides the `new` command for creating new projects | |
| //! from predefined templates. Templates include common project types | |
| //! like Rust, Python, Node.js, and more. |
| sanitized | ||
| } | ||
|
|
||
| fn templates() -> Vec<Template> { |
There was a problem hiding this comment.
The templates() function constructs a large Vec<Template> every time it's called. This can be inefficient, as it involves heap allocations and processing for all template definitions on each call.
Since the templates are static, this vector should be created only once. You can use once_cell::sync::Lazy to ensure the vector is initialized lazily and stored in a static variable.
Here's how you could refactor it:
use once_cell::sync::Lazy; // Add to imports
static TEMPLATES: Lazy<Vec<Template>> = Lazy::new(|| {
vec![
// ... all template definitions here ...
]
});
fn templates() -> &'static [Template] {
&TEMPLATES
}You would also need to update functions that call templates() (like find_template and print_available_templates) to work with a slice &[Template] instead of an owned Vec<Template>. For example, find_template would need to .cloned() the result.
| create_python_venv: false, | ||
| next_steps: vec![ | ||
| "cd {{project_name}}", | ||
| "python3 -m venv .venv && source .venv/bin/activate", | ||
| "pip install -r requirements.txt", | ||
| "uvicorn app.main:app --reload", | ||
| ], |
There was a problem hiding this comment.
The fastapi template is configured with create_python_venv: false, which is inconsistent with the python template (create_python_venv: true). Both are Python-based projects, and automatically creating the virtual environment provides a better and more consistent user experience.
I suggest setting create_python_venv: true for the fastapi template and updating the next_steps to reflect that the venv is already created.
| create_python_venv: false, | |
| next_steps: vec![ | |
| "cd {{project_name}}", | |
| "python3 -m venv .venv && source .venv/bin/activate", | |
| "pip install -r requirements.txt", | |
| "uvicorn app.main:app --reload", | |
| ], | |
| create_python_venv: true, | |
| next_steps: vec![ | |
| "cd {{project_name}}", | |
| "source .venv/bin/activate", | |
| "pip install -r requirements.txt", | |
| "uvicorn app.main:app --reload", | |
| ], |
| TemplateFile { | ||
| path: "docker-compose.yml", | ||
| contents: r#"services: | ||
| {{python_module}}: |
There was a problem hiding this comment.
The service name in the docker-compose.yml for the docker template is using {{python_module}}. This placeholder is typically for sanitized Python module names (e.g., my_app) and is confusing in a generic Docker template.
For better clarity and convention, you should use {{package_name}} (e.g., my-app), which is also used for the container_name.
| {{python_module}}: | |
| {{package_name}}: |



Summary
Fixes #708
Testing
I also tried cargo test -p cx-terminal cli::new in the source workspace, but Cargo fails before compiling this change because the existing optional hrm-ai git dependency points at revision 8bdce0fe12d8d84370e1d70d904bb9daee654c0a, which could not be fetched/authenticated in this environment.
Summary by CodeRabbit
newcommand with full template support--listflag to display available templates