From 6eab015866174f8afa5b05dd082c5f8062f28144 Mon Sep 17 00:00:00 2001 From: dark0dave Date: Fri, 30 Aug 2024 10:23:34 +0100 Subject: [PATCH] fix(436): Fix Missing/wrong pull requests for github commits Signed-off-by: dark0dave --- git-cliff-core/src/release.rs | 90 +++++++++++++++++++++++++- git-cliff-core/src/remote/bitbucket.rs | 4 ++ git-cliff-core/src/remote/gitea.rs | 8 +++ git-cliff-core/src/remote/github.rs | 6 ++ git-cliff-core/src/remote/gitlab.rs | 4 ++ git-cliff-core/src/remote/mod.rs | 6 +- 6 files changed, 115 insertions(+), 3 deletions(-) diff --git a/git-cliff-core/src/release.rs b/git-cliff-core/src/release.rs index 3c9fcabb2d..849cd919ae 100644 --- a/git-cliff-core/src/release.rs +++ b/git-cliff-core/src/release.rs @@ -59,7 +59,76 @@ pub struct Release<'a> { } #[cfg(feature = "github")] -crate::update_release_metadata!(github, update_github_metadata); +impl<'a> Release<'a> { + /// Updates the remote metadata that is contained in the release. + /// + /// This function takes two arguments: + /// + /// - Commits: needed for associating the Git user with the GitHub username. + /// - Pull requests: needed for generating the contributor list for the + /// release. + pub fn update_github_metadata( + &mut self, + mut commits: Vec>, + pull_requests: Vec>, + ) -> Result<()> { + let mut contributors: Vec = Vec::new(); + // retain the commits that are not a part of this release for later + // on checking the first contributors. + commits.retain(|v| { + if let Some(commit) = + self.commits.iter_mut().find(|commit| commit.id == v.id()) + { + let pull_request = pull_requests + .iter() + .find(|pr| pr.merge_commit() == Some(v.id().clone())); + debug!("-------------------------"); + debug!("{:?}", pull_request); + debug!("{:?}", commit); + commit.github.username = pull_request + .map(|v| v.try_get_author()) + .unwrap_or(v.username()); + + commit.github.pr_number = pull_request.map(|v| v.number()); + commit.github.pr_title = + pull_request.and_then(|v| v.title().clone()); + commit.github.pr_labels = + pull_request.map(|v| v.labels().clone()).unwrap_or_default(); + if let Some(contributor) = contributors + .iter_mut() + .find(|v| commit.github.username == v.username) + { + trace!("{:?}", contributor); + contributor.username = commit.github.username.clone(); + contributor.pr_number.get_or_insert(commit.github.pr_number.unwrap_or_default()); + } else { + contributors.push(RemoteContributor { + username: commit.github.username.clone(), + pr_title: commit.github.pr_title.clone(), + pr_number: commit.github.pr_number, + pr_labels: commit.github.pr_labels.clone(), + is_first_time: false, + }); + } + false + } else { + true + } + }); + // mark contributors as first-time + self.github.contributors = contributors + .into_iter() + .map(|mut v| { + v.is_first_time = !commits + .iter() + .map(|v| v.username()) + .any(|login| login == v.username); + v + }) + .collect(); + Ok(()) + } +} #[cfg(feature = "gitlab")] crate::update_release_metadata!(gitlab, update_gitlab_metadata); @@ -493,6 +562,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("rust"), }], + user: GitHubCommitAuthor { login: None }, }, GitHubPullRequest { title: Some(String::from("2")), @@ -503,6 +573,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("rust"), }], + user: GitHubCommitAuthor { login: None }, }, GitHubPullRequest { title: Some(String::from("3")), @@ -513,6 +584,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("deps"), }], + user: GitHubCommitAuthor { login: None }, }, GitHubPullRequest { title: Some(String::from("4")), @@ -523,6 +595,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("deps"), }], + user: GitHubCommitAuthor { login: None }, }, GitHubPullRequest { title: Some(String::from("5")), @@ -533,6 +606,9 @@ mod test { labels: vec![PullRequestLabel { name: String::from("github"), }], + user: GitHubCommitAuthor { + login: Some(String::from("idk")), + }, }, ] .into_iter() @@ -650,6 +726,13 @@ mod test { pr_labels: vec![String::from("deps")], is_first_time: true, }, + RemoteContributor { + username: Some(String::from("idk")), + pr_title: Some(String::from("5")), + pr_number: Some(999999), + pr_labels: vec![String::from("github")], + is_first_time: true, + }, ], }; assert_eq!(expected_metadata, release.github); @@ -1127,6 +1210,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("rust"), }], + user: GiteaCommitAuthor { login: None }, }, GiteaPullRequest { title: Some(String::from("2")), @@ -1137,6 +1221,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("rust"), }], + user: GiteaCommitAuthor { login: None }, }, GiteaPullRequest { title: Some(String::from("3")), @@ -1147,6 +1232,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("deps"), }], + user: GiteaCommitAuthor { login: None }, }, GiteaPullRequest { title: Some(String::from("4")), @@ -1157,6 +1243,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("deps"), }], + user: GiteaCommitAuthor { login: None }, }, GiteaPullRequest { title: Some(String::from("5")), @@ -1167,6 +1254,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("github"), }], + user: GiteaCommitAuthor { login: None }, }, ] .into_iter() diff --git a/git-cliff-core/src/remote/bitbucket.rs b/git-cliff-core/src/remote/bitbucket.rs index 7597711b39..3a332f86db 100644 --- a/git-cliff-core/src/remote/bitbucket.rs +++ b/git-cliff-core/src/remote/bitbucket.rs @@ -137,6 +137,10 @@ impl RemotePullRequest for BitbucketPullRequest { fn merge_commit(&self) -> Option { Some(self.merge_commit_sha.hash.clone()) } + + fn try_get_author(&self) -> Option { + self.author.login.clone() + } } /// diff --git a/git-cliff-core/src/remote/gitea.rs b/git-cliff-core/src/remote/gitea.rs index 251776c300..a2ab44be0b 100644 --- a/git-cliff-core/src/remote/gitea.rs +++ b/git-cliff-core/src/remote/gitea.rs @@ -75,6 +75,8 @@ pub struct PullRequestLabel { } /// Representation of a single pull request. +/// +/// #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct GiteaPullRequest { /// Pull request number. @@ -85,6 +87,8 @@ pub struct GiteaPullRequest { pub merge_commit_sha: Option, /// Labels of the pull request. pub labels: Vec, + /// Author of the pull request + pub user: GiteaCommitAuthor, } impl RemotePullRequest for GiteaPullRequest { @@ -103,6 +107,10 @@ impl RemotePullRequest for GiteaPullRequest { fn merge_commit(&self) -> Option { self.merge_commit_sha.clone() } + + fn try_get_author(&self) -> Option { + self.user.login.clone() + } } impl RemoteEntry for GiteaPullRequest { diff --git a/git-cliff-core/src/remote/github.rs b/git-cliff-core/src/remote/github.rs index 91e53956c2..6ddba6f100 100644 --- a/git-cliff-core/src/remote/github.rs +++ b/git-cliff-core/src/remote/github.rs @@ -85,6 +85,8 @@ pub struct GitHubPullRequest { pub merge_commit_sha: Option, /// Labels of the pull request. pub labels: Vec, + /// Author of the pull request. + pub user: GitHubCommitAuthor, } impl RemotePullRequest for GitHubPullRequest { @@ -103,6 +105,10 @@ impl RemotePullRequest for GitHubPullRequest { fn merge_commit(&self) -> Option { self.merge_commit_sha.clone() } + + fn try_get_author(&self) -> Option { + self.user.login.clone() + } } impl RemoteEntry for GitHubPullRequest { diff --git a/git-cliff-core/src/remote/gitlab.rs b/git-cliff-core/src/remote/gitlab.rs index 5863013670..bd89ce6292 100644 --- a/git-cliff-core/src/remote/gitlab.rs +++ b/git-cliff-core/src/remote/gitlab.rs @@ -174,6 +174,10 @@ impl RemotePullRequest for GitLabMergeRequest { fn merge_commit(&self) -> Option { self.merge_commit_sha.clone() } + + fn try_get_author(&self) -> Option { + Some(self.author.name.clone()) + } } impl RemoteEntry for GitLabMergeRequest { diff --git a/git-cliff-core/src/remote/mod.rs b/git-cliff-core/src/remote/mod.rs index f4bf29c982..5cc2c46583 100644 --- a/git-cliff-core/src/remote/mod.rs +++ b/git-cliff-core/src/remote/mod.rs @@ -80,7 +80,7 @@ pub trait RemoteEntry { } /// Trait for handling remote commits. -pub trait RemoteCommit: DynClone { +pub trait RemoteCommit: DynClone + Debug { /// Commit SHA. fn id(&self) -> String; /// Commit author. @@ -90,7 +90,7 @@ pub trait RemoteCommit: DynClone { dyn_clone::clone_trait_object!(RemoteCommit); /// Trait for handling remote pull requests. -pub trait RemotePullRequest: DynClone { +pub trait RemotePullRequest: DynClone + Debug { /// Number. fn number(&self) -> i64; /// Title. @@ -99,6 +99,8 @@ pub trait RemotePullRequest: DynClone { fn labels(&self) -> Vec; /// Merge commit SHA. fn merge_commit(&self) -> Option; + /// Try to get author from pull request + fn try_get_author(&self) -> Option; } dyn_clone::clone_trait_object!(RemotePullRequest);