dev_deps/producer.rs
1//! [`Producer`] integration: wrap a [`DepCheck`] and emit a [`Report`]
2//! every time the producer runs.
3//!
4//! [`Producer`]: dev_report::Producer
5//! [`Report`]: dev_report::Report
6
7use dev_report::{CheckResult, Producer, Report, Severity};
8
9use crate::DepCheck;
10
11/// `Producer` adapter that runs a [`DepCheck`] and converts the result
12/// into a `Report`.
13///
14/// Subprocess failures map to a single failing `CheckResult` named
15/// `deps::health` with `Severity::Critical` — no panics.
16///
17/// # Example
18///
19/// ```no_run
20/// use dev_deps::{DepCheck, DepProducer, DepScope};
21/// use dev_report::Producer;
22///
23/// let producer = DepProducer::new(
24/// DepCheck::new("my-crate", "0.1.0").scope(DepScope::All),
25/// );
26/// let report = producer.produce();
27/// println!("{}", report.to_json().unwrap());
28/// ```
29pub struct DepProducer {
30 check: DepCheck,
31}
32
33impl DepProducer {
34 /// Build a producer that drives the given [`DepCheck`].
35 pub fn new(check: DepCheck) -> Self {
36 Self { check }
37 }
38}
39
40impl Producer for DepProducer {
41 fn produce(&self) -> Report {
42 match self.check.execute() {
43 Ok(result) => result.into_report(),
44 Err(e) => {
45 let mut report = Report::new(self.check.subject(), self.check.subject_version())
46 .with_producer("dev-deps");
47 let check = CheckResult::fail("deps::health", Severity::Critical)
48 .with_detail(e.to_string())
49 .with_tag("deps")
50 .with_tag("subprocess");
51 report.push(check);
52 report.finish();
53 report
54 }
55 }
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use crate::DepScope;
63
64 #[test]
65 fn produce_returns_report_when_tool_missing() {
66 // Default runner image won't have cargo-udeps + cargo-outdated
67 // installed; the producer should surface that as a failing
68 // CheckResult rather than panicking.
69 let producer = DepProducer::new(DepCheck::new("self", "0.0.0").scope(DepScope::Unused));
70 let report = producer.produce();
71 assert_eq!(report.subject, "self");
72 assert!(!report.checks.is_empty());
73 }
74}