Architecture¶
Overview of Genifest's internal architecture and design decisions.
Work in Progress
This documentation page is being developed. Please check back soon for complete content.
System Overview¶
Genifest follows a modular architecture with clear separation of concerns:
graph TD
A[CLI Interface] --> B[Command Processors]
B --> C[Configuration Loader]
B --> D[Change Applier]
C --> E[Config Validation]
D --> F[Value Evaluation]
D --> G[YAML Processing]
F --> H[Function System]
F --> I[Script Execution] Core Components¶
CLI Layer (internal/cmd/)¶
Subcommand Architecture:
root.go- Main command dispatcherrun.go- Core functionality for applying changestags.go- Tag listing and managementvalidate.go- Configuration validationconfig.go- Configuration displayversion.go- Version informationcommon.go- Shared utilities
Key Features:
- Directory argument support
- Enhanced progress reporting
- Tag filtering logic
- Error handling with context
Configuration System (internal/config/)¶
Metadata-Driven Loading:
- Starts with root
genifest.yaml - Discovers additional configs through metadata
- Creates synthetic configs for directories without explicit configs
- Validates function references and path security
Core Types:
Config- Main configuration structureMetaConfig- Metadata for discoveryPathContext- Path with context informationChangeOrder- Change definitionsFunctionDefinition- Reusable functionsValueFrom- Union type for value sources
Value Evaluation (internal/changes/)¶
EvalContext System:
- Immutable context carrying current state
- File and document context awareness
- Variable scoping and isolation
- Function resolution and execution
Evaluators:
DefaultValue- Literal valuesArgumentRef- Variable referencesBasicTemplate- String templatesFunctionCall- Function executionScriptExec- External script executionFileInclusion- File content inclusionDocumentRef- Document field referencesCallPipeline- Multi-step processing
Change Application¶
Document Processing:
- Multi-document YAML handling
- Key selector path navigation
- Atomic file operations
- Change tracking and reporting
File Selector Matching:
- Glob pattern support
- Path-aware matching
Design Decisions¶
Immutable Contexts¶
Rationale: Prevents side effects and enables safe concurrent use
Implementation:
func (ctx *EvalContext) WithVariable(name, value string) *EvalContext {
newCtx := *ctx
newVars := make(map[string]string)
for k, v := range ctx.Variables {
newVars[k] = v
}
newVars[name] = value
newCtx.Variables = newVars
return &newCtx
}
Metadata-Driven Discovery¶
Rationale: Flexible project organization without rigid structure requirements
Benefits:
- Projects can organize files naturally
- Configurations stay close to managed files
- Automatic discovery reduces configuration burden
Function Scoping¶
Rationale: Prevents naming conflicts and ensures proper encapsulation
Rules:
- Functions are available in their definition directory and children
- Root functions are globally available
- Child functions can override parent functions
Limited Execution¶
This is not aimed at security as much as it is aimed at ensuring edits are constrained nothing unexpected happens.
CloudHome Boundary:
- All file operations must stay within cloudHome
- Path traversal prevention
- Script execution isolation
Script Boundary:
- Scripts must be in designated directories
- Working directory is always cloudHome
- Environment variable isolation
Key Patterns¶
Error Handling¶
Contextual Errors:
User-Friendly Messages:
- Distinguish configuration errors from system errors
- Provide actionable guidance
- Include relevant context
YAML Processing¶
Multi-Document Support:
- Handle files with multiple YAML documents
- Preserve document structure and formatting
- Atomic write operations
Key Selector Navigation:
- Support for nested field access
- Array indexing with
[n]syntax - Complex path resolution
Testing Strategy¶
Integration Tests:
- End-to-end testing with real configurations
- Guestbook example as test fixture
- Context immutability verification
Unit Tests:
- Individual ValueFrom evaluator testing
- Error condition coverage
- Edge case validation
Performance Considerations¶
Memory Efficiency¶
- Process files individually rather than loading entire project
- Lazy evaluation of ValueFrom expressions
- Efficient YAML parsing and modification
File I/O Optimization¶
- Batch file operations where possible
- Only write files when changes are actually made
- Atomic operations to prevent corruption
Extension Points¶
The architecture supports future extensions:
Custom ValueFrom Types¶
New value generation methods can be added by:
- Extending the
ValueFromunion type - Adding evaluator function
- Updating validation logic
Plugin System¶
Future plugin support could provide:
- Custom functions
- External value sources
- Integration with external systems
See Also¶
- Contributing - Development guidelines
- Testing - Testing approach
- Core Concepts - User-facing concepts