swarm-controller: count default-branch merges and lines per repo
This commit is contained in:
parent
c25cf3d48a
commit
2e23f3debf
1 changed files with 576 additions and 6 deletions
|
|
@ -132,6 +132,28 @@ fn merge_base_of(commits: &[forgejo_api::structs::Commit]) -> Option<String> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Lines added and deleted, as [`Client::compare_line_stats`] sums them.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub struct LineStats {
|
||||
pub added: u64,
|
||||
pub deleted: u64,
|
||||
}
|
||||
|
||||
/// `commits`' per-commit stats summed; a negative or missing figure is zero.
|
||||
fn line_stats(commits: &[forgejo_api::structs::Commit]) -> LineStats {
|
||||
let sum = |pick: fn(&forgejo_api::structs::CommitStats) -> Option<i64>| -> u64 {
|
||||
commits
|
||||
.iter()
|
||||
.filter_map(|c| c.stats.as_ref().and_then(pick))
|
||||
.map(|n| u64::try_from(n).unwrap_or(0))
|
||||
.sum()
|
||||
};
|
||||
LineStats {
|
||||
added: sum(|s| s.additions),
|
||||
deleted: sum(|s| s.deletions),
|
||||
}
|
||||
}
|
||||
|
||||
/// `pulls` as the dropdown's rows, newest (highest number) first. A PR
|
||||
/// without a usable number cannot be named, so it is left out.
|
||||
fn open_pulls(pulls: Vec<forgejo_api::structs::PullRequest>) -> Vec<OpenPull> {
|
||||
|
|
@ -1179,6 +1201,28 @@ impl Client {
|
|||
Ok(open_pulls(pulls))
|
||||
}
|
||||
|
||||
/// Lines added and deleted by the commits `before..after` of
|
||||
/// `owner/repo`, summed over the per-commit stats the forge's compare
|
||||
/// returns. A commit the forge sent no stats for counts as zero.
|
||||
///
|
||||
/// The sum is over commits, not a net diff of the two endpoints: a line
|
||||
/// one commit adds and a later one removes counts once in each total.
|
||||
pub async fn compare_line_stats(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
before: &str,
|
||||
after: &str,
|
||||
) -> Result<LineStats> {
|
||||
let basehead = format!("{before}...{after}");
|
||||
let compare = self
|
||||
.api
|
||||
.call(|api| api.repo_compare_diff(owner, repo, &basehead).into_future())
|
||||
.await
|
||||
.with_context(|| format!("compare {basehead} in {owner}/{repo}"))?;
|
||||
Ok(line_stats(compare.commits.as_deref().unwrap_or_default()))
|
||||
}
|
||||
|
||||
/// Every open issue in `owner/repo`, each with its dependency-derived
|
||||
/// `blocked` / `depended_on_by_count` pre-resolved server-side — the
|
||||
/// whole job behind `GET /api/repos/{org}/{repo}/issue-report`. Doing
|
||||
|
|
@ -2228,6 +2272,25 @@ impl Client {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
/// Commit stats sum per side; a commit with none, or a negative figure,
|
||||
/// adds zero.
|
||||
#[test]
|
||||
fn compare_stats_sum_across_commits() {
|
||||
let commit = |stats: Option<(i64, i64)>| {
|
||||
serde_json::from_value::<forgejo_api::structs::Commit>(serde_json::json!({
|
||||
"stats": stats.map(|(a, d)| serde_json::json!({"additions": a, "deletions": d})),
|
||||
}))
|
||||
.expect("commit parses")
|
||||
};
|
||||
let got = line_stats(&[commit(Some((5, 2))), commit(None), commit(Some((-1, 4)))]);
|
||||
assert_eq!(
|
||||
got,
|
||||
LineStats {
|
||||
added: 5,
|
||||
deleted: 6
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// The event list each swarm hook is registered with, as Forgejo names
|
||||
/// the event types (`modules/webhook/type.go`).
|
||||
|
|
|
|||
Loading…
Reference in a new issue