syncable_cli/analyzer/hadolint/rules/
dl3003.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 "DL3003",
14 Severity::Warning,
15 "Use WORKDIR to switch to a directory",
16 |instr, shell| {
17 match instr {
18 Instruction::Run(_) => {
19 if let Some(shell) = shell {
20 !shell.any_command(|cmd| cmd.name == "cd")
22 } else {
23 true
24 }
25 }
26 _ => true,
27 }
28 },
29 )
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35 use crate::analyzer::hadolint::parser::instruction::RunArgs;
36 use crate::analyzer::hadolint::rules::{Rule, RuleState};
37
38 #[test]
39 fn test_no_cd() {
40 let rule = rule();
41 let mut state = RuleState::new();
42
43 let instr = Instruction::Run(RunArgs::shell("apt-get update"));
44 let shell = ParsedShell::parse("apt-get update");
45 rule.check(&mut state, 1, &instr, Some(&shell));
46 assert!(state.failures.is_empty());
47 }
48
49 #[test]
50 fn test_with_cd() {
51 let rule = rule();
52 let mut state = RuleState::new();
53
54 let instr = Instruction::Run(RunArgs::shell("cd /app && npm install"));
55 let shell = ParsedShell::parse("cd /app && npm install");
56 rule.check(&mut state, 1, &instr, Some(&shell));
57 assert_eq!(state.failures.len(), 1);
58 assert_eq!(state.failures[0].code.as_str(), "DL3003");
59 }
60}