use anyhow::Result;
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::path::{Path, PathBuf};
use crate::config::ExcludeConfig;
pub struct CollectInput<'a> {
pub repo_path: &'a Path,
pub exclude_patterns: &'a [String],
pub max_files: usize,
}
pub struct SourceFile {
pub path: PathBuf,
pub content_hash: u64,
}
pub struct CollectOutput {
pub files: Vec<SourceFile>,
}
impl CollectOutput {
pub fn all_paths(&self) -> Vec<PathBuf> {
self.files.iter().map(|f| f.path.clone()).collect()
}
}
pub fn collect_stage(input: &CollectInput) -> Result<CollectOutput> {
let exclude = ExcludeConfig {
paths: input.exclude_patterns.to_vec(),
skip_defaults: false,
};
let mut files = crate::cli::analyze::files::collect_file_list(input.repo_path, &exclude)?;
if input.max_files > 0 && files.len() > input.max_files {
files.truncate(input.max_files);
}
let source_files: Vec<SourceFile> = files
.into_iter()
.map(|path| {
let content_hash = hash_file_content(&path);
SourceFile { path, content_hash }
})
.collect();
Ok(CollectOutput {
files: source_files,
})
}
fn hash_file_content(path: &Path) -> u64 {
match std::fs::read(path) {
Ok(content) => {
let mut hasher = DefaultHasher::new();
content.hash(&mut hasher);
hasher.finish()
}
Err(_) => 0,
}
}