-
-
Notifications
You must be signed in to change notification settings - Fork 147
feat(cli): Add template system for project initialization #676
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
base: dev
Are you sure you want to change the base?
Conversation
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.
7 files reviewed, 3 comments
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.
3 files reviewed, no comments
|
@ishaksebsib conflicts! |
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.
7 files reviewed, no comments
Description
Adds a complete template system to the Helix CLI, allowing users to initialize projects from Git-based templates with Handlebars variable substitution and caching.
Key Features
Template Sources:
helix init --template <template-name>helix init --template <template-name>@v1.0helix init --template https://github.com/user/repo@mainhelix init --template [email protected]:user/repo.git@v2Caching System:
~/.helix/templates/<url_hash>/<commit_hash>/git ls-remoteto check for updatesTemplate Processing:
{{project_name}}).hbsfile extension support for template filesUser Experience:
Implementation Details
New Files:
commands/templates/mod.rs- Template source parsing and configurationcommands/templates/fetcher.rs- Git operations, caching, and cache validationcommands/templates/processor.rs- Handlebars rendering and file copyingDependencies:
handlebars = "6.3.2"for template renderingtempfile = "3.23.0"for temporary filesModified Files:
commands/init.rs- Integrated template processing into the init flowcommands/mod.rs- Exposed templates moduleRelated Issues
None
Checklist when merging to main
rustfmthelix-cli/Cargo.tomlandhelixdb/Cargo.tomlAdditional Notes
None
Greptile Overview
Updated On: 2025-11-07 07:59:38 UTC
Greptile Summary
Implements a complete Git-based template system for the Helix CLI that enables project initialization from official or custom templates with Handlebars variable substitution. The implementation includes a sophisticated commit-hash based caching mechanism with network resilience and atomic operations.
Key Implementation Highlights:
mod.rshandles URL parsing for official templates and Git URLs (including SSH URLs with multiple@symbols),fetcher.rsmanages Git operations with atomic caching usingTempDir, andprocessor.rshandles Handlebars rendering~/.helix/templates/{url_hash}/{commit_hash}/ensures immutability and proper cache invalidation based on upstream commitsgit ls-remoteto check for updates, with graceful fallback to cached versions when network is unavailable (lines 43-48 in fetcher.rs)TempDir::new_in()within the base cache directory followed by atomic rename to prevent race conditions (lines 126-140 in fetcher.rs).gitignore(processor.rs:40), template validation ensureshelix.tomlorhelix.toml.hbsexists (fetcher.rs:179-185)Previous Review Comments Addressed:
db4d905c)723a8865)TempDirRAII pattern - directory is automatically cleaned up on drop if not explicitly keptCode Quality:
@in usernames and SSH URLsinit.rsmaintains existing project protection (checks for existinghelix.tomlbefore processing)No critical issues found. Implementation is production-ready.
Important Files Changed
File Analysis
git ls-remote, and network resilience with proper fallback to cached versions.hbsextension removal, correctly skips symlinks (line 45) and hidden files except.gitignore, filters.gitdirectories during recursionTemplateSourceenum for parsing official templates and Git URLs, handles SSH URLs with multiple@symbols correctly (line 36), includes comprehensive unit teststemplateparameter from unusedStringto functionalOption<String>, maintains existing project protection checkSequence Diagram
sequenceDiagram participant User participant CLI as helix init participant Init as init.rs participant Parser as TemplateSource::parse participant Fetcher as TemplateFetcher participant Git as Git Commands participant Cache as ~/.helix/templates participant Processor as TemplateProcessor participant HBS as Handlebars participant Project as Project Directory User->>CLI: helix init --template [email protected] CLI->>Init: run(template: Some("[email protected]")) Init->>Init: Check helix.toml doesn't exist Init->>Init: Create project directory Init->>Parser: parse("[email protected]") Parser-->>Init: TemplateSource::Official{name: "basic", git_ref: Some("v1.0")} Init->>Fetcher: fetch(source) Fetcher->>Git: git --version Git-->>Fetcher: version info Fetcher->>Fetcher: check_cache_validity(source) Fetcher->>Git: git ls-remote https://github.com/HelixDB/basic v1.0 alt Network Success Git-->>Fetcher: commit_hash: abc123... Fetcher->>Cache: Check if abc123 exists alt Cache Valid Cache-->>Fetcher: Cache exists Fetcher-->>Init: Return cache_path else Cache Invalid Fetcher->>Fetcher: fetch_and_cache(source) Fetcher->>Cache: Create TempDir in base_cache_dir Fetcher->>Git: git clone --depth 1 --branch v1.0 Git-->>Fetcher: Clone to temp directory Fetcher->>Fetcher: validate_template (check helix.toml exists) Fetcher->>Fetcher: Atomic rename temp to abc123 Fetcher-->>Init: Return cache_path end else Network Error Git-->>Fetcher: Network error Fetcher->>Cache: Check for any cached version alt Cache Exists Cache-->>Fetcher: Return latest cached version Fetcher-->>Init: Return cache_path (with warning) else No Cache Fetcher-->>Init: Error: network error and no cache end end Init->>Processor: render_to_dir(cache_dir, project_dir, variables) loop For each file in cache alt Is symlink Processor->>Processor: Skip (line 45) else Is hidden file (except .gitignore) Processor->>Processor: Skip (line 40) else Is directory Processor->>Processor: Recurse into directory else File ends with .hbs Processor->>HBS: render_template(content, variables) HBS-->>Processor: rendered content Processor->>Project: Write file (remove .hbs extension) else Regular file Processor->>Project: Copy file as-is end end Processor-->>Init: Rendering complete Init-->>User: Success message with next steps