syncable_cli/analyzer/hadolint/rules/
dl3043.rs

1//! DL3043: ONBUILD ONBUILD is not allowed
2//!
3//! Nested ONBUILD instructions are not allowed.
4
5use crate::analyzer::hadolint::parser::instruction::Instruction;
6use crate::analyzer::hadolint::rules::{simple_rule, SimpleRule};
7use crate::analyzer::hadolint::shell::ParsedShell;
8use crate::analyzer::hadolint::types::Severity;
9
10pub fn rule() -> SimpleRule<impl Fn(&Instruction, Option<&ParsedShell>) -> bool + Send + Sync> {
11    simple_rule(
12        "DL3043",
13        Severity::Error,
14        "`ONBUILD` combined with `ONBUILD` is not allowed.",
15        |instr, _shell| {
16            match instr {
17                Instruction::OnBuild(inner) => {
18                    !matches!(inner.as_ref(), Instruction::OnBuild(_))
19                }
20                _ => true,
21            }
22        },
23    )
24}
25
26#[cfg(test)]
27mod tests {
28    use super::*;
29    use crate::analyzer::hadolint::rules::{Rule, RuleState};
30    use crate::analyzer::hadolint::parser::instruction::{Arguments, RunArgs, RunFlags};
31
32    #[test]
33    fn test_nested_onbuild() {
34        let rule = rule();
35        let mut state = RuleState::new();
36
37        // ONBUILD ONBUILD RUN echo hello
38        let inner_run = Instruction::Run(RunArgs {
39            arguments: Arguments::Text("echo hello".to_string()),
40            flags: RunFlags::default(),
41        });
42        let inner_onbuild = Instruction::OnBuild(Box::new(inner_run));
43        let instr = Instruction::OnBuild(Box::new(inner_onbuild));
44
45        rule.check(&mut state, 1, &instr, None);
46        assert_eq!(state.failures.len(), 1);
47        assert_eq!(state.failures[0].code.as_str(), "DL3043");
48    }
49
50    #[test]
51    fn test_valid_onbuild() {
52        let rule = rule();
53        let mut state = RuleState::new();
54
55        // ONBUILD RUN echo hello
56        let inner = Instruction::Run(RunArgs {
57            arguments: Arguments::Text("echo hello".to_string()),
58            flags: RunFlags::default(),
59        });
60        let instr = Instruction::OnBuild(Box::new(inner));
61
62        rule.check(&mut state, 1, &instr, None);
63        assert!(state.failures.is_empty());
64    }
65}