use crate::check::{Outcome, Severity};
use crate::finding::Finding;
use super::common;
const MB: u64 = 1024 * 1024;
pub const NAME: &str = "large-files";
pub fn thresholds() -> (u64, u64) {
let warn = crate::config::integer_or("amont.largeFileWarn", 10, 1..=1_000_000) as u64;
let block = crate::config::integer_or("amont.largeFileBlock", 100, 1..=1_000_000) as u64;
(warn * MB, block * MB)
}
pub fn scan(file: &str, len: u64) -> Option<Finding> {
let (warn_bytes, block_bytes) = thresholds();
let mb = len / MB;
if len >= block_bytes {
Some(Finding::new(
NAME,
crate::ui::sanitize(file),
Severity::Block,
format!(
"{mb} MB — over the {} MB limit (GitHub refuses these at push). \
Use git-lfs, or keep it out of history: deletion later does \
not remove the bytes",
block_bytes / MB
),
))
} else if len >= warn_bytes {
Some(Finding::new(
NAME,
crate::ui::sanitize(file),
Severity::Warn,
format!(
"{mb} MB — every future clone pays for this forever \
(git config amont.largeFileWarn to tune)"
),
))
} else {
None
}
}
pub fn staged() -> Outcome {
let root = common::repo_root();
let mut blocked = false;
let mut warned = false;
for f in common::staged_files(&[]) {
let path = std::path::Path::new(&root).join(&f);
let Ok(meta) = std::fs::metadata(&path) else {
continue; };
if !meta.is_file() {
continue;
}
let Some(finding) = scan(&f, meta.len()) else {
continue;
};
let line = format!("large-files: {} is {}", finding.file, finding.message);
match finding.severity {
Severity::Block => {
blocked = true;
common::fail(&line);
}
Severity::Warn => {
warned = true;
common::warn(&line);
}
}
}
if blocked {
return Outcome::Failed;
}
if warned {
return Outcome::Warned;
}
common::ok("No oversized files staged");
Outcome::Passed
}