Skip to content

Commit 92f67b0

Browse files
Mauricio Cassolajoulei
authored andcommitted
Parse and handle team in command
* Parse team in command * Use parsed team in handler
1 parent 130c25a commit 92f67b0

File tree

2 files changed

+158
-81
lines changed

2 files changed

+158
-81
lines changed

parser/src/command/decision.rs

Lines changed: 73 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,40 +21,65 @@ use serde::{Deserialize, Serialize};
2121
pub struct DecisionCommand {
2222
pub resolution: Resolution,
2323
pub reversibility: Reversibility,
24+
pub team: Option<String>,
2425
}
2526

2627
impl DecisionCommand {
2728
pub fn parse<'a>(input: &mut Tokenizer<'a>) -> Result<Option<Self>, Error<'a>> {
2829
let mut toks = input.clone();
2930

3031
match toks.peek_token()? {
31-
Some(Token::Word("merge")) => command_or_error(
32-
input,
33-
&mut toks,
34-
Self {
35-
resolution: Resolution::Merge,
36-
reversibility: Reversibility::Reversible,
37-
},
38-
),
39-
Some(Token::Word("hold")) => command_or_error(
40-
input,
41-
&mut toks,
42-
Self {
43-
resolution: Resolution::Hold,
44-
reversibility: Reversibility::Reversible,
45-
},
46-
),
32+
Some(Token::Word("merge")) => {
33+
toks.next_token()?;
34+
35+
let team: Option<String> = get_team(&mut toks)?;
36+
37+
command_or_error(
38+
input,
39+
&mut toks,
40+
Self {
41+
resolution: Resolution::Merge,
42+
reversibility: Reversibility::Reversible,
43+
team,
44+
},
45+
)
46+
}
47+
Some(Token::Word("hold")) => {
48+
toks.next_token()?;
49+
50+
let team: Option<String> = get_team(&mut toks)?;
51+
52+
command_or_error(
53+
input,
54+
&mut toks,
55+
Self {
56+
resolution: Resolution::Hold,
57+
reversibility: Reversibility::Reversible,
58+
team,
59+
},
60+
)
61+
}
4762
_ => Ok(None),
4863
}
4964
}
5065
}
5166

67+
fn get_team<'a>(toks: &mut Tokenizer<'a>) -> Result<Option<String>, Error<'a>> {
68+
match toks.peek_token()? {
69+
Some(Token::Word(team)) => {
70+
toks.next_token()?;
71+
72+
Ok(Some(team.to_string()))
73+
}
74+
_ => Ok(None),
75+
}
76+
}
77+
5278
fn command_or_error<'a>(
5379
input: &mut Tokenizer<'a>,
5480
toks: &mut Tokenizer<'a>,
5581
command: DecisionCommand,
5682
) -> Result<Option<DecisionCommand>, Error<'a>> {
57-
toks.next_token()?;
5883
if let Some(Token::Dot) | Some(Token::EndOfLine) = toks.peek_token()? {
5984
*input = toks.clone();
6085
Ok(Some(command))
@@ -120,7 +145,8 @@ mod tests {
120145
parse("merge"),
121146
Ok(Some(DecisionCommand {
122147
resolution: Resolution::Merge,
123-
reversibility: Reversibility::Reversible
148+
reversibility: Reversibility::Reversible,
149+
team: None
124150
})),
125151
);
126152
}
@@ -131,7 +157,8 @@ mod tests {
131157
parse("merge."),
132158
Ok(Some(DecisionCommand {
133159
resolution: Resolution::Merge,
134-
reversibility: Reversibility::Reversible
160+
reversibility: Reversibility::Reversible,
161+
team: None
135162
})),
136163
);
137164
}
@@ -142,7 +169,8 @@ mod tests {
142169
parse("hold"),
143170
Ok(Some(DecisionCommand {
144171
resolution: Resolution::Hold,
145-
reversibility: Reversibility::Reversible
172+
reversibility: Reversibility::Reversible,
173+
team: None
146174
})),
147175
);
148176
}
@@ -151,12 +179,36 @@ mod tests {
151179
fn test_expected_end() {
152180
use std::error::Error;
153181
assert_eq!(
154-
parse("hold my beer")
182+
parse("hold lang beer")
155183
.unwrap_err()
156184
.source()
157185
.unwrap()
158186
.downcast_ref(),
159187
Some(&ParseError::ExpectedEnd),
160188
);
161189
}
190+
191+
#[test]
192+
fn test_correct_merge_with_team() {
193+
assert_eq!(
194+
parse("merge lang"),
195+
Ok(Some(DecisionCommand {
196+
resolution: Resolution::Merge,
197+
reversibility: Reversibility::Reversible,
198+
team: Some("lang".to_string())
199+
})),
200+
);
201+
}
202+
203+
#[test]
204+
fn test_correct_hold_with_team() {
205+
assert_eq!(
206+
parse("hold lang"),
207+
Ok(Some(DecisionCommand {
208+
resolution: Resolution::Hold,
209+
reversibility: Reversibility::Reversible,
210+
team: Some("lang".to_string())
211+
})),
212+
);
213+
}
162214
}

src/handlers/decision.rs

