Skip to content

Commit c6d4fc9

Browse files
Merge pull request #682 from kellda/diff-command
Execute only changed commands
2 parents 8d1570c + 6c30d9e commit c6d4fc9

File tree

11 files changed

+144
-42
lines changed

11 files changed

+144
-42
lines changed

parser/src/command.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub fn find_commmand_start(input: &str, bot: &str) -> Option<usize> {
1414
input.find(&format!("@{}", bot))
1515
}
1616

17-
#[derive(Debug)]
17+
#[derive(Debug, PartialEq)]
1818
pub enum Command<'a> {
1919
Relabel(Result<relabel::RelabelCommand, Error<'a>>),
2020
Assign(Result<assign::AssignCommand, Error<'a>>),
@@ -197,6 +197,24 @@ fn code_2() {
197197
assert!(input.parse_command().is_none());
198198
}
199199

200+
#[test]
201+
fn edit_1() {
202+
let input_old = "@bot modify labels: +bug.";
203+
let mut input_old = Input::new(input_old, "bot");
204+
let input_new = "Adding labels: @bot modify labels: +bug. some other text";
205+
let mut input_new = Input::new(input_new, "bot");
206+
assert_eq!(input_old.parse_command(), input_new.parse_command());
207+
}
208+
209+
#[test]
210+
fn edit_2() {
211+
let input_old = "@bot modify label: +bug.";
212+
let mut input_old = Input::new(input_old, "bot");
213+
let input_new = "@bot modify labels: +bug.";
214+
let mut input_new = Input::new(input_new, "bot");
215+
assert_ne!(input_old.parse_command(), input_new.parse_command());
216+
}
217+
200218
#[test]
201219
fn move_input_along() {
202220
let input = "@bot modify labels: +bug. Afterwards, delete the world.";

parser/src/command/relabel.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use crate::token::{Token, Tokenizer};
2929
use std::error::Error as _;
3030
use std::fmt;
3131

32-
#[derive(Debug)]
32+
#[derive(Debug, PartialEq, Eq)]
3333
pub struct RelabelCommand(pub Vec<LabelDelta>);
3434

3535
#[derive(Debug, PartialEq, Eq)]

src/github.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,16 @@ impl Issue {
541541
}
542542
}
543543

544+
#[derive(Debug, serde::Deserialize)]
545+
pub struct ChangeInner {
546+
pub from: String,
547+
}
548+
549+
#[derive(Debug, serde::Deserialize)]
550+
pub struct Changes {
551+
pub body: ChangeInner,
552+
}
553+
544554
#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
545555
#[serde(rename_all = "lowercase")]
546556
pub enum PullRequestReviewAction {
@@ -554,12 +564,14 @@ pub struct PullRequestReviewEvent {
554564
pub action: PullRequestReviewAction,
555565
pub pull_request: Issue,
556566
pub review: Comment,
567+
pub changes: Option<Changes>,
557568
pub repository: Repository,
558569
}
559570

560571
#[derive(Debug, serde::Deserialize)]
561572
pub struct PullRequestReviewComment {
562573
pub action: IssueCommentAction,
574+
pub changes: Option<Changes>,
563575
#[serde(rename = "pull_request")]
564576
pub issue: Issue,
565577
pub comment: Comment,
@@ -577,6 +589,7 @@ pub enum IssueCommentAction {
577589
#[derive(Debug, serde::Deserialize)]
578590
pub struct IssueCommentEvent {
579591
pub action: IssueCommentAction,
592+
pub changes: Option<Changes>,
580593
pub issue: Issue,
581594
pub comment: Comment,
582595
pub repository: Repository,
@@ -612,6 +625,7 @@ pub struct IssuesEvent {
612625
pub action: IssuesAction,
613626
#[serde(alias = "pull_request")]
614627
pub issue: Issue,
628+
pub changes: Option<Changes>,
615629
pub repository: Repository,
616630
/// Some if action is IssuesAction::Labeled, for example
617631
pub label: Option<Label>,
@@ -769,6 +783,14 @@ impl Event {
769783
}
770784
}
771785

786+
/// This will both extract from IssueComment events but also Issue events
787+
pub fn comment_from(&self) -> Option<&str> {
788+
match self {
789+
Event::Issue(e) => Some(&e.changes.as_ref()?.body.from),
790+
Event::IssueComment(e) => Some(&e.changes.as_ref()?.body.from),
791+
}
792+
}
793+
772794
pub fn html_url(&self) -> Option<&str> {
773795
match self {
774796
Event::Issue(e) => Some(&e.issue.html_url),

src/handlers/assign.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,29 @@ impl Handler for AssignmentHandler {
4747
};
4848

4949
if let Event::Issue(e) = event {
50-
if e.action != github::IssuesAction::Opened {
50+
if !matches!(e.action, github::IssuesAction::Opened | github::IssuesAction::Edited) {
5151
log::debug!("skipping event, issue was {:?}", e.action);
52-
// skip events other than opening the issue to avoid retriggering commands in the
52+
// skip events other than opening or editing the issue to avoid retriggering commands in the
5353
// issue body
5454
return Ok(None);
5555
}
5656
}
5757

5858
let mut input = Input::new(&body, &ctx.username);
59-
match input.parse_command() {
59+
let command = input.parse_command();
60+
61+
if let Some(previous) = event.comment_from() {
62+
let mut prev_input = Input::new(&previous, &ctx.username);
63+
let prev_command = prev_input.parse_command();
64+
if command == prev_command {
65+
log::info!("skipping unmodified command: {:?} -> {:?}", prev_command, command);
66+
return Ok(None);
67+
} else {
68+
log::debug!("executing modified command: {:?} -> {:?}", prev_command, command);
69+
}
70+
}
71+
72+
match command {
6073
Command::Assign(Ok(command)) => Ok(Some(command)),
6174
Command::Assign(Err(err)) => {
6275
return Err(format!(

src/handlers/glacier.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,17 @@ impl Handler for GlacierHandler {
3232
};
3333

3434
let mut input = Input::new(&body, &ctx.username);
35-
match input.parse_command() {
35+
let command = input.parse_command();
36+
37+
if let Some(previous) = event.comment_from() {
38+
let mut prev_input = Input::new(&previous, &ctx.username);
39+
let prev_command = prev_input.parse_command();
40+
if command == prev_command {
41+
return Ok(None);
42+
}
43+
}
44+
45+
match command {
3646
Command::Glacier(Ok(command)) => Ok(Some(command)),
3747
Command::Glacier(Err(err)) => {
3848
return Err(format!(

src/handlers/major_change.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,21 @@ impl Handler for MajorChangeHandler {
6363
// All other issue events are ignored
6464
return Ok(None);
6565
}
66-
Event::IssueComment(e) => {
67-
if e.action != github::IssueCommentAction::Created {
68-
return Ok(None);
69-
}
70-
}
66+
Event::IssueComment(e) => {}
7167
}
7268

7369
let mut input = Input::new(&body, &ctx.username);
74-
match input.parse_command() {
70+
let command = input.parse_command();
71+
72+
if let Some(previous) = event.comment_from() {
73+
let mut prev_input = Input::new(&previous, &ctx.username);
74+
let prev_command = prev_input.parse_command();
75+
if command == prev_command {
76+
return Ok(None);
77+
}
78+
}
79+
80+
match command {
7581
Command::Second(Ok(SecondCommand)) => Ok(Some(Invocation::Second)),
7682
_ => Ok(None),
7783
}
@@ -107,14 +113,6 @@ async fn handle_input(
107113
return Ok(());
108114
}
109115

110-
if !issue.labels().iter().any(|l| l.name == "major-change") {
111-
let cmnt = ErrorComment::new(
112-
&issue,
113-
"This is not a major change (it lacks the `major-change` label).",
114-
);
115-
cmnt.post(&ctx.github).await?;
116-
return Ok(());
117-
}
118116
let is_team_member =
119117
if let Err(_) | Ok(false) = event.user().is_team_member(&ctx.github).await {
120118
false

src/handlers/nominate.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,25 @@ impl Handler for NominateHandler {
3030
};
3131

3232
if let Event::Issue(e) = event {
33-
if e.action != github::IssuesAction::Opened {
34-
// skip events other than opening the issue to avoid retriggering commands in the
33+
if !matches!(e.action, github::IssuesAction::Opened | github::IssuesAction::Edited) {
34+
// skip events other than opening or editing the issue to avoid retriggering commands in the
3535
// issue body
3636
return Ok(None);
3737
}
3838
}
3939

4040
let mut input = Input::new(&body, &ctx.username);
41-
match input.parse_command() {
41+
let command = input.parse_command();
42+
43+
if let Some(previous) = event.comment_from() {
44+
let mut prev_input = Input::new(&previous, &ctx.username);
45+
let prev_command = prev_input.parse_command();
46+
if command == prev_command {
47+
return Ok(None);
48+
}
49+
}
50+
51+
match command {
4252
Command::Nominate(Ok(command)) => Ok(Some(command)),
4353
Command::Nominate(Err(err)) => {
4454
return Err(format!(

src/handlers/ping.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,26 @@ impl Handler for PingHandler {
3333
return Ok(None);
3434
};
3535

36-
match event {
37-
Event::Issue(e) => {
38-
if e.action != github::IssuesAction::Opened {
39-
// skip events other than opening the issue to avoid retriggering commands in the
40-
// issue body
41-
return Ok(None);
42-
}
43-
}
44-
Event::IssueComment(e) => {
45-
// Especially on ping commands, which ping tons of folks, this
46-
// is quite noisy.
47-
if e.action != github::IssueCommentAction::Created {
48-
return Ok(None);
49-
}
36+
if let Event::Issue(e) = event {
37+
if !matches!(e.action, github::IssuesAction::Opened | github::IssuesAction::Edited) {
38+
// skip events other than opening or editing the issue to avoid retriggering commands in the
39+
// issue body
40+
return Ok(None);
5041
}
5142
}
5243

5344
let mut input = Input::new(&body, &ctx.username);
54-
match input.parse_command() {
45+
let command = input.parse_command();
46+
47+
if let Some(previous) = event.comment_from() {
48+
let mut prev_input = Input::new(&previous, &ctx.username);
49+
let prev_command = prev_input.parse_command();
50+
if command == prev_command {
51+
return Ok(None);
52+
}
53+
}
54+
55+
match command {
5556
Command::Ping(Ok(command)) => Ok(Some(command)),
5657
Command::Ping(Err(err)) => {
5758
return Err(format!(

src/handlers/prioritize.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,27 @@ impl Handler for PrioritizeHandler {
2525
// not interested in other events
2626
return Ok(None);
2727
};
28+
29+
if let Event::Issue(e) = event {
30+
if !matches!(e.action, github::IssuesAction::Opened | github::IssuesAction::Edited) {
31+
// skip events other than opening or editing the issue to avoid retriggering commands in the
32+
// issue body
33+
return Ok(None);
34+
}
35+
}
2836

2937
let mut input = Input::new(&body, &ctx.username);
30-
match input.parse_command() {
38+
let command = input.parse_command();
39+
40+
if let Some(previous) = event.comment_from() {
41+
let mut prev_input = Input::new(&previous, &ctx.username);
42+
let prev_command = prev_input.parse_command();
43+
if command == prev_command {
44+
return Ok(None);
45+
}
46+
}
47+
48+
match command {
3149
Command::Prioritize(Ok(PrioritizeCommand)) => Ok(Some(PrioritizeCommand)),
3250
_ => Ok(None),
3351
}

src/handlers/relabel.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,25 @@ impl Handler for RelabelHandler {
3838
};
3939

4040
if let Event::Issue(e) = event {
41-
if e.action != github::IssuesAction::Opened {
42-
// skip events other than opening the issue to avoid retriggering commands in the
41+
if !matches!(e.action, github::IssuesAction::Opened | github::IssuesAction::Edited) {
42+
// skip events other than opening or editing the issue to avoid retriggering commands in the
4343
// issue body
4444
return Ok(None);
4545
}
4646
}
4747

4848
let mut input = Input::new(&body, &ctx.username);
49-
match input.parse_command() {
49+
let command = input.parse_command();
50+
51+
if let Some(previous) = event.comment_from() {
52+
let mut prev_input = Input::new(&previous, &ctx.username);
53+
let prev_command = prev_input.parse_command();
54+
if command == prev_command {
55+
return Ok(None);
56+
}
57+
}
58+
59+
match command {
5060
Command::Relabel(Ok(command)) => Ok(Some(command)),
5161
Command::Relabel(Err(err)) => {
5262
return Err(format!(

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ pub async fn webhook(
109109
github::IssueCommentAction::Deleted
110110
}
111111
},
112+
changes: payload.changes,
112113
issue: payload.pull_request,
113114
comment: payload.review,
114115
repository: payload.repository,
@@ -125,6 +126,7 @@ pub async fn webhook(
125126
// review comments.
126127
github::Event::IssueComment(github::IssueCommentEvent {
127128
action: payload.action,
129+
changes: payload.changes,
128130
issue: payload.issue,
129131
comment: payload.comment,
130132
repository: payload.repository,

0 commit comments

Comments
 (0)