Skip to content

Commit 15cba34

Browse files
committed
display tree and results in report for selected comparisons
1 parent 1267474 commit 15cba34

File tree

6 files changed

+329
-66
lines changed

6 files changed

+329
-66
lines changed

assets/report.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ div.category div.header.header-background {
149149
background: #292929;
150150
}
151151

152+
153+
div.category div.subheader.header {
154+
margin: 10px;
155+
top: 2em;
156+
}
157+
152158
div.category div.crate {
153159
display: flex;
154160
padding: 0.8em;

src/report/analyzer.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
use super::{Comparison, CrateResult, RawTestResults};
2+
use crate::crates::Crate;
3+
use crate::results::{
4+
FailureReason,
5+
TestResult::{self, BuildFail},
6+
};
7+
use std::collections::BTreeSet;
8+
use std::collections::HashMap;
9+
10+
#[derive(PartialEq)]
11+
pub enum ReportConfig {
12+
Simple,
13+
Complete { toolchain: usize },
14+
}
15+
16+
#[derive(Clone)]
17+
pub enum ReportCrates {
18+
Plain(Vec<CrateResult>),
19+
Complete {
20+
tree: HashMap<Crate, Vec<CrateResult>>,
21+
results: HashMap<TestResult, Vec<CrateResult>>,
22+
},
23+
}
24+
25+
pub struct TestResults {
26+
pub categories: HashMap<Comparison, ReportCrates>,
27+
pub info: HashMap<Comparison, u32>,
28+
}
29+
30+
fn analyze_detailed(toolchain: usize, crates: Vec<CrateResult>) -> ReportCrates {
31+
let mut tree = HashMap::new();
32+
let mut results = HashMap::new();
33+
34+
let mut root = Vec::new();
35+
for krate in crates {
36+
if let BuildFail(FailureReason::DependsOn(ref deps)) =
37+
(&krate.runs[toolchain]).as_ref().unwrap().res
38+
{
39+
for dep in deps {
40+
tree.entry(dep.clone())
41+
.or_insert_with(Vec::new)
42+
.push(krate.clone())
43+
}
44+
} else {
45+
root.push(krate);
46+
}
47+
}
48+
49+
for krate in root {
50+
// record results only for root crates
51+
if let BuildFail(FailureReason::CompilerError(codes)) =
52+
krate.runs[toolchain].clone().unwrap().res
53+
{
54+
for code in codes {
55+
results
56+
.entry(BuildFail(FailureReason::CompilerError(btreeset![code])))
57+
.or_insert_with(Vec::new)
58+
.push(krate.clone())
59+
}
60+
} else {
61+
results
62+
.entry(krate.runs[toolchain].as_ref().unwrap().res.clone())
63+
.or_insert_with(Vec::new)
64+
.push(krate)
65+
}
66+
}
67+
68+
ReportCrates::Complete { tree, results }
69+
}
70+
71+
pub fn analyze_report(test: RawTestResults) -> TestResults {
72+
let mut comparison = HashMap::new();
73+
for krate in test.crates {
74+
comparison
75+
.entry(krate.res)
76+
.or_insert_with(Vec::new)
77+
.push(krate);
78+
}
79+
80+
let info = comparison
81+
.iter()
82+
.map(|(&key, vec)| (key, vec.len() as u32))
83+
.collect::<HashMap<_, _>>();
84+
85+
let mut categories = HashMap::new();
86+
for (cat, crates) in comparison {
87+
if let ReportConfig::Complete { toolchain } = cat.report_config() {
88+
categories.insert(cat, analyze_detailed(toolchain, crates));
89+
} else {
90+
categories.insert(cat, ReportCrates::Plain(crates));
91+
}
92+
}
93+
94+
TestResults { categories, info }
95+
}

src/report/html.rs

Lines changed: 101 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ use crate::assets;
22
use crate::experiments::Experiment;
33
use crate::prelude::*;
44
use crate::report::{
5-
archives::Archive, Color, Comparison, ReportWriter, ResultColor, ResultName, TestResults,
5+
analyzer::ReportCrates, archives::Archive, Color, Comparison, CrateResult, ReportWriter,
6+
ResultColor, ResultName, TestResults,
67
};
7-
use crate::results::EncodingType;
8+
use crate::results::{EncodingType, FailureReason, TestResult};
89
use std::collections::HashMap;
910

1011
#[derive(Serialize)]
@@ -21,6 +22,19 @@ enum CurrentPage {
2122
Downloads,
2223
}
2324

25+
#[derive(Serialize)]
26+
enum ReportCratesHTML {
27+
Plain(Vec<CrateResultHTML>),
28+
Tree {
29+
count: u32,
30+
tree: HashMap<String, Vec<CrateResultHTML>>,
31+
},
32+
RootResults {
33+
count: u32,
34+
results: HashMap<String, Vec<CrateResultHTML>>,
35+
},
36+
}
37+
2438
impl CurrentPage {
2539
fn navbar(&self) -> Vec<NavbarItem> {
2640
vec![
@@ -47,7 +61,8 @@ impl CurrentPage {
4761
struct ResultsContext<'a> {
4862
ex: &'a Experiment,
4963
nav: Vec<NavbarItem>,
50-
categories: HashMap<Comparison, Vec<CrateResultHTML>>,
64+
categories: Vec<(Comparison, ReportCratesHTML)>,
65+
info: HashMap<Comparison, u32>,
5166
full: bool,
5267
crates_count: usize,
5368

@@ -93,43 +108,103 @@ fn write_report<W: ReportWriter>(
93108
let mut result_colors = Vec::new();
94109
let mut result_names = Vec::new();
95110

96-
let mut categories = HashMap::new();
97-
for result in &res.crates {
98-
// Skip some categories if this is not the full report
99-
if !full && !result.res.show_in_summary() {
100-
continue;
101-
}
102-
103-
// Add the colors and names used in this run
104-
comparison_colors
105-
.entry(result.res)
106-
.or_insert_with(|| result.res.color());
107-
111+
let mut to_html_crate_result = |result: CrateResult| {
108112
let mut runs = [None, None];
109113

110114
for (pos, run) in result.runs.iter().enumerate() {
111115
if let Some(ref run) = run {
112-
let idx = test_results_to_int.entry(&run.res).or_insert_with(|| {
113-
result_colors.push(run.res.color());
114-
result_names.push(run.res.name());
115-
result_names.len() - 1
116-
});
116+
let idx = test_results_to_int
117+
.entry(run.res.clone())
118+
.or_insert_with(|| {
119+
result_colors.push(run.res.color());
120+
result_names.push(run.res.name());
121+
result_names.len() - 1
122+
});
117123
runs[pos] = Some(BuildTestResultHTML {
118124
res: *idx as usize,
119125
log: run.log.clone(),
120126
});
121127
}
122128
}
123129

124-
let category = categories.entry(result.res).or_insert_with(Vec::new);
125-
let result = CrateResultHTML {
130+
CrateResultHTML {
126131
name: result.name.clone(),
127132
url: result.url.clone(),
128133
res: result.res,
129134
runs,
130-
};
131-
category.push(result);
132-
}
135+
}
136+
};
137+
138+
let categories = res
139+
.categories
140+
.iter()
141+
.filter(|(category, _)| full || category.show_in_summary())
142+
.map(|(&category, crates)| (category, crates.to_owned()))
143+
.flat_map(|(category, crates)| {
144+
comparison_colors.insert(category, category.color());
145+
146+
match crates {
147+
ReportCrates::Plain(crates) => vec![(
148+
category,
149+
ReportCratesHTML::Plain(
150+
crates
151+
.into_iter()
152+
.map(|result| to_html_crate_result(result))
153+
.collect::<Vec<_>>(),
154+
),
155+
)]
156+
.into_iter(),
157+
ReportCrates::Complete { tree, results } => {
158+
let tree = tree
159+
.into_iter()
160+
.map(|(root, deps)| {
161+
(
162+
root.to_string(),
163+
deps.into_iter()
164+
.map(|result| to_html_crate_result(result))
165+
.collect::<Vec<_>>(),
166+
)
167+
})
168+
.collect::<HashMap<_, _>>();
169+
let results = results
170+
.into_iter()
171+
.map(|(res, krates)| {
172+
(
173+
if let TestResult::BuildFail(FailureReason::CompilerError(_)) = res
174+
{
175+
res.to_string()
176+
} else {
177+
res.name()
178+
},
179+
krates
180+
.into_iter()
181+
.map(|result| to_html_crate_result(result))
182+
.collect::<Vec<_>>(),
183+
)
184+
})
185+
.collect::<HashMap<_, _>>();
186+
187+
vec![
188+
(
189+
category,
190+
ReportCratesHTML::Tree {
191+
count: tree.keys().len() as u32,
192+
tree,
193+
},
194+
),
195+
(
196+
category,
197+
ReportCratesHTML::RootResults {
198+
count: results.keys().len() as u32,
199+
results,
200+
},
201+
),
202+
]
203+
.into_iter()
204+
}
205+
}
206+
})
207+
.collect();
133208

134209
let context = ResultsContext {
135210
ex,
@@ -140,6 +215,7 @@ fn write_report<W: ReportWriter>(
140215
}
141216
.navbar(),
142217
categories,
218+
info: res.info.clone(),
143219
full,
144220
crates_count,
145221
comparison_colors,

0 commit comments

Comments
 (0)