Skip to content

Commit d18ba48

Browse files
authored
Merge pull request #1704 from pitaj/no_merges-configs
add more config options for `no_merges`
2 parents a6a7a48 + a1a20a5 commit d18ba48

File tree

2 files changed

+101
-26
lines changed

2 files changed

+101
-26
lines changed

src/config.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,18 @@ pub(crate) struct AssignConfig {
9494

9595
#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
9696
pub(crate) struct NoMergesConfig {
97+
/// No action will be taken on PRs with these labels.
9798
#[serde(default)]
98-
_empty: (),
99+
pub(crate) exclude_labels: Vec<String>,
100+
/// Set these labels on the PR when merge commits are detected.
101+
#[serde(default)]
102+
pub(crate) labels: Vec<String>,
103+
/// Override the default message to post when merge commits are detected.
104+
///
105+
/// This message will always be followed up with
106+
/// "The following commits are merge commits:" and then
107+
/// a list of the merge commits.
108+
pub(crate) message: Option<String>,
99109
}
100110

101111
#[derive(PartialEq, Eq, Debug, serde::Deserialize)]

src/handlers/no_merges.rs

Lines changed: 90 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use crate::{
55
config::NoMergesConfig,
66
db::issue_data::IssueData,
7-
github::{IssuesAction, IssuesEvent},
7+
github::{IssuesAction, IssuesEvent, Label},
88
handlers::Context,
99
};
1010
use anyhow::Context as _;
@@ -38,16 +38,23 @@ pub(super) async fn parse_input(
3838
return Ok(None);
3939
}
4040

41-
// Require an empty configuration block to enable no-merges notifications.
42-
if config.is_none() {
41+
// Require a `[no_merges]` configuration block to enable no-merges notifications.
42+
let Some(config) = config else {
4343
return Ok(None);
44-
}
44+
};
4545

4646
// Don't ping on rollups or draft PRs.
4747
if event.issue.title.starts_with("Rollup of") || event.issue.draft {
4848
return Ok(None);
4949
}
5050

51+
// Don't trigger if the PR has any of the excluded labels.
52+
for label in event.issue.labels() {
53+
if config.exclude_labels.contains(&label.name) {
54+
return Ok(None);
55+
}
56+
}
57+
5158
let mut merge_commits = HashSet::new();
5259
let commits = event
5360
.issue
@@ -71,53 +78,74 @@ pub(super) async fn parse_input(
7178
})
7279
}
7380

81+
const DEFAULT_MESSAGE: &str = "
82+
There are merge commits (commits with multiple parents) in your changes. We have a \
83+
[no merge policy](https://rustc-dev-guide.rust-lang.org/git.html#no-merge-policy) \
84+
so these commits will need to be removed for this pull request to be merged.
85+
86+
You can start a rebase with the following commands:
87+
```shell-session
88+
$ # rebase
89+
$ git rebase -i master
90+
$ # delete any merge commits in the editor that appears
91+
$ git push --force-with-lease
92+
```
93+
94+
";
95+
7496
pub(super) async fn handle_input(
7597
ctx: &Context,
76-
_config: &NoMergesConfig,
98+
config: &NoMergesConfig,
7799
event: &IssuesEvent,
78100
input: NoMergesInput,
79101
) -> anyhow::Result<()> {
80102
let mut client = ctx.db.get().await;
81103
let mut state: IssueData<'_, NoMergesState> =
82104
IssueData::load(&mut client, &event.issue, NO_MERGES_KEY).await?;
83105

106+
let mut message = config
107+
.message
108+
.as_deref()
109+
.unwrap_or(DEFAULT_MESSAGE)
110+
.to_string();
111+
84112
let since_last_posted = if state.data.mentioned_merge_commits.is_empty() {
85113
""
86114
} else {
87115
" (since this message was last posted)"
88116
};
117+
writeln!(
118+
message,
119+
"The following commits are merge commits{since_last_posted}:"
120+
)
121+
.unwrap();
89122

90123
let mut should_send = false;
91-
let mut message = format!(
92-
"
93-
There are merge commits (commits with multiple parents) in your changes. We have a
94-
[no merge policy](https://rustc-dev-guide.rust-lang.org/git.html#no-merge-policy) so
95-
these commits will need to be removed for this pull request to be merged.
96-
97-
You can start a rebase with the following commands:
98-
99-
```shell-session
100-
$ # rebase
101-
$ git rebase -i master
102-
$ # delete any merge commits in the editor that appears
103-
$ git push --force-with-lease
104-
```
105-
106-
The following commits are merge commits{since_last_posted}:
107-
108-
"
109-
);
110124
for commit in &input.merge_commits {
111125
if state.data.mentioned_merge_commits.contains(commit) {
112126
continue;
113127
}
114128

115129
should_send = true;
116130
state.data.mentioned_merge_commits.insert((*commit).clone());
117-
write!(message, "- {commit}").unwrap();
131+
writeln!(message, "- {commit}").unwrap();
118132
}
119133

120134
if should_send {
135+
// Set labels
136+
let labels = config
137+
.labels
138+
.iter()
139+
.cloned()
140+
.map(|name| Label { name })
141+
.collect();
142+
event
143+
.issue
144+
.add_labels(&ctx.github, labels)
145+
.await
146+
.context("failed to set no_merges labels")?;
147+
148+
// Post comment
121149
event
122150
.issue
123151
.post_comment(&ctx.github, &message)
@@ -127,3 +155,40 @@ pub(super) async fn handle_input(
127155
}
128156
Ok(())
129157
}
158+
159+
#[cfg(test)]
160+
mod test {
161+
use super::*;
162+
163+
#[test]
164+
fn message() {
165+
let mut message = DEFAULT_MESSAGE.to_string();
166+
167+
writeln!(message, "The following commits are merge commits:").unwrap();
168+
169+
for n in 1..5 {
170+
writeln!(message, "- commit{n}").unwrap();
171+
}
172+
173+
assert_eq!(
174+
message,
175+
"
176+
There are merge commits (commits with multiple parents) in your changes. We have a [no merge policy](https://rustc-dev-guide.rust-lang.org/git.html#no-merge-policy) so these commits will need to be removed for this pull request to be merged.
177+
178+
You can start a rebase with the following commands:
179+
```shell-session
180+
$ # rebase
181+
$ git rebase -i master
182+
$ # delete any merge commits in the editor that appears
183+
$ git push --force-with-lease
184+
```
185+
186+
The following commits are merge commits:
187+
- commit1
188+
- commit2
189+
- commit3
190+
- commit4
191+
"
192+
);
193+
}
194+
}

0 commit comments

Comments
 (0)