syncable_cli/analyzer/hadolint/rules/
dl4004.rs1use crate::analyzer::hadolint::parser::instruction::Instruction;
7use crate::analyzer::hadolint::rules::{CustomRule, RuleState, custom_rule};
8use crate::analyzer::hadolint::shell::ParsedShell;
9use crate::analyzer::hadolint::types::Severity;
10
11pub fn rule()
12-> CustomRule<impl Fn(&mut RuleState, u32, &Instruction, Option<&ParsedShell>) + Send + Sync> {
13 custom_rule(
14 "DL4004",
15 Severity::Error,
16 "Multiple `ENTRYPOINT` instructions found. If you list more than one `ENTRYPOINT` then only the last `ENTRYPOINT` will take effect",
17 |state, line, instr, _shell| {
18 match instr {
19 Instruction::From(_) => {
20 state.data.set_int("entrypoint_count", 0);
22 }
23 Instruction::Entrypoint(_) => {
24 let count = state.data.get_int("entrypoint_count") + 1;
25 state.data.set_int("entrypoint_count", count);
26
27 if count > 1 {
28 state.add_failure(
29 "DL4004",
30 Severity::Error,
31 "Multiple `ENTRYPOINT` instructions found. If you list more than one `ENTRYPOINT` then only the last `ENTRYPOINT` will take effect",
32 line,
33 );
34 }
35 }
36 _ => {}
37 }
38 },
39 )
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use crate::analyzer::hadolint::parser::instruction::{Arguments, BaseImage};
46 use crate::analyzer::hadolint::rules::Rule;
47
48 #[test]
49 fn test_single_entrypoint() {
50 let rule = rule();
51 let mut state = RuleState::new();
52
53 let from = Instruction::From(BaseImage::new("ubuntu"));
54 let ep = Instruction::Entrypoint(Arguments::List(vec!["./entrypoint.sh".to_string()]));
55
56 rule.check(&mut state, 1, &from, None);
57 rule.check(&mut state, 2, &ep, None);
58 assert!(state.failures.is_empty());
59 }
60
61 #[test]
62 fn test_multiple_entrypoints() {
63 let rule = rule();
64 let mut state = RuleState::new();
65
66 let from = Instruction::From(BaseImage::new("ubuntu"));
67 let ep1 = Instruction::Entrypoint(Arguments::List(vec!["./script1.sh".to_string()]));
68 let ep2 = Instruction::Entrypoint(Arguments::List(vec!["./script2.sh".to_string()]));
69
70 rule.check(&mut state, 1, &from, None);
71 rule.check(&mut state, 2, &ep1, None);
72 rule.check(&mut state, 3, &ep2, None);
73 assert_eq!(state.failures.len(), 1);
74 assert_eq!(state.failures[0].code.as_str(), "DL4004");
75 }
76}