use crate::linter::{Diagnostic, LintResult, Severity, Span};
pub fn check(source: &str) -> LintResult {
let mut result = LintResult::new();
let mut current_run = String::new();
let mut run_start_line = 0;
for (line_num, line) in source.lines().enumerate() {
let trimmed = line.trim();
if trimmed.starts_with("RUN ") {
run_start_line = line_num + 1;
current_run = trimmed.to_string();
} else if !current_run.is_empty() {
if current_run.ends_with('\\') {
current_run.push(' ');
current_run.push_str(trimmed);
} else {
check_run_command(¤t_run, run_start_line, &mut result);
current_run.clear();
}
}
if trimmed.starts_with("RUN ") && !trimmed.ends_with('\\') {
check_run_command(trimmed, line_num + 1, &mut result);
current_run.clear();
}
}
if !current_run.is_empty() {
check_run_command(¤t_run, run_start_line, &mut result);
}
result
}
fn check_run_command(run_cmd: &str, line_num: usize, result: &mut LintResult) {
if run_cmd.contains("apt-get install") {
let has_cleanup = run_cmd.contains("rm -rf /var/lib/apt");
if !has_cleanup {
let span = Span::new(line_num, 1, line_num, run_cmd.len().min(80));
let diag = Diagnostic::new(
"DOCKER003",
Severity::Warning,
"apt-get install without cleanup - add 'rm -rf /var/lib/apt/lists/*' to reduce image size".to_string(),
span,
);
result.add(diag);
}
}
}