mirror of
https://github.com/encounter/decomp.dev.git
synced 2026-07-10 03:18:48 -07:00
Improve GitHub PR comment formatting
This commit is contained in:
+126
-35
@@ -1,4 +1,4 @@
|
||||
use std::{cmp::Ordering, fmt::Display};
|
||||
use std::{cmp::Ordering, fmt::Display, mem::take};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use axum::{
|
||||
@@ -469,6 +469,46 @@ fn process_new_items(items: &[ReportItem]) -> Vec<ChangeItem> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn measure_line_matched(
|
||||
name: &str,
|
||||
from: u64,
|
||||
from_percent: f32,
|
||||
to: u64,
|
||||
to_percent: f32,
|
||||
) -> String {
|
||||
let emoji = if to > from { "📈" } else { "📉" };
|
||||
let percent_diff = to_percent - from_percent;
|
||||
let percent_str = if percent_diff < 0.0 {
|
||||
format!("{percent_diff:.2}%")
|
||||
} else {
|
||||
format!("+{percent_diff:.2}%")
|
||||
};
|
||||
let bytes_diff = to as i64 - from as i64;
|
||||
let bytes_str = match bytes_diff.cmp(&0) {
|
||||
Ordering::Less => bytes_diff.to_string(),
|
||||
Ordering::Equal | Ordering::Greater => format!("+{bytes_diff}"),
|
||||
};
|
||||
format!("{emoji} **{name}**: {to_percent:.2}% ({percent_str}, {bytes_str} bytes)\n")
|
||||
}
|
||||
|
||||
fn measure_line_bytes(name: &str, from: u64, to: u64) -> String {
|
||||
let diff = to as i64 - from as i64;
|
||||
let diff_str = match diff.cmp(&0) {
|
||||
Ordering::Less => diff.to_string(),
|
||||
Ordering::Equal | Ordering::Greater => format!("+{diff}"),
|
||||
};
|
||||
format!("**{name}**: {to} bytes ({diff_str} bytes)\n")
|
||||
}
|
||||
|
||||
fn measure_line_simple(name: &str, from: u64, to: u64) -> String {
|
||||
let diff = to as i64 - from as i64;
|
||||
let diff_str = match diff.cmp(&0) {
|
||||
Ordering::Less => diff.to_string(),
|
||||
Ordering::Equal | Ordering::Greater => format!("+{diff}"),
|
||||
};
|
||||
format!("**{name}**: {to} ({diff_str})\n")
|
||||
}
|
||||
|
||||
fn generate_comment(
|
||||
from: &FullReportFile,
|
||||
to: &ProcessArtifactResult,
|
||||
@@ -476,46 +516,97 @@ fn generate_comment(
|
||||
changes: Changes,
|
||||
) -> String {
|
||||
let mut comment = format!(
|
||||
"## Report for {} ({} - {})\n\n",
|
||||
"### Report for {} ({} - {})\n\n",
|
||||
to.version,
|
||||
&from.commit.sha[..7],
|
||||
&to_commit.sha[..7]
|
||||
);
|
||||
comment.push_str("### Changes\n");
|
||||
for unit in changes.units {
|
||||
for function in unit.functions {
|
||||
let (from, to) = match (function.from, function.to) {
|
||||
(Some(from), Some(to)) => (from, to),
|
||||
(None, Some(to)) => (ChangeItemInfo::default(), to),
|
||||
(Some(from), None) => (from, ChangeItemInfo::default()),
|
||||
(None, None) => continue,
|
||||
};
|
||||
let emoji = if to.fuzzy_match_percent == 100.0 {
|
||||
"✅"
|
||||
} else if to.fuzzy_match_percent > from.fuzzy_match_percent {
|
||||
"📈"
|
||||
} else {
|
||||
"📉"
|
||||
};
|
||||
let from_bytes = ((from.fuzzy_match_percent as f64 / 100.0) * from.size as f64) as u64;
|
||||
let to_bytes = ((to.fuzzy_match_percent as f64 / 100.0) * to.size as f64) as u64;
|
||||
let bytes_diff = to_bytes as i64 - from_bytes as i64;
|
||||
let bytes_str = match bytes_diff.cmp(&0) {
|
||||
Ordering::Less => bytes_diff.to_string(),
|
||||
Ordering::Equal => "0".to_string(),
|
||||
Ordering::Greater => format!("+{}", bytes_diff),
|
||||
};
|
||||
let name = function
|
||||
.metadata
|
||||
.as_ref()
|
||||
.and_then(|m| m.demangled_name.as_deref())
|
||||
.unwrap_or(&function.name);
|
||||
comment.push_str(&format!(
|
||||
"- {} `{} | {}` {} bytes -> {:.2}%\n",
|
||||
emoji, unit.name, name, bytes_str, to.fuzzy_match_percent
|
||||
));
|
||||
let mut measure_written = false;
|
||||
let from_measures = from.report.measures;
|
||||
let to_measures = to.report.measures.unwrap_or_default();
|
||||
if from_measures.total_code != to_measures.total_code {
|
||||
comment.push_str(&measure_line_bytes(
|
||||
"Total code",
|
||||
from_measures.total_code,
|
||||
to_measures.total_code,
|
||||
));
|
||||
measure_written = true;
|
||||
}
|
||||
if from_measures.total_functions != to_measures.total_functions {
|
||||
comment.push_str(&measure_line_simple(
|
||||
"Total functions",
|
||||
from_measures.total_functions as u64,
|
||||
to_measures.total_functions as u64,
|
||||
));
|
||||
measure_written = true;
|
||||
}
|
||||
if from_measures.matched_code != to_measures.matched_code {
|
||||
comment.push_str(&measure_line_matched(
|
||||
"Matched code",
|
||||
from_measures.matched_code,
|
||||
from_measures.matched_code_percent,
|
||||
to_measures.matched_code,
|
||||
to_measures.matched_code_percent,
|
||||
));
|
||||
measure_written = true;
|
||||
}
|
||||
if from_measures.complete_code != to_measures.complete_code {
|
||||
comment.push_str(&measure_line_matched(
|
||||
"Linked code",
|
||||
from_measures.complete_code,
|
||||
from_measures.complete_code_percent,
|
||||
to_measures.complete_code,
|
||||
to_measures.complete_code_percent,
|
||||
));
|
||||
measure_written = true;
|
||||
}
|
||||
if measure_written {
|
||||
comment.push('\n');
|
||||
}
|
||||
let mut total_changes = 0;
|
||||
let mut iter = changes.units.into_iter().flat_map(|mut unit| {
|
||||
let functions = take(&mut unit.functions);
|
||||
functions.into_iter().map(move |f| (unit.clone(), f))
|
||||
});
|
||||
for (unit, item) in iter.by_ref() {
|
||||
let (from, to) = match (item.from, item.to) {
|
||||
(Some(from), Some(to)) => (from, to),
|
||||
(None, Some(to)) => (ChangeItemInfo::default(), to),
|
||||
(Some(from), None) => (from, ChangeItemInfo::default()),
|
||||
(None, None) => continue,
|
||||
};
|
||||
let emoji = if to.fuzzy_match_percent == 100.0 {
|
||||
"✅"
|
||||
} else if to.fuzzy_match_percent > from.fuzzy_match_percent {
|
||||
"📈"
|
||||
} else {
|
||||
"📉"
|
||||
};
|
||||
let from_bytes = ((from.fuzzy_match_percent as f64 / 100.0) * from.size as f64) as u64;
|
||||
let to_bytes = ((to.fuzzy_match_percent as f64 / 100.0) * to.size as f64) as u64;
|
||||
let bytes_diff = to_bytes as i64 - from_bytes as i64;
|
||||
let bytes_str = match bytes_diff.cmp(&0) {
|
||||
Ordering::Less => bytes_diff.to_string(),
|
||||
Ordering::Equal => "0".to_string(),
|
||||
Ordering::Greater => format!("+{}", bytes_diff),
|
||||
};
|
||||
let name =
|
||||
item.metadata.as_ref().and_then(|m| m.demangled_name.as_deref()).unwrap_or(&item.name);
|
||||
comment.push_str(&format!(
|
||||
"{emoji} `{} | {}` {} bytes -> {:.2}%\n",
|
||||
unit.name, name, bytes_str, to.fuzzy_match_percent
|
||||
));
|
||||
total_changes += 1;
|
||||
if total_changes >= 30 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let remaining = iter.count();
|
||||
if remaining > 0 {
|
||||
comment.push_str(&format!("...and {} more items\n", remaining));
|
||||
} else if total_changes == 0 {
|
||||
comment.push_str("No changes\n");
|
||||
}
|
||||
comment
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user