qlty_coverage/publish/
planner.rs1use crate::git::retrieve_commit_metadata;
2use crate::publish::Plan;
3use crate::publish::Settings;
4use crate::transformer::AddPrefix;
5use crate::transformer::AppendMetadata;
6use crate::transformer::ComputeSummary;
7use crate::transformer::IgnorePaths;
8use crate::transformer::StripDotSlashPrefix;
9use crate::transformer::StripPrefix;
10use crate::utils::extract_path_and_format;
11use crate::Transformer;
12use anyhow::Result;
13use pbjson_types::Timestamp;
14use qlty_config::QltyConfig;
15use qlty_types::tests::v1::CoverageMetadata;
16use qlty_types::tests::v1::ReportFile;
17use std::vec;
18use time::OffsetDateTime;
19
20#[derive(Debug, Clone)]
21pub struct Planner {
22 config: QltyConfig,
23 settings: Settings,
24}
25
26impl Planner {
27 pub fn new(config: &QltyConfig, settings: &Settings) -> Self {
28 Self {
29 config: config.clone(),
30 settings: settings.clone(),
31 }
32 }
33
34 pub fn compute(&self) -> Result<Plan> {
35 let metadata = self.compute_metadata()?;
36
37 Ok(Plan {
38 metadata: metadata.clone(),
39 report_files: self.compute_report_files()?,
40 transformers: self.compute_transformers(&metadata)?,
41 })
42 }
43
44 fn compute_metadata(&self) -> Result<CoverageMetadata> {
45 let now = OffsetDateTime::now_utc();
46
47 let mut metadata = if let Some(ci) = crate::ci::current() {
48 ci.metadata()
49 } else {
50 let mut metadata = CoverageMetadata::default();
51 metadata.ci = "unknown".to_string();
52 metadata
53 };
54
55 metadata.uploaded_at = Some(Timestamp {
56 seconds: now.unix_timestamp() as i64,
57 nanos: now.nanosecond() as i32,
58 });
59 metadata.tag = self.settings.tag.clone();
60
61 if let Some(build_id) = self.settings.override_build_id.clone() {
63 metadata.build_id = build_id;
64 }
65
66 if let Some(commit_sha) = self.settings.override_commit_sha.clone() {
67 metadata.commit_sha = commit_sha;
68 }
69
70 if let Some(branch) = self.settings.override_branch.clone() {
71 metadata.branch = branch;
72 }
73
74 if let Some(pull_request_number) = self.settings.override_pull_request_number.clone() {
75 metadata.pull_request_number = pull_request_number;
76 }
77
78 let commit_metadata = retrieve_commit_metadata()?;
79 metadata.commit_message = commit_metadata.commit_message;
80 metadata.committer_email = commit_metadata.committer_email;
81 metadata.committer_name = commit_metadata.committer_name;
82 metadata.author_email = commit_metadata.author_email;
83 metadata.author_name = commit_metadata.author_name;
84 metadata.author_time = Some(Timestamp {
85 seconds: commit_metadata.author_time.seconds(),
86 nanos: 0,
87 });
88
89 metadata.commit_time = Some(Timestamp {
90 seconds: commit_metadata.commit_time.seconds(),
91 nanos: 0,
92 });
93
94 Ok(metadata)
95 }
96
97 fn compute_report_files(&self) -> Result<Vec<ReportFile>> {
98 let paths = if self.settings.paths.is_empty() {
99 self.config.coverage.paths.clone().unwrap_or_default()
100 } else {
101 self.settings.paths.clone()
102 };
103
104 let mut report_files: Vec<ReportFile> = vec![];
105
106 for path in paths {
107 let (path, format) =
108 extract_path_and_format(&path, self.settings.report_format.clone())?;
109
110 report_files.push(ReportFile {
111 path: path.to_string_lossy().into_owned(),
112 format: format.to_string(),
113 ..Default::default()
114 })
115 }
116
117 Ok(report_files)
118 }
119
120 fn compute_transformers(
121 &self,
122 metadata: &CoverageMetadata,
123 ) -> Result<Vec<Box<dyn Transformer>>> {
124 let mut transformers: Vec<Box<dyn Transformer>> = vec![];
125
126 transformers.push(Box::new(ComputeSummary::new()));
127
128 if let Some(prefix) = self.settings.strip_prefix.clone() {
129 transformers.push(Box::new(StripPrefix::new(prefix)));
130 } else {
131 transformers.push(Box::new(StripPrefix::default()));
132 }
133
134 transformers.push(Box::new(StripDotSlashPrefix));
135
136 if self.config.coverage.ignores.is_some() {
137 transformers.push(Box::new(IgnorePaths::new(
138 &self.config.coverage.ignores.as_ref().unwrap(),
139 )?));
140 }
141
142 if let Some(prefix) = self.settings.add_prefix.clone() {
143 transformers.push(Box::new(AddPrefix::new(&prefix)));
144 }
145
146 transformers.push(Box::new(AppendMetadata::new(metadata)));
147 Ok(transformers)
148 }
149}