Skip to content

Commit 3e7a08b

Browse files
authored
Merge pull request #360 from Kobzol/delegate-comment
Improve delegate comments
2 parents 038b313 + 9edde73 commit 3e7a08b

File tree

10 files changed

+102
-39
lines changed

10 files changed

+102
-39
lines changed

src/bin/bors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ fn try_main(opts: Opts) -> anyhow::Result<()> {
137137

138138
let db = Arc::new(db);
139139
let ctx = BorsContext::new(
140-
CommandParser::new(opts.cmd_prefix.clone()),
140+
CommandParser::new(opts.cmd_prefix.clone().into()),
141141
db.clone(),
142142
repos.clone(),
143143
);
@@ -194,7 +194,7 @@ fn try_main(opts: Opts) -> anyhow::Result<()> {
194194
WebhookSecret::new(opts.webhook_secret),
195195
repos,
196196
db,
197-
opts.cmd_prefix,
197+
opts.cmd_prefix.into(),
198198
);
199199
let server_process = webhook_server(state);
200200

src/bors/command/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod parser;
22
use std::fmt;
3+
use std::fmt::{Display, Formatter};
34
use std::str::FromStr;
45

56
use crate::{database::DelegatedPermission, github::CommitSha};
@@ -8,6 +9,27 @@ pub use parser::{CommandParseError, CommandParser};
89
/// Priority of a commit.
910
pub type Priority = u32;
1011

12+
/// Command prefix used to identify bors commands, e.g. `@bors`.
13+
pub struct CommandPrefix(String);
14+
15+
impl From<String> for CommandPrefix {
16+
fn from(value: String) -> Self {
17+
Self(value)
18+
}
19+
}
20+
21+
impl Display for CommandPrefix {
22+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
23+
self.0.fmt(f)
24+
}
25+
}
26+
27+
impl AsRef<str> for CommandPrefix {
28+
fn as_ref(&self) -> &str {
29+
self.0.as_str()
30+
}
31+
}
32+
1133
/// Type of parent allowed in a try build
1234
#[derive(Clone, Debug, PartialEq)]
1335
pub enum Parent {

src/bors/command/parser.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Defines parsers for bors commands.
22
3-
use crate::bors::command::{Approver, BorsCommand, Parent};
3+
use crate::bors::command::{Approver, BorsCommand, CommandPrefix, Parent};
44
use crate::database::DelegatedPermission;
55
use crate::github::CommitSha;
66
use pulldown_cmark::{Event, Parser, Tag, TagEnd, TextMergeStream};
@@ -27,17 +27,17 @@ enum CommandPart<'a> {
2727
}
2828

2929
pub struct CommandParser {
30-
prefix: String,
30+
prefix: CommandPrefix,
3131
}
3232

