1use crate::report::{CheckReport, FailOnPolicy};
4
5pub const EXIT_CLEAN: i32 = 0;
7pub const EXIT_POLICY_VIOLATION: i32 = 1;
9pub const EXIT_EXECUTION_ERROR: i32 = 2;
12
13#[must_use]
37pub fn exit_code(report: &CheckReport, policy: &FailOnPolicy, had_execution_error: bool) -> i32 {
38 if policy.matches(&report.findings) {
39 return EXIT_POLICY_VIOLATION;
40 }
41 if had_execution_error {
42 return EXIT_EXECUTION_ERROR;
43 }
44 EXIT_CLEAN
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50 use crate::report::{Category, CheckFinding};
51 use deps_core::EcosystemId;
52 use deps_core::diagnostic::Severity;
53 use deps_core::position::Range;
54 use std::path::PathBuf;
55
56 fn finding(category: Category) -> CheckFinding {
57 CheckFinding {
58 ecosystem: EcosystemId::Cargo,
59 manifest_path: PathBuf::from("Cargo.toml"),
60 dependency_name: Some("serde".to_string()),
61 requirement: None,
62 category,
63 code: None,
64 advisory_url: None,
65 advisory_severity: None,
66 severity: Severity::Warning,
67 range: Range::default(),
68 message: "test".to_string(),
69 }
70 }
71
72 #[test]
73 fn test_exit_code_clean_report_is_zero() {
74 let report = CheckReport::default();
75 let policy = FailOnPolicy::default_categories();
76 assert_eq!(exit_code(&report, &policy, false), EXIT_CLEAN);
77 }
78
79 #[test]
80 fn test_exit_code_policy_violation_is_one() {
81 let report = CheckReport {
82 findings: vec![finding(Category::Vulnerable)],
83 };
84 let policy = FailOnPolicy::default_categories();
85 assert_eq!(exit_code(&report, &policy, false), EXIT_POLICY_VIOLATION);
86 }
87
88 #[test]
89 fn test_exit_code_non_failing_category_is_zero() {
90 let report = CheckReport {
91 findings: vec![finding(Category::Outdated)],
92 };
93 let policy = FailOnPolicy::default_categories();
94 assert_eq!(exit_code(&report, &policy, false), EXIT_CLEAN);
95 }
96
97 #[test]
98 fn test_exit_code_execution_error_is_two() {
99 let report = CheckReport::default();
100 let policy = FailOnPolicy::default_categories();
101 assert_eq!(exit_code(&report, &policy, true), EXIT_EXECUTION_ERROR);
102 }
103
104 #[test]
105 fn test_exit_code_execution_error_takes_precedence_over_clean_policy() {
106 let report = CheckReport {
107 findings: vec![finding(Category::Outdated)],
108 };
109 let policy = FailOnPolicy::default_categories();
110 assert_eq!(exit_code(&report, &policy, true), EXIT_EXECUTION_ERROR);
111 }
112
113 #[test]
116 fn test_exit_code_policy_violation_takes_precedence_over_execution_error() {
117 let report = CheckReport {
118 findings: vec![finding(Category::Vulnerable)],
119 };
120 let policy = FailOnPolicy::default_categories();
121 assert_eq!(exit_code(&report, &policy, true), EXIT_POLICY_VIOLATION);
122 }
123}