syncable_cli/analyzer/hadolint/rules/
dl3015.rs1use crate::analyzer::hadolint::parser::instruction::Instruction;
7use crate::analyzer::hadolint::rules::{SimpleRule, simple_rule};
8use crate::analyzer::hadolint::shell::ParsedShell;
9use crate::analyzer::hadolint::types::Severity;
10
11pub fn rule() -> SimpleRule<impl Fn(&Instruction, Option<&ParsedShell>) -> bool + Send + Sync> {
12 simple_rule(
13 "DL3015",
14 Severity::Info,
15 "Avoid additional packages by specifying `--no-install-recommends`.",
16 |instr, shell| {
17 match instr {
18 Instruction::Run(_) => {
19 if let Some(shell) = shell {
20 !shell.any_command(|cmd| {
22 if cmd.name == "apt-get" && cmd.has_any_arg(&["install"]) {
23 !cmd.has_any_flag(&["no-install-recommends"])
25 } else {
26 false
27 }
28 })
29 } else {
30 true
31 }
32 }
33 _ => true,
34 }
35 },
36 )
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42 use crate::analyzer::hadolint::config::HadolintConfig;
43 use crate::analyzer::hadolint::lint::{LintResult, lint};
44
45 fn lint_dockerfile(content: &str) -> LintResult {
46 lint(content, &HadolintConfig::default())
47 }
48
49 #[test]
50 fn test_apt_get_without_no_install_recommends() {
51 let result = lint_dockerfile("FROM ubuntu:20.04\nRUN apt-get install -y nginx");
52 assert!(result.failures.iter().any(|f| f.code.as_str() == "DL3015"));
53 }
54
55 #[test]
56 fn test_apt_get_with_no_install_recommends() {
57 let result = lint_dockerfile(
58 "FROM ubuntu:20.04\nRUN apt-get install -y --no-install-recommends nginx",
59 );
60 assert!(!result.failures.iter().any(|f| f.code.as_str() == "DL3015"));
61 }
62
63 #[test]
64 fn test_apt_get_update_no_flag_needed() {
65 let result = lint_dockerfile("FROM ubuntu:20.04\nRUN apt-get update");
66 assert!(!result.failures.iter().any(|f| f.code.as_str() == "DL3015"));
67 }
68}