syncable_cli/analyzer/hadolint/rules/
dl3050.rs

1//! DL3050: Superfluous label present
2//!
3//! Some labels are redundant or should use OCI annotation keys.
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        "DL3050",
13        Severity::Info,
14        "Superfluous label present.",
15        |instr, _shell| {
16            match instr {
17                Instruction::Label(pairs) => {
18                    // Check for deprecated/superfluous labels that should use OCI keys
19                    let deprecated_labels = [
20                        "description",
21                        "version",
22                        "build-date",
23                        "vcs-url",
24                        "vcs-ref",
25                        "vendor",
26                        "name",
27                        "url",
28                        "documentation",
29                        "source",
30                        "licenses",
31                        "title",
32                        "revision",
33                        "created",
34                    ];
35
36                    !pairs.iter().any(|(key, _)| {
37                        let key_lower = key.to_lowercase();
38                        deprecated_labels.contains(&key_lower.as_str())
39                    })
40                }
41                _ => true,
42            }
43        },
44    )
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50    use crate::analyzer::hadolint::lint::{lint, LintResult};
51    use crate::analyzer::hadolint::config::HadolintConfig;
52
53    fn lint_dockerfile(content: &str) -> LintResult {
54        lint(content, &HadolintConfig::default())
55    }
56
57    #[test]
58    fn test_deprecated_description() {
59        let result = lint_dockerfile("FROM ubuntu:20.04\nLABEL description=\"Test image\"");
60        assert!(result.failures.iter().any(|f| f.code.as_str() == "DL3050"));
61    }
62
63    #[test]
64    fn test_oci_description() {
65        let result = lint_dockerfile("FROM ubuntu:20.04\nLABEL org.opencontainers.image.description=\"Test image\"");
66        assert!(!result.failures.iter().any(|f| f.code.as_str() == "DL3050"));
67    }
68}