-
Notifications
You must be signed in to change notification settings - Fork 21
feat: add recruit command #474
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey - 我发现了两个问题,并给出了一些高层次的反馈:
into_parameters_no_context中对extra_tags_mode的手动校验可以移动到 clap 的定义中(例如value_parser = clap::value_parser!(i32).range(0..=2)),这样无效值会在解析阶段就被拒绝,而不是在转换阶段才发现。- 在
recruitment_time的解析循环中,建议使用splitn(2, '='),并返回更结构化的错误信息(包含 level 和 minutes 部分),以便更容易调试格式错误的输入,并避免当=出现多于一次时产生意料之外的行为。
给 AI Agent 的提示
Please address the comments from this code review:
## Overall Comments
- The manual validation of `extra_tags_mode` in `into_parameters_no_context` could be shifted into the clap definition (e.g., `value_parser = clap::value_parser!(i32).range(0..=2)`) so invalid values are rejected at parse time rather than at conversion.
- In the `recruitment_time` parsing loop, consider using `splitn(2, '=')` and a more structured error message (including the level and minutes parts) to make debugging malformed inputs easier and avoid surprises if `=` appears more than once.
## Individual Comments
### Comment 1
<location> `crates/maa-cli/src/run/preset/recruit.rs:134-146` </location>
<code_context>
+ params.insert("extra_tags_mode", self.extra_tags_mode);
+
+ // Times
+ params.insert("times", self.times);
+
+ // Set time only when times is 0
</code_context>
<issue_to_address>
**suggestion:** 考虑在将 `times` 插入参数之前,先校验它是否为非负数。
目前任何 `i32` 都会被接受(包括 `--times=-1`),这很可能是无效的,并可能导致下游行为令人困惑。可以加一个简单的检查,比如 `if self.times < 0 { bail!("times must be non-negative") }`,以便在遇到错误输入时尽早失败。
```suggestion
// Extra tags mode validation
if !(0..=2).contains(&self.extra_tags_mode) {
bail!("extra_tags_mode must be between 0 and 2");
}
params.insert("extra_tags_mode", self.extra_tags_mode);
// Times validation
if self.times < 0 {
bail!("times must be non-negative");
}
// Times
params.insert("times", self.times);
// Set time only when times is 0
if self.times == 0 {
params.insert("set_time", self.set_time);
}
```
</issue_to_address>
### Comment 2
<location> `crates/maa-cli/src/run/preset/recruit.rs:160-165` </location>
<code_context>
+ if !self.recruitment_time.is_empty() {
+ let mut time_map = std::collections::BTreeMap::new();
+
+ for time_spec in self.recruitment_time {
+ let mut parts = time_spec.split('=');
+ let level = parts.next();
+ let minutes = parts.next();
+
+ match (level, minutes) {
+ (Some(level), Some(minutes)) => {
+ let level_str = level.to_owned();
</code_context>
<issue_to_address>
**suggestion (bug_risk):** `recruitment_time` 解析器会静默忽略多余的 `=` 片段;建议显式拒绝这种格式错误的参数。
由于这里使用的是 `split('=')`,但只读取了两个元素,对类似 `--recruitment-time=3=540=foo` 的输入,解析结果是 `level="3"`、`minutes="540"`,而尾部的 `"foo"` 会被忽略。如果这不是期望的行为,建议在读取完 `level` 和 `minutes` 后检查 `parts.next().is_none()`,否则就返回错误,使格式错误的参数能尽早失败,而不是被部分接受。
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据这些反馈来改进评审质量。
Original comment in English
Hey - I've found 2 issues, and left some high level feedback:
- The manual validation of
extra_tags_modeininto_parameters_no_contextcould be shifted into the clap definition (e.g.,value_parser = clap::value_parser!(i32).range(0..=2)) so invalid values are rejected at parse time rather than at conversion. - In the
recruitment_timeparsing loop, consider usingsplitn(2, '=')and a more structured error message (including the level and minutes parts) to make debugging malformed inputs easier and avoid surprises if=appears more than once.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The manual validation of `extra_tags_mode` in `into_parameters_no_context` could be shifted into the clap definition (e.g., `value_parser = clap::value_parser!(i32).range(0..=2)`) so invalid values are rejected at parse time rather than at conversion.
- In the `recruitment_time` parsing loop, consider using `splitn(2, '=')` and a more structured error message (including the level and minutes parts) to make debugging malformed inputs easier and avoid surprises if `=` appears more than once.
## Individual Comments
### Comment 1
<location> `crates/maa-cli/src/run/preset/recruit.rs:134-146` </location>
<code_context>
+ params.insert("extra_tags_mode", self.extra_tags_mode);
+
+ // Times
+ params.insert("times", self.times);
+
+ // Set time only when times is 0
</code_context>
<issue_to_address>
**suggestion:** Consider validating that `times` is non-negative before inserting it into parameters.
Currently any `i32` is accepted (including `--times=-1`), which is probably invalid and may lead to confusing downstream behavior. A small check like `if self.times < 0 { bail!("times must be non-negative") }` would fail fast on bad input.
```suggestion
// Extra tags mode validation
if !(0..=2).contains(&self.extra_tags_mode) {
bail!("extra_tags_mode must be between 0 and 2");
}
params.insert("extra_tags_mode", self.extra_tags_mode);
// Times validation
if self.times < 0 {
bail!("times must be non-negative");
}
// Times
params.insert("times", self.times);
// Set time only when times is 0
if self.times == 0 {
params.insert("set_time", self.set_time);
}
```
</issue_to_address>
### Comment 2
<location> `crates/maa-cli/src/run/preset/recruit.rs:160-165` </location>
<code_context>
+ if !self.recruitment_time.is_empty() {
+ let mut time_map = std::collections::BTreeMap::new();
+
+ for time_spec in self.recruitment_time {
+ let mut parts = time_spec.split('=');
+ let level = parts.next();
+ let minutes = parts.next();
+
+ match (level, minutes) {
+ (Some(level), Some(minutes)) => {
+ let level_str = level.to_owned();
</code_context>
<issue_to_address>
**suggestion (bug_risk):** The `recruitment_time` parser silently ignores extra `=` segments; consider rejecting malformed specs explicitly.
Because you call `split('=')` and only read two elements, an input like `--recruitment-time=3=540=foo` is parsed as `level="3"`, `minutes="540"` and the trailing `"foo"` is ignored. If that’s not desired, consider checking `parts.next().is_none()` after reading `level` and `minutes` and returning an error otherwise, so malformed specs fail fast instead of being partially accepted.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| // Extra tags mode validation | ||
| if !(0..=2).contains(&self.extra_tags_mode) { | ||
| bail!("extra_tags_mode must be between 0 and 2"); | ||
| } | ||
| params.insert("extra_tags_mode", self.extra_tags_mode); | ||
|
|
||
| // Times | ||
| params.insert("times", self.times); | ||
|
|
||
| // Set time only when times is 0 | ||
| if self.times == 0 { | ||
| params.insert("set_time", self.set_time); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: 考虑在将 times 插入参数之前,先校验它是否为非负数。
目前任何 i32 都会被接受(包括 --times=-1),这很可能是无效的,并可能导致下游行为令人困惑。可以加一个简单的检查,比如 if self.times < 0 { bail!("times must be non-negative") },以便在遇到错误输入时尽早失败。
| // Extra tags mode validation | |
| if !(0..=2).contains(&self.extra_tags_mode) { | |
| bail!("extra_tags_mode must be between 0 and 2"); | |
| } | |
| params.insert("extra_tags_mode", self.extra_tags_mode); | |
| // Times | |
| params.insert("times", self.times); | |
| // Set time only when times is 0 | |
| if self.times == 0 { | |
| params.insert("set_time", self.set_time); | |
| } | |
| // Extra tags mode validation | |
| if !(0..=2).contains(&self.extra_tags_mode) { | |
| bail!("extra_tags_mode must be between 0 and 2"); | |
| } | |
| params.insert("extra_tags_mode", self.extra_tags_mode); | |
| // Times validation | |
| if self.times < 0 { | |
| bail!("times must be non-negative"); | |
| } | |
| // Times | |
| params.insert("times", self.times); | |
| // Set time only when times is 0 | |
| if self.times == 0 { | |
| params.insert("set_time", self.set_time); | |
| } |
Original comment in English
suggestion: Consider validating that times is non-negative before inserting it into parameters.
Currently any i32 is accepted (including --times=-1), which is probably invalid and may lead to confusing downstream behavior. A small check like if self.times < 0 { bail!("times must be non-negative") } would fail fast on bad input.
| // Extra tags mode validation | |
| if !(0..=2).contains(&self.extra_tags_mode) { | |
| bail!("extra_tags_mode must be between 0 and 2"); | |
| } | |
| params.insert("extra_tags_mode", self.extra_tags_mode); | |
| // Times | |
| params.insert("times", self.times); | |
| // Set time only when times is 0 | |
| if self.times == 0 { | |
| params.insert("set_time", self.set_time); | |
| } | |
| // Extra tags mode validation | |
| if !(0..=2).contains(&self.extra_tags_mode) { | |
| bail!("extra_tags_mode must be between 0 and 2"); | |
| } | |
| params.insert("extra_tags_mode", self.extra_tags_mode); | |
| // Times validation | |
| if self.times < 0 { | |
| bail!("times must be non-negative"); | |
| } | |
| // Times | |
| params.insert("times", self.times); | |
| // Set time only when times is 0 | |
| if self.times == 0 { | |
| params.insert("set_time", self.set_time); | |
| } |
| for time_spec in self.recruitment_time { | ||
| let mut parts = time_spec.split('='); | ||
| let level = parts.next(); | ||
| let minutes = parts.next(); | ||
|
|
||
| match (level, minutes) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): recruitment_time 解析器会静默忽略多余的 = 片段;建议显式拒绝这种格式错误的参数。
由于这里使用的是 split('='),但只读取了两个元素,对类似 --recruitment-time=3=540=foo 的输入,解析结果是 level="3"、minutes="540",而尾部的 "foo" 会被忽略。如果这不是期望的行为,建议在读取完 level 和 minutes 后检查 parts.next().is_none(),否则就返回错误,使格式错误的参数能尽早失败,而不是被部分接受。
Original comment in English
suggestion (bug_risk): The recruitment_time parser silently ignores extra = segments; consider rejecting malformed specs explicitly.
Because you call split('=') and only read two elements, an input like --recruitment-time=3=540=foo is parsed as level="3", minutes="540" and the trailing "foo" is ignored. If that’s not desired, consider checking parts.next().is_none() after reading level and minutes and returning an error otherwise, so malformed specs fail fast instead of being partially accepted.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #474 +/- ##
==========================================
+ Coverage 69.40% 69.66% +0.26%
==========================================
Files 56 57 +1
Lines 5608 5670 +62
Branches 5608 5670 +62
==========================================
+ Hits 3892 3950 +58
- Misses 1425 1428 +3
- Partials 291 292 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Summary by Sourcery
在 CLI 中新增一个
recruit预设命令,用于配置和运行招募任务,并提供丰富的标签配置和报表选项。新功能:
RecruitCLI 子命令,通过通用的预设运行器来执行招募任务。RecruitParams预设配置,支持标签选择/确认、优先标签、额外标签选择模式、运行次数、时间限制、加急许可以及服务器选择。测试:
recruit命令新增全面的 CLI 解析测试,覆盖正常流程、参数组合以及校验错误等情况。Original summary in English
Summary by Sourcery
Add a new
recruitpreset command to the CLI for configuring and running recruitment tasks with rich tagging and reporting options.New Features:
RecruitCLI subcommand wired into the main command dispatcher to run recruitment tasks via the generic preset runner.RecruitParamspreset configuration supporting tag selection/confirmation, preferred tags, extra tag selection modes, run count, time limits, expedited permits, and server selection.Tests:
recruitcommand covering normal flows, parameter combinations, and validation error cases.