pub mod downloader;
pub mod pointer;
use crate::auth::SecureString;
use anyhow::Result;
use pointer::{is_lfs_pointer, parse_pointer};
use std::path::Path;
use tracing::{debug, info, warn};
use walkdir::WalkDir;
pub async fn resolve_lfs_pointers(
repo_path: &Path,
repo_url: &str,
token: Option<&SecureString>,
_verify_hashes: bool,
) -> Result<usize> {
let dl = downloader::LfsDownloader::new();
let mut resolved = 0;
for entry in WalkDir::new(repo_path)
.follow_links(false)
.into_iter()
.filter_map(|e| e.ok())
{
let path = entry.path();
if !path.is_file() {
continue;
}
if path.components().any(|c| c.as_os_str() == ".git") {
continue;
}
if let Ok(content) = std::fs::read(path) {
if is_lfs_pointer(&content) {
match parse_pointer(&content) {
Ok(pointer) => {
info!(
"Resolving LFS pointer: {} ({} bytes)",
path.display(),
pointer.size
);
match dl.download_object(repo_url, &pointer, path, token).await {
Ok(()) => {
resolved += 1;
debug!("Resolved LFS object: {}", path.display());
}
Err(e) => {
warn!("Failed to resolve LFS pointer {}: {}", path.display(), e);
}
}
}
Err(e) => {
warn!("Invalid LFS pointer {}: {}", path.display(), e);
}
}
}
}
}
Ok(resolved)
}