Some checks failed
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Security Audit (push) Has been cancelled
CI/CD Pipeline / Build Docker Image (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Performance Benchmarks (push) Has been cancelled
CI/CD Pipeline / Cleanup (push) Has been cancelled
351 lines
9.5 KiB
Markdown
351 lines
9.5 KiB
Markdown
# Rustelo Layered Override System
|
|
|
|
## 🎯 Architecture Overview
|
|
|
|
The layered override system enables customization at multiple levels while maintaining framework integrity and update safety. This system follows a clear precedence hierarchy:
|
|
|
|
**Precedence Order**: `Local > Feature > Template > Framework`
|
|
|
|
## 🏗️ Layer Definitions
|
|
|
|
### 1. Framework Layer (Bottom - Never Modified)
|
|
- **Location**: Framework crates in dependencies
|
|
- **Content**: Core rustelo functionality
|
|
- **Modification**: ❌ Never modified directly
|
|
- **Updates**: Automatic via `cargo rustelo update`
|
|
|
|
### 2. Template Layer (Foundation)
|
|
- **Location**: Project templates from `/rustelo/templates/`
|
|
- **Content**: Default project structure and configurations
|
|
- **Modification**: ❌ Not modified directly in projects
|
|
- **Updates**: Synced via `cargo rustelo sync templates`
|
|
|
|
### 3. Feature Layer (Additive)
|
|
- **Location**: Feature-specific additions from `/rustelo/features/*/templates/`
|
|
- **Content**: Feature configurations, dependencies, tooling
|
|
- **Modification**: ✅ Can be overridden by local layer
|
|
- **Updates**: Managed via `cargo rustelo add/remove <feature>`
|
|
|
|
### 4. Local Layer (Top - Full Control)
|
|
- **Location**: Project-specific files and customizations
|
|
- **Content**: Local customizations, overrides, project-specific code
|
|
- **Modification**: ✅ Full control by developers
|
|
- **Updates**: Always preserved during framework updates
|
|
|
|
## 🔧 Override Resolution Process
|
|
|
|
### Configuration Files (Cargo.toml, justfile, package.json)
|
|
|
|
```
|
|
Resolution Order:
|
|
1. Check for local override: `config/local/Cargo.toml`
|
|
2. Check for feature configs: `config/features/*/Cargo.toml`
|
|
3. Check template default: `config/templates/Cargo.toml`
|
|
4. Fall back to framework defaults
|
|
```
|
|
|
|
**Merge Strategy**: Hierarchical merge with higher layers taking precedence
|
|
|
|
### Component Overrides (Pages, Components)
|
|
|
|
```
|
|
Resolution Order:
|
|
1. Local components: `src/components/local/`
|
|
2. Feature components: `src/components/features/*/`
|
|
3. Template components: `src/components/templates/`
|
|
4. Framework components: Framework crates
|
|
```
|
|
|
|
**Selection Strategy**: First found wins (no merging for components)
|
|
|
|
### Route Definitions
|
|
|
|
```
|
|
Resolution Order:
|
|
1. Local routes: `config/routes/local/`
|
|
2. Feature routes: `config/routes/features/*/`
|
|
3. Template routes: `config/routes/templates/`
|
|
4. Framework routes: Generated defaults
|
|
```
|
|
|
|
**Merge Strategy**: Route sets are merged with local routes overriding conflicts
|
|
|
|
### Styling (CSS, UnoCSS)
|
|
|
|
```
|
|
Resolution Order:
|
|
1. Local styles: `styles/local/`
|
|
2. Feature styles: `styles/features/*/`
|
|
3. Template styles: `styles/templates/`
|
|
4. Framework styles: Default framework styles
|
|
```
|
|
|
|
**Merge Strategy**: CSS cascade with local styles having highest specificity
|
|
|
|
## 📁 Directory Structure
|
|
|
|
```
|
|
my-rustelo-project/
|
|
├── config/
|
|
│ ├── local/ # Local overrides (highest precedence)
|
|
│ │ ├── Cargo.toml
|
|
│ │ ├── justfile
|
|
│ │ └── app.toml
|
|
│ ├── features/ # Feature-specific configs
|
|
│ │ ├── analytics/
|
|
│ │ ├── smart-build/
|
|
│ │ └── debugging-tools/
|
|
│ └── templates/ # Template defaults (lowest precedence)
|
|
├── src/
|
|
│ ├── components/
|
|
│ │ ├── local/ # Local component overrides
|
|
│ │ ├── features/ # Feature components
|
|
│ │ └── templates/ # Template components
|
|
│ └── pages/
|
|
│ ├── local/ # Local page overrides
|
|
│ ├── features/ # Feature pages
|
|
│ └── templates/ # Template pages
|
|
├── routes/
|
|
│ ├── local/ # Local route definitions
|
|
│ ├── features/ # Feature routes
|
|
│ └── templates/ # Template routes
|
|
├── styles/
|
|
│ ├── local/ # Local styling
|
|
│ ├── features/ # Feature styles
|
|
│ └── templates/ # Template styles
|
|
└── scripts/
|
|
├── local/ # Local scripts
|
|
├── features/ # Feature scripts
|
|
└── templates/ # Template scripts
|
|
```
|
|
|
|
## ⚙️ Implementation
|
|
|
|
### Configuration Resolution Engine
|
|
|
|
```rust
|
|
pub struct LayeredConfig {
|
|
layers: Vec<ConfigLayer>,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum ConfigLayer {
|
|
Local(PathBuf),
|
|
Feature(String, PathBuf),
|
|
Template(PathBuf),
|
|
Framework,
|
|
}
|
|
|
|
impl LayeredConfig {
|
|
pub fn resolve<T>(&self, config_name: &str) -> Result<T, ConfigError>
|
|
where
|
|
T: DeserializeOwned + Merge
|
|
{
|
|
let mut result = T::default();
|
|
|
|
// Apply layers from lowest to highest precedence
|
|
for layer in &self.layers {
|
|
if let Some(config) = self.load_config_from_layer(layer, config_name)? {
|
|
result.merge(config);
|
|
}
|
|
}
|
|
|
|
Ok(result)
|
|
}
|
|
}
|
|
```
|
|
|
|
### Component Resolution Engine
|
|
|
|
```rust
|
|
pub struct LayeredComponents {
|
|
component_dirs: Vec<ComponentDir>,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum ComponentDir {
|
|
Local(PathBuf),
|
|
Feature(String, PathBuf),
|
|
Template(PathBuf),
|
|
Framework,
|
|
}
|
|
|
|
impl LayeredComponents {
|
|
pub fn find_component(&self, name: &str) -> Option<PathBuf> {
|
|
// Search from highest to lowest precedence
|
|
for dir in &self.component_dirs {
|
|
if let Some(path) = self.search_component_in_dir(dir, name) {
|
|
return Some(path);
|
|
}
|
|
}
|
|
None
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🚀 CLI Integration
|
|
|
|
### Automatic Layer Setup
|
|
|
|
```bash
|
|
# Create layered structure when adding features
|
|
cargo rustelo add analytics
|
|
# Creates: config/features/analytics/, src/components/features/analytics/, etc.
|
|
|
|
# Create local override
|
|
cargo rustelo override component Header
|
|
# Creates: src/components/local/Header.rs (overrides template/feature version)
|
|
|
|
# Create local config override
|
|
cargo rustelo override config Cargo.toml
|
|
# Creates: config/local/Cargo.toml (merges with other layers)
|
|
```
|
|
|
|
### Override Management
|
|
|
|
```bash
|
|
# List all overrides
|
|
cargo rustelo list-overrides
|
|
|
|
# Show override hierarchy for specific item
|
|
cargo rustelo trace component Header
|
|
# Output:
|
|
# Header component resolution:
|
|
# ✅ src/components/local/Header.rs (USED)
|
|
# 🔸 src/components/features/analytics/Header.rs
|
|
# 🔸 src/components/templates/Header.rs
|
|
|
|
# Remove local override (fall back to next layer)
|
|
cargo rustelo remove-override component Header
|
|
```
|
|
|
|
## 🛡️ Update Safety
|
|
|
|
### Framework Updates
|
|
When running `cargo rustelo update`:
|
|
|
|
1. **Framework crates** are updated to latest versions
|
|
2. **Template defaults** are refreshed (but not applied)
|
|
3. **Feature configs** are updated if compatible
|
|
4. **Local overrides** are never modified
|
|
5. **Conflict detection** warns of incompatibilities
|
|
|
|
### Feature Updates
|
|
When running `cargo rustelo add/remove <feature>`:
|
|
|
|
1. **Feature layer** is added/removed
|
|
2. **Local overrides** take precedence over new feature configs
|
|
3. **Dependency conflicts** are resolved in favor of local choices
|
|
4. **Migration warnings** provided for breaking changes
|
|
|
|
## 🎨 Configuration Merging Examples
|
|
|
|
### Cargo.toml Merging
|
|
|
|
**Template Layer**:
|
|
```toml
|
|
[dependencies]
|
|
leptos = "0.6"
|
|
serde = "1.0"
|
|
```
|
|
|
|
**Feature Layer (analytics)**:
|
|
```toml
|
|
[dependencies]
|
|
prometheus = "0.13"
|
|
chrono = "0.4"
|
|
```
|
|
|
|
**Local Layer**:
|
|
```toml
|
|
[dependencies]
|
|
leptos = "0.7" # Override template version
|
|
anyhow = "1.0" # Add local dependency
|
|
```
|
|
|
|
**Final Result**:
|
|
```toml
|
|
[dependencies]
|
|
leptos = "0.7" # Local override
|
|
serde = "1.0" # From template
|
|
prometheus = "0.13" # From analytics feature
|
|
chrono = "0.4" # From analytics feature
|
|
anyhow = "1.0" # Local addition
|
|
```
|
|
|
|
### UnoCSS Configuration Merging
|
|
|
|
**Template Layer**:
|
|
```typescript
|
|
export default {
|
|
theme: {
|
|
colors: {
|
|
primary: '#3b82f6',
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Feature Layer (analytics)**:
|
|
```typescript
|
|
export default {
|
|
theme: {
|
|
colors: {
|
|
analytics: '#10b981',
|
|
}
|
|
},
|
|
shortcuts: {
|
|
'metric-card': 'bg-white shadow-md rounded-lg p-4',
|
|
}
|
|
}
|
|
```
|
|
|
|
**Local Layer**:
|
|
```typescript
|
|
export default {
|
|
theme: {
|
|
colors: {
|
|
primary: '#ef4444', // Override template primary
|
|
brand: '#8b5cf6', // Add local color
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Final Result**:
|
|
```typescript
|
|
export default {
|
|
theme: {
|
|
colors: {
|
|
primary: '#ef4444', // Local override
|
|
analytics: '#10b981', // From analytics feature
|
|
brand: '#8b5cf6', // Local addition
|
|
}
|
|
},
|
|
shortcuts: {
|
|
'metric-card': 'bg-white shadow-md rounded-lg p-4', // From analytics
|
|
}
|
|
}
|
|
```
|
|
|
|
## 📋 Benefits
|
|
|
|
### For Developers
|
|
- **Full customization** without losing update capability
|
|
- **Clear precedence** - always know which config wins
|
|
- **Safe experimentation** - local changes never affect framework
|
|
- **Easy rollback** - remove local override to revert to defaults
|
|
|
|
### for Framework Maintainers
|
|
- **Update safety** - never break user customizations
|
|
- **Feature composability** - features don't conflict with each other
|
|
- **Clear boundaries** - framework, template, feature, and local concerns separated
|
|
- **Debugging support** - trace resolution path for any configuration
|
|
|
|
### For Teams
|
|
- **Consistent structure** - all projects follow same layered approach
|
|
- **Shared overrides** - commit local layer for team-wide customizations
|
|
- **Feature experimentation** - test features without permanent changes
|
|
- **Migration safety** - gradual migration between framework versions
|
|
|
|
This layered override system ensures that Rustelo provides maximum flexibility while maintaining the reliability and update safety that production applications require. |