Skip to content

Commit cf06277

Browse files
committed
implement the ready & author shortcuts to swap waiting-on labels
1 parent 6231db5 commit cf06277

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

src/handlers.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ mod ping;
3737
mod prioritize;
3838
mod relabel;
3939
mod rustc_commits;
40+
mod shortcut;
4041

4142
pub async fn handle(ctx: &Context, event: &Event) -> Vec<HandlerError> {
4243
let config = config::get(&ctx.github, event.repo_name()).await;
@@ -225,6 +226,7 @@ command_handlers! {
225226
prioritize: Prioritize,
226227
relabel: Relabel,
227228
major_change: Second,
229+
shortcut: Shortcut,
228230
close: Close,
229231
}
230232

src/handlers/shortcut.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//! Purpose: Allow the use of single words shortcut to do specific actions on GitHub via comments.
2+
//!
3+
//! Parsing is done in the `parser::command::shortcut` module.
4+
5+
use crate::{
6+
config::ShortcutConfig,
7+
github::{Event, Label},
8+
handlers::Context,
9+
interactions::ErrorComment,
10+
};
11+
use parser::command::shortcut::ShortcutCommand;
12+
13+
pub(super) async fn handle_command(
14+
ctx: &Context,
15+
_config: &ShortcutConfig,
16+
event: &Event,
17+
input: ShortcutCommand,
18+
) -> anyhow::Result<()> {
19+
let issue = event.issue().unwrap();
20+
// NOTE: if shortcuts available to issues are created, they need to be allowed here
21+
if !issue.is_pr() {
22+
let msg = format!("The \"{:?}\" shortcut only works on pull requests.", input);
23+
let cmnt = ErrorComment::new(&issue, msg);
24+
cmnt.post(&ctx.github).await?;
25+
return Ok(());
26+
}
27+
28+
let mut issue_labels = issue.labels().to_owned();
29+
let waiting_on_review = "S-waiting-on-review";
30+
let waiting_on_author = "S-waiting-on-author";
31+
32+
match input {
33+
ShortcutCommand::Ready => {
34+
if assign_and_remove_label(&mut issue_labels, waiting_on_review, waiting_on_author)
35+
.is_some()
36+
{
37+
return Ok(());
38+
}
39+
issue.set_labels(&ctx.github, issue_labels).await?;
40+
}
41+
ShortcutCommand::Author => {
42+
if assign_and_remove_label(&mut issue_labels, waiting_on_author, waiting_on_review)
43+
.is_some()
44+
{
45+
return Ok(());
46+
}
47+
issue.set_labels(&ctx.github, issue_labels).await?;
48+
}
49+
}
50+
51+
Ok(())
52+
}
53+
54+
fn assign_and_remove_label(
55+
issue_labels: &mut Vec<Label>,
56+
assign: &str,
57+
remove: &str,
58+
) -> Option<()> {
59+
if issue_labels.iter().any(|label| label.name == assign) {
60+
return Some(());
61+
}
62+
63+
if let Some(index) = issue_labels.iter().position(|label| label.name == remove) {
64+
issue_labels.swap_remove(index);
65+
}
66+
67+
issue_labels.push(Label {
68+
name: assign.into(),
69+
});
70+
71+
None
72+
}
73+
74+
#[cfg(test)]
75+
mod tests {
76+
77+
use super::{assign_and_remove_label, Label};
78+
fn create_labels(names: Vec<&str>) -> Vec<Label> {
79+
names
80+
.into_iter()
81+
.map(|name| Label { name: name.into() })
82+
.collect()
83+
}
84+
85+
#[test]
86+
fn test_adds_without_labels() {
87+
let expected = create_labels(vec!["assign"]);
88+
let mut labels = vec![];
89+
assert!(assign_and_remove_label(&mut labels, "assign", "remove").is_none());
90+
assert_eq!(labels, expected);
91+
}
92+
93+
#[test]
94+
fn test_do_nothing_with_label_already_set() {
95+
let expected = create_labels(vec!["assign"]);
96+
let mut labels = create_labels(vec!["assign"]);
97+
assert!(assign_and_remove_label(&mut labels, "assign", "remove").is_some());
98+
assert_eq!(labels, expected);
99+
}
100+
101+
#[test]
102+
fn test_other_labels_untouched() {
103+
let expected = create_labels(vec!["bug", "documentation", "assign"]);
104+
let mut labels = create_labels(vec!["bug", "documentation"]);
105+
assert!(assign_and_remove_label(&mut labels, "assign", "remove").is_none());
106+
assert_eq!(labels, expected);
107+
}
108+
109+
#[test]
110+
fn test_correctly_remove_label() {
111+
let expected = create_labels(vec!["bug", "documentation", "assign"]);
112+
let mut labels = create_labels(vec!["bug", "documentation", "remove"]);
113+
assert!(assign_and_remove_label(&mut labels, "assign", "remove").is_none());
114+
assert_eq!(labels, expected);
115+
}
116+
}

0 commit comments

Comments
 (0)