From 1be278e60cca7433225bd2502afbd6e1200fb976 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 18 Sep 2024 00:21:56 +0200 Subject: Save `CHANGELOG.md` after each review in `changelog` tool --- examples/changelog/src/changelog.rs | 69 ++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 20 deletions(-) (limited to 'examples/changelog/src/changelog.rs') diff --git a/examples/changelog/src/changelog.rs b/examples/changelog/src/changelog.rs index 39cbb42c..9421f91c 100644 --- a/examples/changelog/src/changelog.rs +++ b/examples/changelog/src/changelog.rs @@ -29,7 +29,7 @@ impl Changelog { } } - pub async fn list() -> Result<(Self, Vec), Error> { + pub async fn list() -> Result<(Self, Vec), Error> { let mut changelog = Self::new(); { @@ -97,7 +97,7 @@ impl Changelog { } } - let mut candidates = Candidate::list().await?; + let mut candidates = Contribution::list().await?; for reviewed_entry in changelog.entries() { candidates.retain(|candidate| candidate.id != reviewed_entry); @@ -106,6 +106,30 @@ impl Changelog { Ok((changelog, candidates)) } + pub async fn save(self) -> Result<(), Error> { + let markdown = fs::read_to_string("CHANGELOG.md").await?; + + let Some((header, rest)) = markdown.split_once("\n## ") else { + return Err(Error::InvalidFormat); + }; + + let Some((_unreleased, rest)) = rest.split_once("\n## ") else { + return Err(Error::InvalidFormat); + }; + + let unreleased = format!( + "\n## [Unreleased]\n{changelog}", + changelog = self.to_string() + ); + + let rest = format!("\n## {rest}"); + + let changelog = [header, &unreleased, &rest].concat(); + fs::write("CHANGELOG.md", changelog).await?; + + Ok(()) + } + pub fn len(&self) -> usize { self.ids.len() } @@ -132,7 +156,7 @@ impl Changelog { target.push(item); - if !self.authors.contains(&entry.author) { + if entry.author != "hecrj" && !self.authors.contains(&entry.author) { self.authors.push(entry.author); self.authors.sort_by_key(|author| author.to_lowercase()); } @@ -238,21 +262,12 @@ impl fmt::Display for Category { } #[derive(Debug, Clone)] -pub struct Candidate { +pub struct Contribution { pub id: u64, } -#[derive(Debug, Clone)] -pub struct PullRequest { - pub id: u64, - pub title: String, - pub description: String, - pub labels: Vec, - pub author: String, -} - -impl Candidate { - pub async fn list() -> Result, Error> { +impl Contribution { + pub async fn list() -> Result, Error> { let output = process::Command::new("git") .args([ "log", @@ -273,20 +288,31 @@ impl Candidate { let (_, pull_request) = title.split_once("#")?; let (pull_request, _) = pull_request.split_once([')', ' '])?; - Some(Candidate { + Some(Contribution { id: pull_request.parse().ok()?, }) }) .collect()) } +} - pub async fn fetch(self) -> Result { +#[derive(Debug, Clone)] +pub struct PullRequest { + pub id: u64, + pub title: String, + pub description: String, + pub labels: Vec, + pub author: String, +} + +impl PullRequest { + pub async fn fetch(contribution: Contribution) -> Result { let request = reqwest::Client::new() .request( reqwest::Method::GET, format!( "https://api.github.com/repos/iced-rs/iced/pulls/{}", - self.id + contribution.id ), ) .header("User-Agent", "iced changelog generator") @@ -319,8 +345,8 @@ impl Candidate { let schema: Schema = request.send().await?.json().await?; - Ok(PullRequest { - id: self.id, + Ok(Self { + id: contribution.id, title: schema.title, description: schema.body, labels: schema.labels.into_iter().map(|label| label.name).collect(), @@ -339,6 +365,9 @@ pub enum Error { #[error("no GITHUB_TOKEN variable was set")] GitHubTokenNotFound, + + #[error("the changelog format is not valid")] + InvalidFormat, } impl From for Error { -- cgit