3333
impl CommandParser {
34-
pub fn new(prefix: String) -> Self {
34+
pub fn new(prefix: CommandPrefix) -> Self {
3535
Self { prefix }
3636
}
3737

3838
/// Prefix of the bot, used to invoke commands from PR comments.
3939
/// For example `@bors`.
40-
pub fn prefix(&self) -> &str {
40+
pub fn prefix(&self) -> &CommandPrefix {
4141
&self.prefix
4242
}
4343

@@ -49,9 +49,9 @@ impl CommandParser {
4949
let segments = extract_text_from_markdown(text);
5050
segments
5151
.lines()
52-
.filter_map(|line| match line.find(&self.prefix) {
52+
.filter_map(|line| match line.find(self.prefix.as_ref()) {
5353
Some(index) => {
54-
let input = &line[index + self.prefix.len()..];
54+
let input = &line[index + self.prefix.as_ref().len()..];
5555
parse_command(input)
5656
}
5757
None => None,
@@ -1346,6 +1346,6 @@ I am markdown HTML comment
13461346
}
13471347

13481348
fn parse_commands(text: &str) -> Vec<Result<BorsCommand, CommandParseError>> {
1349-
CommandParser::new("@bors".to_string()).parse_commands(text)
1349+
CommandParser::new("@bors".to_string().into()).parse_commands(text)
13501350
}
13511351
}

src/bors/comment.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use serde::Serialize;
22

3+
use crate::bors::command::CommandPrefix;
34
use crate::database::BuildModel;
45
use crate::{
56
database::{WorkflowModel, WorkflowStatus},
@@ -105,7 +106,7 @@ pub fn workflow_failed_comment(workflows: &[WorkflowModel]) -> Comment {
105106
pub fn try_build_started_comment(
106107
head_sha: &CommitSha,
107108
merge_sha: &CommitSha,
108-
bot_prefix: &str,
109+
bot_prefix: &CommandPrefix,
109110
cancelled_workflow_urls: Vec<String>,
110111
) -> Comment {
111112
use std::fmt::Write;
@@ -167,6 +168,26 @@ pub fn approve_non_open_pr_comment() -> Comment {
167168
Comment::new("Only open, non-draft PRs can be approved".to_string())
168169
}
169170

171+
pub fn delegate_try_builds_comment(delegatee: &str, bot_prefix: &CommandPrefix) -> Comment {
172+
Comment::new(format!(
173+
r":v: @{delegatee}, you can now perform try builds on this pull request!
174+
175+
You can now post `{bot_prefix} try` to start a try build.
176+
",
177+
))
178+
}
179+
180+
/// `delegatee` is the user who received the delegation privileges, while `delegator` is the user
181+
/// who gave these privileges to the `delegatee`.
182+
pub fn delegate_comment(delegatee: &str, delegator: &str, bot_prefix: &CommandPrefix) -> Comment {
183+
Comment::new(format!(
184+
r#":v: @{delegatee}, you can now approve this pull request!
185+
186+
If @{delegator} told you to "`r=me`" after making some further change, then please make that change and post `{bot_prefix} r={delegator}`.
187+
"#
188+
))
189+
}
190+
170191
fn list_workflows_status(workflows: &[WorkflowModel]) -> String {
171192
workflows
172193
.iter()

src/bors/handlers/mod.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,16 @@ async fn handle_comment(
446446
}
447447
BorsCommand::SetDelegate(delegate_type) => {
448448
let span = tracing::info_span!("Delegate");
449-
command_delegate(repo, database, &pr, &comment.author, delegate_type)
450-
.instrument(span)
451-
.await
449+
command_delegate(
450+
repo,
451+
database,
452+
&pr,
453+
&comment.author,
454+
delegate_type,
455+
ctx.parser.prefix(),
456+
)
457+
.instrument(span)
458+
.await
452459
}
453460
BorsCommand::Undelegate => {
454461
let span = tracing::info_span!("Undelegate");

src/bors/handlers/review.rs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ use std::sync::Arc;
22

33
use crate::PgDbClient;
44
use crate::bors::RepositoryState;
5-
use crate::bors::command::Approver;
65
use crate::bors::command::RollupMode;
7-
use crate::bors::comment::approve_non_open_pr_comment;
6+
use crate::bors::command::{Approver, CommandPrefix};
7+
use crate::bors::comment::{
8+
approve_non_open_pr_comment, delegate_comment, delegate_try_builds_comment,
9+
};
810
use crate::bors::handlers::has_permission;
911
use crate::bors::handlers::labels::handle_label_trigger;
1012
use crate::bors::handlers::{PullRequestData, deny_request};
@@ -102,6 +104,7 @@ pub(super) async fn command_delegate(
102104
pr: &PullRequestData,
103105
author: &GithubUser,
104106
delegated_permission: DelegatedPermission,
107+
bot_prefix: &CommandPrefix,
105108
) -> anyhow::Result<()> {
106109
tracing::info!(
107110
"Delegating PR {} {} permissions",
@@ -118,7 +121,9 @@ pub(super) async fn command_delegate(
118121
&repo_state,
119122
pr.number(),
120123
&pr.github.author.username,
124+
&author.username,
121125
delegated_permission,
126+
bot_prefix,
122127
)
123128
.await
124129
}
@@ -268,19 +273,16 @@ async fn notify_of_delegation(
268273
repo: &RepositoryState,
269274
pr_number: PullRequestNumber,
270275
delegatee: &str,
276+
delegator: &str,
271277
delegated_permission: DelegatedPermission,
278+
bot_prefix: &CommandPrefix,
272279
) -> anyhow::Result<()> {
273-
let message = match delegated_permission {
274-
DelegatedPermission::Try => format!(
275-
"@{} can now perform try builds on this pull request",
276-
delegatee
277-
),
278-
DelegatedPermission::Review => format!("@{} can now approve this pull request", delegatee),
280+
let comment = match delegated_permission {
281+
DelegatedPermission::Try => delegate_try_builds_comment(delegatee, bot_prefix),
282+
DelegatedPermission::Review => delegate_comment(delegatee, delegator, bot_prefix),
279283
};
280284

281-
repo.client
282-
.post_comment(pr_number, Comment::new(message))
283-
.await
285+
repo.client.post_comment(pr_number, comment).await
284286
}
285287

286288
#[cfg(test)]
@@ -542,7 +544,11 @@ mod tests {
542544
.await?;
543545
insta::assert_snapshot!(
544546
tester.get_comment().await?,
545-
@"@default-user can now approve this pull request"
547+
@r#"
548+
:v: @default-user, you can now approve this pull request!
549+
550+
If @reviewer told you to "`r=me`" after making some further change, then please make that change and post `@bors r=reviewer`.
551+
"#
546552
);
547553

548554
tester
@@ -980,7 +986,11 @@ mod tests {
980986
.await?;
981987
insta::assert_snapshot!(
982988
tester.get_comment().await?,
983-
@"@default-user can now perform try builds on this pull request"
989+
@r"
990+
:v: @default-user, you can now perform try builds on this pull request!
991+
992+
You can now post `@bors try` to start a try build.
993+
"
984994
);
985995
tester
986996
.default_pr()

src/bors/handlers/trybuild.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::sync::Arc;
22

33
use crate::PgDbClient;
44
use crate::bors::RepositoryState;
5-
use crate::bors::command::Parent;
5+
use crate::bors::command::{CommandPrefix, Parent};
66
use crate::bors::comment::no_try_build_in_progress_comment;
77
use crate::bors::comment::try_build_cancelled_comment;
88
use crate::bors::comment::unclean_try_build_cancelled_comment;
@@ -51,7 +51,7 @@ pub(super) async fn command_try_build(
5151
author: &GithubUser,
5252
parent: Option<Parent>,
5353
jobs: Vec<String>,
54-
bot_prefix: &str,
54+
bot_prefix: &CommandPrefix,
5555
) -> anyhow::Result<()> {
5656
let repo = repo.as_ref();
5757
if !has_permission(repo, author, pr, PermissionType::Try).await? {

src/bors/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ mod handlers;
2525
pub mod merge_queue;
2626
pub mod mergeable_queue;
2727

28+
pub use command::CommandPrefix;
29+
2830
#[cfg(test)]
2931
pub static WAIT_FOR_CANCEL_TIMED_OUT_BUILDS_REFRESH: TestSyncMarker = TestSyncMarker::new();
3032

src/github/server.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::bors::mergeable_queue::{
55
handle_mergeable_queue_item,
66
};
77
use crate::bors::{
8-
BorsContext, RepositoryState, RollupMode, handle_bors_global_event,
8+
BorsContext, CommandPrefix, RepositoryState, RollupMode, handle_bors_global_event,
99
handle_bors_repository_event,
1010
};
1111
use crate::github::webhook::GitHubWebhook;
@@ -42,7 +42,7 @@ pub struct ServerState {
4242
webhook_secret: WebhookSecret,
4343
repositories: HashMap<GithubRepoName, Arc<RepositoryState>>,
4444
db: Arc<PgDbClient>,
45-
cmd_prefix: String,
45+
cmd_prefix: CommandPrefix,
4646
}
4747

4848
impl ServerState {
@@ -52,7 +52,7 @@ impl ServerState {
5252
webhook_secret: WebhookSecret,
5353
repositories: HashMap<GithubRepoName, Arc<RepositoryState>>,
5454
db: Arc<PgDbClient>,
55-
cmd_prefix: String,
55+
cmd_prefix: CommandPrefix,
5656
) -> Self {
5757
Self {
5858
repository_event_queue,
@@ -68,7 +68,7 @@ impl ServerState {
6868
&self.webhook_secret
6969
}
7070

71-
pub fn get_cmd_prefix(&self) -> &str {
71+
pub fn get_cmd_prefix(&self) -> &CommandPrefix {
7272
&self.cmd_prefix
7373
}
7474
}
@@ -123,7 +123,7 @@ async fn help_handler(State(state): State<ServerStateRef>) -> impl IntoResponse
123123

124124
HtmlTemplate(HelpTemplate {
125125
repos,
126-
cmd_prefix: state.get_cmd_prefix().to_string(),
126+
cmd_prefix: state.get_cmd_prefix().as_ref().to_string(),
127127
})
128128
}
129129

src/tests/mocks/bors.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ use super::repository::PullRequest;
1919
use crate::bors::merge_queue::MergeQueueSender;
2020
use crate::bors::mergeable_queue::MergeableQueueSender;
2121
use crate::bors::{
22-
RollupMode, WAIT_FOR_CANCEL_TIMED_OUT_BUILDS_REFRESH, WAIT_FOR_MERGEABILITY_STATUS_REFRESH,
23-
WAIT_FOR_PR_STATUS_REFRESH, WAIT_FOR_WORKFLOW_STARTED,
22+
CommandPrefix, RollupMode, WAIT_FOR_CANCEL_TIMED_OUT_BUILDS_REFRESH,
23+
WAIT_FOR_MERGEABILITY_STATUS_REFRESH, WAIT_FOR_PR_STATUS_REFRESH, WAIT_FOR_WORKFLOW_STARTED,
2424
};
2525
use crate::database::{BuildStatus, DelegatedPermission, OctocrabMergeableState, PullRequestModel};
2626
use crate::github::api::load_repositories;
@@ -33,9 +33,6 @@ use crate::tests::mocks::workflow::{
3333
};
3434
use octocrab::params::checks::{CheckRunConclusion, CheckRunStatus};
3535

36-
pub fn default_cmd_prefix() -> String {
37-
"@bors".to_string()
38-
}
3936
use crate::tests::mocks::{
4037
Branch, ExternalHttpMock, GitHubState, Repo, User, default_pr_number, default_repo_name,
4138
};
@@ -46,6 +43,10 @@ use crate::{
4643
create_app, create_bors_process,
4744
};
4845

46+
pub fn default_cmd_prefix() -> CommandPrefix {
47+
"@bors".to_string().into()
48+
}
49+
4950
pub struct BorsBuilder {
5051
github: GitHubState,
5152
pool: PgPool,
@@ -131,7 +132,7 @@ impl BorsTester {
131132
}
132133

133134
let ctx = BorsContext::new(
134-
CommandParser::new("@bors".to_string()),
135+
CommandParser::new("@bors".to_string().into()),
135136
db.clone(),
136137
repos.clone(),
137138
);

0 commit comments

Comments
 (0)