# Development ## Setting Up Development Environment ### Prerequisites - Rust 1.70+ ([install here](https://rustup.rs/)) - Git 2.0+ - A terminal with 256-color support ### Clone and Build ```bash git clone https://github.com/Princelad/forge.git cd forge cargo build ``` ### Run During Development ```bash # Debug build (faster compilation) cargo run -- /path/to/repo # Release build (optimized) cargo run --release -- /path/to/repo # Run tests cargo test # Run benchmarks cargo bench # Check code quality cargo clippy cargo fmt --check ``` ## Code Quality Standards All code must follow these standards: ### Formatting - Use `cargo fmt` for consistent code style - Run before committing: `cargo fmt` ### Linting - Run `cargo clippy` and fix all warnings - No unsafe code without documentation - Meaningful variable names (no single letters except loop variables) ### Error Handling - Use `Result` for fallible operations - No `unwrap()` in production code (use `.ok()`, `.unwrap_or_default()`, or `.context()`) - Wrap errors with context using `color-eyre` ### Performance - Use `&str` instead of `String` when ownership not needed - Prefer iterators over collecting into vectors - Use `get()` instead of direct indexing for safety ### Testing - Write tests for new features - Test both happy paths and error cases - Use descriptive test names: `test_feature_with_condition()` ## Project Structure ``` src/ ├── main.rs # Entry point, app loop, page routing ├── lib.rs # Public exports ├── async_task.rs # Background task manager + async git ops ├── data.rs # Data models (Module, Developer, Project) ├── git.rs # Git operations wrapper (push/pull/fetch with progress) ├── key_handler.rs # Keyboard event handling ├── screen.rs # Base screen trait and Page enum ├── status_symbols.rs # UI status glyphs ├── ui_utils.rs # Shared UI helpers ├── state/ # Page state structs (Dashboard/Changes/Board/Merge/Modules/Branches/History) └── pages/ # Screen implementations ├── mod.rs ├── main_menu.rs ├── dashboard.rs ├── project_board.rs ├── changes.rs ├── commit_history.rs ├── branch_manager.rs ├── merge_visualizer.rs ├── module_manager.rs ├── settings.rs └── help.rs benches/ # Criterion benchmarks ├── git_operations.rs └── data_operations.rs ``` ## Adding a New Screen To add a new screen to Forge: ### 1. Create the Screen Module ```bash touch src/pages/my_feature.rs ``` ### 2. Implement the Screen Trait ```rust use crate::screen::Screen; pub struct MyFeatureScreen { // your state } impl Screen for MyFeatureScreen { fn handle_key(&mut self, key: KeyEvent) -> Result<()> { // Handle keyboard input Ok(()) } fn render(&self, f: &mut Frame) { // Render to terminal } fn on_enter(&mut self) -> Result<()> { // Initialize when screen becomes active Ok(()) } fn on_exit(&mut self) -> Result<()> { // Cleanup when screen is deactivated Ok(()) } } ``` ### 3. Register the Screen Add to `src/pages/mod.rs`: ```rust pub mod my_feature; pub use my_feature::MyFeatureScreen; ``` ### 4. Add to Main Menu Update `src/pages/main_menu.rs` to include navigation to your screen. ### 5. Add Tests ```bash touch tests/my_feature.rs ``` ## Testing Forge ships with **155 unit + integration tests** plus **11 Criterion benchmarks** covering Git, data persistence, async tasks, key handling, and page state logic. ### Commands ```bash cargo test cargo clippy -- -D warnings cargo bench ``` ### Coverage - Git integration, including remote fetch/pull/push with cancellation - Data models and JSON persistence stored under `.git/forge` - Async task manager and background channels - Key handler action mapping - Page states: Dashboard, Changes, Board, Merge, Module Manager, Branch Manager, Commit History - App wiring and screen routing in `main.rs` ### Benchmarks - Framework: [Criterion.rs](https://github.com/bheisler/criterion.rs) - Suites: `git_operations` (repo discovery, status, history, branches, staging) and `data_operations` (module/developer CRUD, progress, auto-population) - Reports: `target/criterion/report/index.html` ### Tips - Use `cargo test -- --nocapture` for verbose output - `cargo bench` compiles tests but marks them ignored during benchmark runs - Latest run (2026-01-28): `cargo test`, `cargo clippy -- -D warnings`, and `cargo bench` all completed. Benchmarks reported a mild regression on `stage_file` (~+1.4%) and an improvement on `unstage_file` (~-3.3%). - Data operations: nanosecond range For detailed benchmark results, see the [Performance wiki page](Performance.md). ## Git Workflow 1. **Create a feature branch:** ```bash git checkout -b feature/my-feature ``` 2. **Make changes** and test locally: ```bash cargo test cargo clippy cargo fmt ``` 3. **Commit with clear messages:** ```bash git commit -m "feat: add new feature" ``` 4. **Push and open PR:** ```bash git push origin feature/my-feature ``` 5. **PR review and merge** ## Commit Message Format Use conventional commits: - `feat:` — New feature - `fix:` — Bug fix - `docs:` — Documentation - `refactor:` — Code refactoring - `perf:` — Performance improvement - `test:` — Adding or updating tests - `chore:` — Maintenance tasks Example: ``` feat: add merge conflict visualization - Display local and incoming versions side-by-side - Add resolution tracking with visual indicators - Update keybindings in help overlay Closes #42 ``` ## Common Development Tasks ### View Git Status The `git.rs` module provides these utilities: ```rust use crate::git::GitRepository; let repo = GitRepository::open(path)?; let status = repo.get_status()?; ``` ### Read/Write Data The `data.rs` module handles persistence: ```rust use crate::data::{Module, Developer}; let modules = Module::load_from_file(".forge")?; modules.save_to_file(".forge")?; ``` ### Render Text Use ratatui widgets in `pages/*.rs`: ```rust let text = vec![Line::from("Hello")]; let paragraph = Paragraph::new(text); f.render_widget(paragraph, area); ``` ## Debugging ### Enable Debug Logging Set environment variable: ```bash RUST_LOG=debug cargo run ``` Repository discovery (~10ms) is the primary I/O bottleneck - Most Git operations (staging, branch listing) complete in microseconds - Data operations (module/developer management) are negligible (nanoseconds) - See the [Performance wiki page](Performance.md) for detailed benchmarks and optimization guidelines ### Performance Best Practices - Use `Vec::with_capacity()` when size is known upfront - Prefer iterators over collecting into vectors when possible - Cache Git operations that don't change frequently - Limit commit history to 50 commits (already implemented) - Generate diffs on-demand rather than preemptively ### Print Debug Output ```rust eprintln!("Debug: {:?}", value); ``` ### Common Issues | Issue | Solution | | -------------------------- | ------------------------------------------------------- | | Terminal rendering glitchy | Check terminal size (min 80×24), try different terminal | | Git operations slow | Check repo size, consider limiting diff context | | Keybindings not working | Check terminal compatibility, see help overlay | | Build fails | Update Rust: `rustup update`, then `cargo clean` | ## Performance Considerations - [Criterion.rs](https://github.com/bheisler/criterion.rs) — Benchmarking framework ## Getting Help - Check existing issues: [Issues](https://github.com/Princelad/forge/issues) - Ask on discussions or community channels - See the [FAQ](FAQ.md) for common questions - Review the [Architecture](Architecture.md) wiki for system design - Check the [Performance](Performance.md) wiki for optimization guidance --- ## See Also - **[Architecture](Architecture.md)** — System design and data flow - **[Performance](Performance.md)** — Benchmarks and optimization guidelines - **[Workflows](Workflows.md)** — User workflows and interaction patterns - **[Getting Started](Getting-Started.md)** — Installation and first run - **[CONTRIBUTING.md](../../CONTRIBUTING.md)** — Quick contributing guide - [ratatui Documentation](https://ratatui.rs) - [git2-rs API](https://docs.rs/git2/) - [Rust Book](https://doc.rust-lang.org/book/) - [Conventional Commits](https://www.conventionalcommits.org/) ## Getting Help - Check existing issues: [Issues](https://github.com/Princelad/forge/issues) - Ask on discussions or community channels - See the [FAQ](FAQ) for common questions