Lines changed: 85 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub(super) async fn handle_command(
3131
let DecisionCommand {
3232
resolution,
3333
reversibility,
34+
team: team_name,
3435
} = cmd;
3536

3637
let issue = event.issue().unwrap();
@@ -59,67 +60,91 @@ pub(super) async fn handle_command(
5960
Ok(())
6061
}
6162
_ => {
62-
let start_date: DateTime<Utc> = chrono::Utc::now().into();
63-
let end_date: DateTime<Utc> =
64-
start_date.checked_add_signed(Duration::days(10)).unwrap();
65-
66-
let mut current: BTreeMap<String, Option<UserStatus>> = BTreeMap::new();
67-
let mut history: BTreeMap<String, Vec<UserStatus>> = BTreeMap::new();
68-
69-
// TODO
70-
// change this to be entered by the user as part of the command
71-
// it should match the same team that we check for above when determining if the user is a member
72-
let team = github::get_team(&ctx.github, &"T-lang").await?.unwrap();
73-
for member in team.members {
74-
current.insert(member.name.clone(), None);
75-
history.insert(member.name.clone(), Vec::new());
63+
match team_name {
64+
None => {
65+
let cmnt = ErrorComment::new(
66+
&issue,
67+
"In the first vote, is necessary to specify the team name that will be involved in the decision process.",
68+
);
69+
cmnt.post(&ctx.github).await?;
70+
71+
Ok(())
72+
}
73+
Some(team_name) => {
74+
match github::get_team(&ctx.github, &team_name).await {
75+
Ok(Some(team)) => {
76+
let start_date: DateTime<Utc> = chrono::Utc::now().into();
77+
let end_date: DateTime<Utc> =
78+
start_date.checked_add_signed(Duration::days(10)).unwrap();
79+
80+
let mut current: BTreeMap<String, Option<UserStatus>> = BTreeMap::new();
81+
let mut history: BTreeMap<String, Vec<UserStatus>> = BTreeMap::new();
82+
83+
// Add team members to current and history
84+
for member in team.members {
85+
current.insert(member.github.clone(), None);
86+
history.insert(member.github.clone(), Vec::new());
87+
}
88+
89+
// Add issue user to current and history
90+
current.insert(
91+
user.login.clone(),
92+
Some(UserStatus {
93+
comment_id: event.html_url().unwrap().to_string(),
94+
text: event.comment_body().unwrap().to_string(),
95+
reversibility: reversibility,
96+
resolution: resolution,
97+
}),
98+
);
99+
history.insert(user.login.clone(), Vec::new());
100+
101+
// Initialize issue decision state
102+
insert_issue_decision_state(
103+
&db,
104+
&issue.number,
105+
&user.login,
106+
&start_date,
107+
&end_date,
108+
&current,
109+
&history,
110+
&reversibility,
111+
&resolution,
112+
)
113+
.await?;
114+
115+
// TO DO -- Do not insert this job until we support more votes
116+
// let metadata = serde_json::value::to_value(DecisionProcessActionMetadata {
117+
// message: "some message".to_string(),
118+
// get_issue_url: format!("{}/issues/{}", issue.repository().url(), issue.number),
119+
// status: resolution,
120+
// })
121+
// .unwrap();
122+
// insert_job(
123+
// &db,
124+
// &DECISION_PROCESS_JOB_NAME.to_string(),
125+
// &end_date,
126+
// &metadata,
127+
// )
128+
// .await?;
129+
130+
let comment = build_status_comment(&history, &current)?;
131+
issue
132+
.post_comment(&ctx.github, &comment)
133+
.await
134+
.context("merge vote comment")?;
135+
136+
Ok(())
137+
}
138+
_ => {
139+
let cmnt =
140+
ErrorComment::new(&issue, "Failed to resolve to a known team.");
141+
cmnt.post(&ctx.github).await?;
142+
143+
Ok(())
144+
}
145+
}
146+
}
76147
}
77-
78-
current.insert(
79-
user.login.clone(),
80-
Some(UserStatus {
81-
comment_id: "comment_id".to_string(),
82-
text: "something".to_string(),
83-
reversibility: reversibility,
84-
resolution: resolution,
85-
}),
86-
);
87-
88-
insert_issue_decision_state(
89-
&db,
90-
&issue.number,
91-
&user.login,
92-
&start_date,
93-
&end_date,
94-
&current,
95-
&history,
96-
&reversibility,
97-
&resolution,
98-
)
99-
.await?;
100-
101-
// TO DO -- Do not insert this job until we support more votes
102-
// let metadata = serde_json::value::to_value(DecisionProcessActionMetadata {
103-
// message: "some message".to_string(),
104-
// get_issue_url: format!("{}/issues/{}", issue.repository().url(), issue.number),
105-
// status: resolution,
106-
// })
107-
// .unwrap();
108-
// insert_job(
109-
// &db,
110-
// &DECISION_PROCESS_JOB_NAME.to_string(),
111-
// &end_date,
112-
// &metadata,
113-
// )
114-
// .await?;
115-
116-
let comment = build_status_comment(&history, &current)?;
117-
issue
118-
.post_comment(&ctx.github, &comment)
119-
.await
120-
.context("merge vote comment")?;
121-
122-
Ok(())
123148
}
124149
}
125150
}

0 commit comments

Comments
 (0)