Skip to content

Development

Prince Lad edited this page Jan 27, 2026 · 4 revisions

Development

Setting Up Development Environment

Prerequisites

  • Rust 1.70+ (install here)
  • Git 2.0+
  • A terminal with 256-color support

Clone and Build

git clone https://github.com/Princelad/forge.git
cd forge
cargo build

Run During Development

# 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<T, E> 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

touch src/pages/my_feature.rs

2. Implement the Screen Trait

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:

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

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

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
  • 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.

Git Workflow

  1. Create a feature branch:

    git checkout -b feature/my-feature
  2. Make changes and test locally:

    cargo test
    cargo clippy
    cargo fmt
  3. Commit with clear messages:

    git commit -m "feat: add new feature"
  4. Push and open PR:

    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:

use crate::git::GitRepository;

let repo = GitRepository::open(path)?;
let status = repo.get_status()?;

Read/Write Data

The data.rs module handles persistence:

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:

let text = vec![Line::from("Hello")];
let paragraph = Paragraph::new(text);
f.render_widget(paragraph, area);

Debugging

Enable Debug Logging

Set environment variable:

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 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

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

Getting Help

  • Check existing issues: Issues
  • Ask on discussions or community channels
  • See the FAQ for common questions
  • Review the Architecture wiki for system design
  • Check the Performance wiki for optimization guidance

See Also

Getting Help

  • Check existing issues: Issues
  • Ask on discussions or community channels
  • See the FAQ for common questions

Clone this wiki locally