syncable_cli/analyzer/hadolint/rules/
dl3007.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 "DL3007",
14 Severity::Warning,
15 "Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag",
16 |instr, _shell| {
17 match instr {
18 Instruction::From(base) => {
19 match &base.tag {
21 Some(tag) => tag != "latest",
22 None => true, }
24 }
25 _ => true,
26 }
27 },
28 )
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34 use crate::analyzer::hadolint::parser::instruction::BaseImage;
35 use crate::analyzer::hadolint::rules::{Rule, RuleState};
36
37 #[test]
38 fn test_specific_tag() {
39 let rule = rule();
40 let mut state = RuleState::new();
41
42 let mut base = BaseImage::new("ubuntu");
43 base.tag = Some("20.04".to_string());
44 let instr = Instruction::From(base);
45
46 rule.check(&mut state, 1, &instr, None);
47 assert!(state.failures.is_empty());
48 }
49
50 #[test]
51 fn test_latest_tag() {
52 let rule = rule();
53 let mut state = RuleState::new();
54
55 let mut base = BaseImage::new("ubuntu");
56 base.tag = Some("latest".to_string());
57 let instr = Instruction::From(base);
58
59 rule.check(&mut state, 1, &instr, None);
60 assert_eq!(state.failures.len(), 1);
61 assert_eq!(state.failures[0].code.as_str(), "DL3007");
62 }
63
64 #[test]
65 fn test_no_tag() {
66 let rule = rule();
67 let mut state = RuleState::new();
68
69 let instr = Instruction::From(BaseImage::new("ubuntu"));
70 rule.check(&mut state, 1, &instr, None);
71 assert!(state.failures.is_empty());
73 }
74}