Skip to content

Commit e1b1c75

Browse files
committed
Parse @bors try commands to replace homu for try builds
1 parent b083539 commit e1b1c75

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

src/bors/command/parser.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,22 @@ enum CommandPart<'a> {
2828

2929
pub struct CommandParser {
3030
prefix: String,
31+
parsers: Vec<ParserFn>,
3132
}
3233

3334
impl CommandParser {
3435
pub fn new(prefix: String) -> Self {
35-
Self { prefix }
36+
Self {
37+
prefix,
38+
parsers: DEFAULT_PARSERS.to_vec(),
39+
}
40+
}
41+
42+
pub fn new_try_only(prefix: String) -> Self {
43+
Self {
44+
prefix,
45+
parsers: ONLY_TRY_PARSERS.to_vec(),
46+
}
3647
}
3748

3849
/// Prefix of the bot, used to invoke commands from PR comments.
@@ -52,7 +63,7 @@ impl CommandParser {
5263
.filter_map(|line| match line.find(&self.prefix) {
5364
Some(index) => {
5465
let input = &line[index + self.prefix.len()..];
55-
parse_command(input)
66+
parse_command(input, &self.parsers)
5667
}
5768
None => None,
5869
})
@@ -116,9 +127,10 @@ fn extract_text_from_markdown(text: &str) -> String {
116127
}
117128

118129
type ParseResult<T = BorsCommand> = Option<Result<T, CommandParseError>>;
130+
type ParserFn = fn(&CommandPart<'_>, &[CommandPart<'_>]) -> ParseResult;
119131

120132
// The order of the parsers in the vector is important
121-
const PARSERS: &[fn(&CommandPart<'_>, &[CommandPart<'_>]) -> ParseResult] = &[
133+
const DEFAULT_PARSERS: &[ParserFn] = &[
122134
parser_approval,
123135
parser_unapprove,
124136
parser_rollup,
@@ -133,12 +145,14 @@ const PARSERS: &[fn(&CommandPart<'_>, &[CommandPart<'_>]) -> ParseResult] = &[
133145
parser_tree_ops,
134146
];
135147

136-
fn parse_command(input: &str) -> ParseResult {
148+
const ONLY_TRY_PARSERS: &[ParserFn] = &[parser_try_cancel, parser_try];
149+
150+
fn parse_command(input: &str, parsers: &[ParserFn]) -> ParseResult {
137151
match parse_parts(input) {
138152
Ok(parts) => match parts.as_slice() {
139153
[] => Some(Err(CommandParseError::MissingCommand)),
140154
[command, arguments @ ..] => {
141-
for parser in PARSERS {
155+
for parser in parsers {
142156
if let Some(result) = parser(command, arguments) {
143157
return Some(result);
144158
}

src/bors/handlers/mod.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::bors::{BorsContext, Comment, RepositoryState};
2424
use crate::database::{DelegatedPermission, PullRequestModel};
2525
use crate::github::{GithubUser, PullRequest, PullRequestNumber};
2626
use crate::permissions::PermissionType;
27-
use crate::{PgDbClient, TeamApiClient, load_repositories};
27+
use crate::{CommandParser, PgDbClient, TeamApiClient, load_repositories};
2828
use anyhow::Context;
2929
use octocrab::Octocrab;
3030
use pr_events::{
@@ -360,7 +360,23 @@ async fn handle_comment(
360360
use std::fmt::Write;
361361

362362
let pr_number = comment.pr_number;
363-
let commands = ctx.parser.parse_commands(&comment.text);
363+
let mut commands = ctx.parser.parse_commands(&comment.text);
364+
365+
// Temporary special case for migration from homu on rust-lang/rust.
366+
// Try to parse `@bors try` commands with a hardcoded prefix normally assigned to homu.
367+
if repo.repository().owner() == "rust-lang" && repo.repository().name() == "rust" {
368+
let homu_commands = CommandParser::new_try_only("@bors".to_string())
369+
.parse_commands(&comment.text)
370+
.into_iter()
371+
.filter(|res| match res {
372+
// Let homu handle unknown and missing commands
373+
Err(CommandParseError::UnknownCommand(_) | CommandParseError::MissingCommand) => {
374+
false
375+
}
376+
_ => true,
377+
});
378+
commands.extend(homu_commands);
379+
}
364380

365381
// Bail if no commands
366382
if commands.is_empty() {

0 commit comments

Comments
 (0)