From 18754e298808e03e23d55f67d8c686e3ec635286 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 | 83 +++++++++++++++++++++++++- 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 | 2 + 6 files changed, 106 insertions(+), 1 deletion(-) diff --git a/git-cliff-core/src/release.rs b/git-cliff-core/src/release.rs index 3c9fcabb2d..c2a62489ee 100644 --- a/git-cliff-core/src/release.rs +++ b/git-cliff-core/src/release.rs @@ -59,7 +59,69 @@ 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())); + commit.github.username = 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 !contributors + .iter() + .any(|v| commit.github.username == v.username) + { + contributors.push(RemoteContributor { + username: pull_request + .map(|v| v.try_get_author()) + .unwrap_or(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 +555,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("rust"), }], + user: GitHubCommitAuthor { login: None }, }, GitHubPullRequest { title: Some(String::from("2")), @@ -503,6 +566,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("rust"), }], + user: GitHubCommitAuthor { login: None }, }, GitHubPullRequest { title: Some(String::from("3")), @@ -513,6 +577,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("deps"), }], + user: GitHubCommitAuthor { login: None }, }, GitHubPullRequest { title: Some(String::from("4")), @@ -523,6 +588,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("deps"), }], + user: GitHubCommitAuthor { login: None }, }, GitHubPullRequest { title: Some(String::from("5")), @@ -533,6 +599,9 @@ mod test { labels: vec![PullRequestLabel { name: String::from("github"), }], + user: GitHubCommitAuthor { + login: Some(String::from("idk")), + }, }, ] .into_iter() @@ -650,6 +719,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 +1203,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("rust"), }], + user: GiteaCommitAuthor { login: None }, }, GiteaPullRequest { title: Some(String::from("2")), @@ -1137,6 +1214,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("rust"), }], + user: GiteaCommitAuthor { login: None }, }, GiteaPullRequest { title: Some(String::from("3")), @@ -1147,6 +1225,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("deps"), }], + user: GiteaCommitAuthor { login: None }, }, GiteaPullRequest { title: Some(String::from("4")), @@ -1157,6 +1236,7 @@ mod test { labels: vec![PullRequestLabel { name: String::from("deps"), }], + user: GiteaCommitAuthor { login: None }, }, GiteaPullRequest { title: Some(String::from("5")), @@ -1167,6 +1247,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..8bcd2fd02d 100644 --- a/git-cliff-core/src/remote/mod.rs +++ b/git-cliff-core/src/remote/mod.rs @@ -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);