use heroforge_core::Repository;
use std::collections::HashSet;
use std::process::Command;
fn get_git_files(repo_path: &str) -> Result<HashSet<String>, Box<dyn std::error::Error>> {
let output = Command::new("find")
.args([repo_path, "-type", "f", "-not", "-path", "*/.git/*"])
.output()?;
let stdout = String::from_utf8_lossy(&output.stdout);
let base_path = format!("{}/", repo_path);
let files: HashSet<String> = stdout
.lines()
.map(|line| line.replace(&base_path, ""))
.collect();
Ok(files)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let git_url = "https://forge.ourworld.tf/geomind_research/herolib_rust.git";
let fossil_path = "/tmp/herolib.forge";
println!("=== Heroforge Git Import Test ===\n");
if std::path::Path::new(fossil_path).exists() {
std::fs::remove_file(fossil_path)?;
println!("Removed existing {}", fossil_path);
}
println!("Creating new heroforge repository at {}", fossil_path);
let repo = Repository::init(fossil_path)?;
println!("Importing from git: {}", git_url);
println!("This may take a moment...\n");
let commit_hash = repo
.git_import()
.url(git_url)
.branch("main")
.message("Import herolib_rust from git")
.author("developer")
.execute()?;
println!("Import complete!");
println!("Commit hash: {}\n", commit_hash);
let temp_git_dir = "/tmp/herolib_rust_compare";
if std::path::Path::new(temp_git_dir).exists() {
std::fs::remove_dir_all(temp_git_dir)?;
}
println!("Cloning git repo for comparison...");
let clone_output = Command::new("git")
.args([
"clone",
"--depth",
"1",
"--branch",
"main",
git_url,
temp_git_dir,
])
.output()?;
if !clone_output.status.success() {
eprintln!(
"Git clone failed: {}",
String::from_utf8_lossy(&clone_output.stderr)
);
return Ok(());
}
let git_files = get_git_files(temp_git_dir)?;
println!("Files in git repository (find): {}", git_files.len());
let forge_find_result = repo.fs().find().pattern("**/*").execute()?;
let forge_files: HashSet<String> = forge_find_result
.files
.iter()
.map(|f| f.path.clone())
.collect();
println!(
"Files in heroforge repository (find): {}",
forge_files.len()
);
println!("\n=== Comparison ===");
let in_git_not_forge: Vec<_> = git_files.difference(&forge_files).collect();
let in_forge_not_git: Vec<_> = forge_files.difference(&git_files).collect();
if in_git_not_forge.is_empty() && in_forge_not_git.is_empty() {
println!("✓ All files match! ({} files)", git_files.len());
} else {
if !in_git_not_forge.is_empty() {
println!(
"\n✗ Files in git but NOT in heroforge ({}):",
in_git_not_forge.len()
);
for f in in_git_not_forge.iter().take(10) {
println!(" - {}", f);
}
if in_git_not_forge.len() > 10 {
println!(" ... and {} more", in_git_not_forge.len() - 10);
}
}
if !in_forge_not_git.is_empty() {
println!(
"\n✗ Files in heroforge but NOT in git ({}):",
in_forge_not_git.len()
);
for f in in_forge_not_git.iter().take(10) {
println!(" - {}", f);
}
if in_forge_not_git.len() > 10 {
println!(" ... and {} more", in_forge_not_git.len() - 10);
}
}
}
std::fs::remove_dir_all(temp_git_dir)?;
println!("\n=== Pattern matching tests ===");
let rust_in_forge = repo.fs().find().pattern("**/*.rs").execute()?;
let rust_count_forge = rust_in_forge.files.len();
println!("Rust files (*.rs) in heroforge: {}", rust_count_forge);
let toml_in_forge = repo.fs().find().pattern("**/*.toml").execute()?;
let toml_count_forge = toml_in_forge.files.len();
println!("TOML files (*.toml) in heroforge: {}", toml_count_forge);
let md_in_forge = repo.fs().find().pattern("**/*.md").execute()?;
let md_count_forge = md_in_forge.files.len();
println!("Markdown files (*.md) in heroforge: {}", md_count_forge);
let packages_files = repo.fs().find().pattern("packages/**/*").execute()?;
println!("Files in packages/: {}", packages_files.files.len());
println!("\n=== Sample Rust files ===");
for file in rust_in_forge.files.iter().take(15) {
println!(" {}", file.path);
}
if rust_count_forge > 15 {
println!(" ... and {} more", rust_count_forge - 15);
}
println!("\n=== Test Complete ===");
println!("Repository saved at: {}", fossil_path);
Ok(())
}