As a template author, I want to define computed variables in the manifest so that derived values (like packagePath from packageName) are automatically available without user input.
Evaluate in order: Computed variables are processed in manifest declaration order. If a computed var references another that hasn't been computed yet, Velocity throws TemplateRenderException. This implicitly catches circular dependencies without DAG complexity.
Manifest storage: Add computed field to TemplateManifest record. Computed variables are defined alongside prompts in manifest.yaml.
## Implementation Approach
### Design Decisions
1. **Evaluate in order**: Computed variables are processed in manifest declaration order. If a computed var references another that hasn't been computed yet, Velocity throws `TemplateRenderException`. This implicitly catches circular dependencies without DAG complexity.
2. **Manifest storage**: Add `computed` field to `TemplateManifest` record. Computed variables are defined alongside prompts in `manifest.yaml`.
### Manifest Schema
```yaml
computed:
- name: packagePath
expression: "$str.replace($packageName, '.', '/')"
- name: appClassName
expression: "$str.pascal($appName)"
```
### Implementation
1. Add `List<ComputedVariable>` to `TemplateManifest`
2. Create `ComputedVariable` record with `name` and `expression` fields
3. Add `evaluateComputed()` method to `TemplateEngine`
4. Call evaluation after prompts collected, before rendering
### Files to Modify
- `TemplateManifest.java` - Add computed field
- `ComputedVariable.java` - NEW record
- `TemplateEngine.java` - Add `evaluateComputed()` method
- `InitCommand.java` - Call evaluation in workflow
### Test Coverage
- Basic expression evaluation
- StringTool usage in expressions
- Variable chaining (computed using other computed)
- Undefined variable detection (implicit cycle detection)
- Empty/null handling
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Part of #12
User Story
As a template author, I want to define computed variables in the manifest so that derived values (like
packagePathfrompackageName) are automatically available without user input.Design
Computed Variables Section
Add
computedsection to template manifest:Expression Engine
Use Velocity for computed expressions:
$packageName$packageName.replace('.', '/')$appName.substring(0,1).toUpperCase()Evaluation Order
Circular Dependency Detection
Computed variables cannot reference each other circularly. Engine validates the dependency graph before evaluation.
Files to Create/Modify
TemplateManifest.javaMap<String, String> computedfieldComputedVariableEvaluator.javaTemplateEngine.javaInitCommand.javaImplementation Tasks
computedfield toTemplateManifestrecordComputedVariableEvaluatorclassAcceptance Criteria
packagePathderives correctly frompackageName.replace(),.substring())Implementation Approach
Design Decisions
Evaluate in order: Computed variables are processed in manifest declaration order. If a computed var references another that hasn't been computed yet, Velocity throws
TemplateRenderException. This implicitly catches circular dependencies without DAG complexity.Manifest storage: Add
computedfield toTemplateManifestrecord. Computed variables are defined alongside prompts inmanifest.yaml.Manifest Schema
Implementation
List<ComputedVariable>toTemplateManifestComputedVariablerecord withnameandexpressionfieldsevaluateComputed()method toTemplateEngineFiles to Modify
TemplateManifest.java- Add computed fieldComputedVariable.java- NEW recordTemplateEngine.java- AddevaluateComputed()methodInitCommand.java- Call evaluation in workflowTest Coverage
Implementation Complete
Files Created/Modified
StringTool.javareplace()methodComputedVariable.javaTemplateManifest.javacomputedfield (List)TemplatesHub.javacomputedfield to TemplateEntry recordTemplateEngine.javaevaluateComputed()methodInitCommand.javaTest Coverage
ComputedVariableTest.javaStringTool.replace()inStringToolTest.javaDesign Decisions
TemplateRenderException(implicit cycle detection).Usage