diff options
| author | Laurenz <laurmaedje@gmail.com> | 2024-02-28 11:37:52 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-28 10:37:52 +0000 |
| commit | a518e2dd4d829b45b0887da28acb77d0568894ab (patch) | |
| tree | e7387b27e299383a0bd1a26ad58f485630cb23b7 /docs/src/contribs.rs | |
| parent | e16d3f5a67a31154797b4d56cdc6ed142ee2a7cf (diff) | |
Move docs generation code (#3519)
Diffstat (limited to 'docs/src/contribs.rs')
| -rw-r--r-- | docs/src/contribs.rs | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/docs/src/contribs.rs b/docs/src/contribs.rs new file mode 100644 index 00000000..58a730e2 --- /dev/null +++ b/docs/src/contribs.rs @@ -0,0 +1,86 @@ +use std::cmp::Reverse; +use std::collections::HashMap; +use std::fmt::Write; + +use serde::{Deserialize, Serialize}; + +use crate::{Html, Resolver}; + +/// Build HTML detailing the contributors between two tags. +pub fn contributors(resolver: &dyn Resolver, from: &str, to: &str) -> Option<Html> { + let staff = ["laurmaedje", "reknih"]; + + // Determine number of contributions per person. + let mut contributors = HashMap::<String, Contributor>::new(); + for commit in resolver.commits(from, to) { + contributors + .entry(commit.author.login.clone()) + .or_insert_with(|| Contributor { + login: commit.author.login, + avatar: commit.author.avatar_url, + contributions: 0, + }) + .contributions += 1; + } + + // Keep only non-staff people. + let mut contributors: Vec<_> = contributors + .into_values() + .filter(|c| !staff.contains(&c.login.as_str())) + .collect(); + + // Sort by highest number of commits. + contributors.sort_by_key(|c| (Reverse(c.contributions), c.login.clone())); + if contributors.is_empty() { + return None; + } + + let mut html = "Thanks to everyone who contributed to this release!".to_string(); + html += "<ul class=\"contribs\">"; + + for Contributor { login, avatar, contributions } in contributors { + let login = login.replace('\"', """).replace('&', "&"); + let avatar = avatar.replace("?v=", "?s=64&v="); + let s = if contributions > 1 { "s" } else { "" }; + write!( + html, + r#"<li> + <a href="https://github.com/{login}" target="_blank"> + <img + width="64" + height="64" + src="{avatar}" + alt="GitHub avatar of {login}" + title="@{login} made {contributions} contribution{s}" + crossorigin="anonymous" + > + </a> + </li>"# + ) + .unwrap(); + } + + html += "</ul>"; + + Some(Html::new(html)) +} + +#[derive(Debug)] +struct Contributor { + login: String, + avatar: String, + contributions: usize, +} + +/// A commit on the `typst` repository. +#[derive(Debug, Serialize, Deserialize)] +pub struct Commit { + author: Author, +} + +/// A commit author. +#[derive(Debug, Serialize, Deserialize)] +pub struct Author { + login: String, + avatar_url: String, +} |
