Expand description
§heroforge
A pure Rust client library for reading and writing Heroforge SCM repositories.
§Overview
heroforge provides a complete API for interacting with Heroforge repositories without
requiring the Heroforge CLI. It supports both reading from existing repositories and
creating new ones from scratch.
§Quick Start (Builder API)
use heroforge::Repository;
fn main() -> heroforge::Result<()> {
// Create a new repository
let repo = Repository::init("project.forge")?;
// Create initial commit using builder
let init = repo.commit()
.message("Initial commit")
.author("admin")
.initial()
.execute()?;
// Add files using builder
let v1 = repo.commit()
.message("Add project files")
.author("developer")
.parent(&init)
.file("README.md", b"# My Project\n")
.file("src/main.rs", b"fn main() {}\n")
.execute()?;
// Tag the release
repo.tags()
.create("v1.0.0")
.at_commit(&v1)
.author("developer")
.execute()?;
// Read files using builder
let readme = repo.files().on_trunk().read_string("README.md")?;
let rust_files = repo.files().at_tag("v1.0.0").find("**/*.rs")?;
// Sync to remote
repo.sync()
.to("quic://backup.example.com:4443/project")
.push()?;
Ok(())
}§Features
§File Operations
// List files on trunk
let files = repo.files().on_trunk().list()?;
// Read file from a branch
let content = repo.files().on_branch("feature").read("config.json")?;
// Find files at a tag
let rust = repo.files().at_tag("v1.0").find("**/*.rs")?;§Commit Operations
let hash = repo.commit()
.message("Add feature")
.author("developer")
.parent("abc123")
.file("src/feature.rs", b"// new feature")
.execute()?;§Branch/Tag Operations
// Create branch
repo.branches()
.create("feature-x")
.from_branch("trunk")
.author("developer")
.execute()?;
// Create tag
repo.tags()
.create("v1.0.0")
.at_branch("trunk")
.author("developer")
.execute()?;§Filesystem Operations (Copy, Move, Delete, Find, Symlinks)
// Copy, move, delete files and directories
repo.fs().modify()
.message("Reorganize project structure")
.author("developer")
.copy_file("README.md", "docs/README.md")
.copy_dir("src", "backup/src")
.move_file("old.txt", "archive/old.txt")
.move_dir("scripts", "tools")
.delete_file("temp.log")
.delete_dir("cache")
.execute()?;
// Find files with patterns and ignore rules
let rust_files = repo.fs().find()
.pattern("**/*.rs")
.ignore("target/**")
.ignore_hidden(true)
.paths()?;
// Change permissions
repo.fs().modify()
.message("Make scripts executable")
.author("developer")
.make_executable("scripts/deploy.sh")
.chmod_dir("bin", 0o755)
.execute()?;
// Create symlinks
repo.fs().modify()
.message("Add symlinks")
.author("developer")
.symlink("lib/latest", "lib/v2.0")
.execute()?;
// Utility operations (no commit needed)
let exists = repo.fs().exists("README.md")?;
let is_dir = repo.fs().is_dir("src")?;
let size = repo.fs().du("src")?;
let count = repo.fs().count("**/*.rs")?;§Sync Operations (QUIC)
// Push over QUIC
repo.sync()
.to("quic://server:4443/repo")
.push()?;
// Pull from remote
repo.sync()
.from("quic://server:4443/repo")
.auth("user", "password")
.pull()?;Re-exports§
pub use error::FossilError;pub use error::Result;pub use repo::CheckIn;pub use repo::FileInfo;pub use repo::Repository;pub use server::Server;pub use sync::SyncBuilder;pub use sync::SyncProtocol;pub use sync::SyncResult;pub use repo::BranchBuilder;pub use repo::BranchesBuilder;pub use repo::CommitBuilder;pub use repo::FileEntry;pub use repo::FileQuery;pub use repo::FileType;pub use repo::FilesBuilder;pub use repo::FindBuilder;pub use repo::FindResult;pub use repo::FsBuilder;pub use repo::FsOperation;pub use repo::FsOpsBuilder;pub use repo::FsPreview;pub use repo::HistoryBuilder;pub use repo::Permissions;pub use repo::TagBuilder;pub use repo::TagsBuilder;pub use repo::UserBuilder;pub use repo::UsersBuilder;