heroforge-core 0.2.2

Pure Rust core library for reading and writing Fossil SCM repositories
Documentation
# Heroforge

A pure Rust library for version-controlled storage with a filesystem-like API.

## Quick Start

```rust
use heroforge::Repository;

// Create a new repository
let repo = Repository::init("project.forge")?;

// Initial commit
let hash = repo.commit()
    .message("Initial commit")
    .author("developer")
    .initial()
    .execute()?;

// Add files
repo.commit()
    .message("Add project files")
    .author("developer")
    .parent(&hash)
    .file("README.md", b"# My Project")
    .file("src/main.rs", b"fn main() {}")
    .execute()?;

// Read files
let content = repo.files().on_trunk().read_string("README.md")?;
```

## Two Ways to Work with Files

### 1. Repository API (Immediate Commits)

Each operation creates a commit immediately:

```rust
let repo = Repository::open_rw("project.forge")?;

// Single commit with multiple files
repo.commit()
    .message("Update files")
    .author("developer")
    .parent(&last_hash)
    .file("config.json", b"{}")
    .file("data.txt", b"hello")
    .execute()?;

// Filesystem operations (copy, move, delete)
repo.fs().modify()
    .message("Reorganize")
    .author("developer")
    .copy_file("README.md", "docs/README.md")
    .delete_file("old.txt")
    .execute()?;
```

### 2. FsInterface (Staging with Background Commits)

Writes go to a staging directory first, then auto-commit every minute:

```rust
use heroforge::{Repository, FsInterface};
use std::sync::Arc;

let repo = Arc::new(Repository::open_rw("project.forge")?);
let fs = FsInterface::new(repo, "developer")?;

// Fast writes to staging
fs.write_file("config.json", b"{}")?;
fs.write_file("data.txt", b"hello")?;

// Reads check staging first, then database
let content = fs.read_file("config.json")?;

// Partial updates (efficient for large files)
fs.write_at("data.bin", 100, b"updated")?;

// Force immediate commit (or wait for auto-commit)
fs.commit()?;
```

**When to use which:**
- **Repository API**: Explicit control, each operation is a commit
- **FsInterface**: High-frequency writes, automatic batching, filesystem-like usage

## Common Operations

### Branches

```rust
// List
let branches = repo.branches().list()?;

// Create
repo.branches()
    .create("feature")
    .from_branch("trunk")
    .author("developer")
    .execute()?;

// Get latest commit
let tip = repo.branches().get("feature")?.tip()?;
```

### Tags

```rust
// Create at branch tip
repo.tags()
    .create("v1.0.0")
    .at_branch("trunk")
    .author("developer")
    .execute()?;

// Create at specific commit
repo.tags()
    .create("v1.0.1")
    .at_commit(&hash)
    .author("developer")
    .execute()?;

// List
let tags = repo.tags().list()?;
```

### Reading Files

```rust
// From trunk
let bytes = repo.files().on_trunk().read("file.bin")?;
let text = repo.files().on_trunk().read_string("file.txt")?;

// From branch or tag
let content = repo.files().on_branch("feature").read("src/lib.rs")?;
let content = repo.files().at_tag("v1.0.0").read("Cargo.toml")?;

// List and find
let files = repo.files().on_trunk().list()?;
let rust_files = repo.files().on_trunk().find("**/*.rs")?;
```

### Filesystem Operations

```rust
use heroforge::fs::{Find, Modify};

// Find files with patterns
let rust_files = Find::new(&repo)
    .pattern("**/*.rs")
    .ignore("target/**")
    .ignore_hidden()
    .max_depth(5)
    .paths()?;

// Convenience functions
use heroforge::fs::{find, count, exists, is_dir, stat, du};
let files = find(&repo, "**/*.rs")?;
let num = count(&repo, "**/*.md")?;
let has_readme = exists(&repo, "README.md")?;
let total_size = du(&repo, "src/**/*")?;

// Batch operations (single commit)
Modify::new(&repo)
    .message("Cleanup")
    .author("developer")
    .copy_file("a.txt", "backup/a.txt")
    .move_file("old.txt", "archive/old.txt")
    .delete_dir("temp")
    .make_executable("scripts/run.sh")
    .symlink("latest", "releases/v1.0.0")
    .execute()?;
```

### Upload/Download (OS Filesystem <-> Repository)

```rust
use heroforge::fs::{upload, upload_dir, download, download_dir, download_matching};

// Upload file from OS to repository
upload(&repo, "/path/to/local/file.txt", "file.txt", "developer", None)?;

// Upload entire directory
upload_dir(&repo, "/path/to/local/src", "src", "developer", Some("Import source"))?;

// Download file from repository to OS
download(&repo, "config.json", "/tmp/config.json")?;

// Download entire directory
let count = download_dir(&repo, "src", "/tmp/src_export")?;

// Download matching files
let count = download_matching(&repo, "**/*.rs", "/tmp/rust_files")?;
```

### History

```rust
// Recent commits
let commits = repo.history().limit(10).list()?;

for commit in commits {
    println!("{} - {}", commit.hash, commit.comment);
}

// Get specific commit
let commit = repo.history().get(&hash)?;
```

### Sync (Push/Pull)

```rust
// Push to remote
repo.sync()
    .to("quic://server:4443/repo")
    .push()?;

// Pull from remote
repo.sync()
    .from("quic://server:4443/repo")
    .auth("user", "password")
    .pull()?;
```

## Error Handling

All operations return `Result<T, FossilError>`:

```rust
use heroforge::{Repository, FossilError};

match repo.files().on_trunk().read("missing.txt") {
    Ok(content) => println!("Got {} bytes", content.len()),
    Err(FossilError::ArtifactNotFound(_)) => println!("File not found"),
    Err(e) => println!("Error: {}", e),
}
```

## Features

Enable optional features in `Cargo.toml`:

```toml
[dependencies]
heroforge = { version = "0.2", features = ["git-import"] }
```

### git-import

Import from Git repositories:

```rust
repo.git_import()
    .url("https://github.com/user/project.git")
    .branch("main")
    .message("Import from git")
    .author("developer")
    .execute()?;
```

## Module Overview

| Module | Purpose |
|--------|---------|
| `repo` | Repository operations, commits, branches, tags |
| `fs` | Filesystem interface with staging |
| `sync` | Push/pull over QUIC protocol |
| `artifact` | Low-level blob and manifest handling |
| `tools` | Import utilities (git-import) |