Skip to content

Commit 602f13b

Browse files
committed
Add support for exceptions in non default branch warning
1 parent 742b66b commit 602f13b

File tree

2 files changed

+63
-9
lines changed

2 files changed

+63
-9
lines changed

src/config.rs

+41-2
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ pub(crate) struct PingTeamConfig {
9090
#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
9191
#[serde(deny_unknown_fields)]
9292
pub(crate) struct AssignConfig {
93-
/// If `true`, then posts a warning comment if the PR is opened against a
93+
/// If enabled, then posts a warning comment if the PR is opened against a
9494
/// different branch than the default (usually master or main).
9595
#[serde(default)]
96-
pub(crate) warn_non_default_branch: bool,
96+
pub(crate) warn_non_default_branch: WarnNonDefaultBranchConfig,
9797
/// A URL to include in the welcome message.
9898
pub(crate) contributing_url: Option<String>,
9999
/// Ad-hoc groups that can be referred to in `owners`.
@@ -117,6 +117,45 @@ impl AssignConfig {
117117
}
118118
}
119119

120+
#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
121+
#[serde(deny_unknown_fields)]
122+
#[serde(untagged)]
123+
pub(crate) enum WarnNonDefaultBranchConfig {
124+
Simple(bool),
125+
Extended {
126+
enable: bool,
127+
/// List of exceptions that have a different default branch
128+
#[serde(default)]
129+
exceptions: Vec<WarnNonDefaultBranchException>,
130+
},
131+
}
132+
133+
#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
134+
#[serde(deny_unknown_fields)]
135+
pub(crate) struct WarnNonDefaultBranchException {
136+
/// Substring in the title that match this exception
137+
pub(crate) title: String,
138+
/// The actual branch that should be associated with the issue
139+
pub(crate) branch: String,
140+
}
141+
142+
impl Default for WarnNonDefaultBranchConfig {
143+
fn default() -> WarnNonDefaultBranchConfig {
144+
WarnNonDefaultBranchConfig::Simple(false)
145+
}
146+
}
147+
148+
impl WarnNonDefaultBranchConfig {
149+
pub(crate) fn enabled_and_exceptions(&self) -> Option<&[WarnNonDefaultBranchException]> {
150+
match self {
151+
WarnNonDefaultBranchConfig::Simple(enable) => enable.then(|| &[] as &[_]),
152+
WarnNonDefaultBranchConfig::Extended { enable, exceptions } => {
153+
enable.then(|| exceptions.as_slice())
154+
}
155+
}
156+
}
157+
}
158+
120159
#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
121160
#[serde(deny_unknown_fields)]
122161
pub(crate) struct NoMergesConfig {

src/handlers/assign.rs

+22-7
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
//! the PR modifies.
1919
2020
use crate::{
21-
config::AssignConfig,
21+
config::{AssignConfig, WarnNonDefaultBranchException},
2222
github::{self, Event, FileDiff, Issue, IssuesAction, Selection},
2323
handlers::{Context, GithubClient, IssuesEvent},
2424
interactions::EditIssueBody,
@@ -73,6 +73,11 @@ const NON_DEFAULT_BRANCH: &str =
7373
but this one is against {target}. \
7474
Please double check that you specified the right target!";
7575

76+
const NON_DEFAULT_BRANCH_EXCEPTION: &str =
77+
"Pull requests targetting the {default} branch are usually filed against the {default} \
78+
branch, but this one is against {target}. \
79+
Please double check that you specified the right target!";
80+
7681
const SUBMODULE_WARNING_MSG: &str = "These commits modify **submodules**.";
7782

7883
fn on_vacation_msg(user: &str) -> String {
@@ -179,8 +184,8 @@ pub(super) async fn handle_input(
179184

180185
// Compute some warning messages to post to new PRs.
181186
let mut warnings = Vec::new();
182-
if config.warn_non_default_branch {
183-
warnings.extend(non_default_branch(event));
187+
if let Some(exceptions) = config.warn_non_default_branch.enabled_and_exceptions() {
188+
warnings.extend(non_default_branch(exceptions, event));
184189
}
185190
warnings.extend(modifies_submodule(diff));
186191
if !warnings.is_empty() {
@@ -209,15 +214,25 @@ fn is_self_assign(assignee: &str, pr_author: &str) -> bool {
209214
assignee.to_lowercase() == pr_author.to_lowercase()
210215
}
211216

212-
/// Returns a message if the PR is opened against the non-default branch.
213-
fn non_default_branch(event: &IssuesEvent) -> Option<String> {
217+
/// Returns a message if the PR is opened against the non-default branch (or the exception branch
218+
/// if it's an exception).
219+
fn non_default_branch(
220+
exceptions: &[WarnNonDefaultBranchException],
221+
event: &IssuesEvent,
222+
) -> Option<String> {
214223
let target_branch = &event.issue.base.as_ref().unwrap().git_ref;
215-
let default_branch = &event.repository.default_branch;
224+
let (default_branch, warn_msg) = exceptions
225+
.iter()
226+
.find(|e| event.issue.title.contains(&e.title))
227+
.map_or_else(
228+
|| (&event.repository.default_branch, NON_DEFAULT_BRANCH),
229+
|e| (&e.branch, NON_DEFAULT_BRANCH_EXCEPTION),
230+
);
216231
if target_branch == default_branch {
217232
return None;
218233
}
219234
Some(
220-
NON_DEFAULT_BRANCH
235+
warn_msg
221236
.replace("{default}", default_branch)
222237
.replace("{target}", target_branch),
223238
)

0 commit comments

Comments
 (0)