storkit: merge 378_story_status_command_shows_work_item_type_story_bug_spike_refactor_next_to_each_item
This commit is contained in:
@@ -16,23 +16,36 @@ pub(super) fn handle_status(ctx: &CommandContext) -> Option<String> {
|
|||||||
|
|
||||||
/// Format a short display label for a work item.
|
/// Format a short display label for a work item.
|
||||||
///
|
///
|
||||||
/// Extracts the leading numeric ID from the file stem (e.g. `"293"` from
|
/// Extracts the leading numeric ID and optional type tag from the file stem
|
||||||
/// `"293_story_register_all_bot_commands"`) and combines it with the human-
|
/// (e.g. `"293"` and `"story"` from `"293_story_register_all_bot_commands"`)
|
||||||
/// readable name from the front matter when available.
|
/// and combines them with the human-readable name from the front matter when
|
||||||
|
/// available. Known types (`story`, `bug`, `spike`, `refactor`) are shown as
|
||||||
|
/// bracketed labels; unknown or missing types are omitted silently.
|
||||||
///
|
///
|
||||||
/// Examples:
|
/// Examples:
|
||||||
/// - `("293_story_foo", Some("Register all bot commands"))` → `"293 — Register all bot commands"`
|
/// - `("293_story_foo", Some("Register all bot commands"))` → `"293 [story] — Register all bot commands"`
|
||||||
/// - `("293_story_foo", None)` → `"293"`
|
/// - `("375_bug_foo", None)` → `"375 [bug]"`
|
||||||
|
/// - `("293_story_foo", None)` → `"293 [story]"`
|
||||||
/// - `("no_number_here", None)` → `"no_number_here"`
|
/// - `("no_number_here", None)` → `"no_number_here"`
|
||||||
pub(super) fn story_short_label(stem: &str, name: Option<&str>) -> String {
|
pub(super) fn story_short_label(stem: &str, name: Option<&str>) -> String {
|
||||||
let number = stem
|
let mut parts = stem.splitn(3, '_');
|
||||||
.split('_')
|
let first = parts.next().unwrap_or(stem);
|
||||||
.next()
|
let (number, type_label) = if !first.is_empty() && first.chars().all(|c| c.is_ascii_digit()) {
|
||||||
.filter(|s| !s.is_empty() && s.chars().all(|c| c.is_ascii_digit()))
|
let t = parts.next().and_then(|t| match t {
|
||||||
.unwrap_or(stem);
|
"story" | "bug" | "spike" | "refactor" => Some(t),
|
||||||
match name {
|
_ => None,
|
||||||
Some(n) => format!("{number} — {n}"),
|
});
|
||||||
|
(first, t)
|
||||||
|
} else {
|
||||||
|
(stem, None)
|
||||||
|
};
|
||||||
|
let prefix = match type_label {
|
||||||
|
Some(t) => format!("{number} [{t}]"),
|
||||||
None => number.to_string(),
|
None => number.to_string(),
|
||||||
|
};
|
||||||
|
match name {
|
||||||
|
Some(n) => format!("{prefix} — {n}"),
|
||||||
|
None => prefix,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,13 +213,13 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn short_label_extracts_number_and_name() {
|
fn short_label_extracts_number_and_name() {
|
||||||
let label = story_short_label("293_story_register_all_bot_commands", Some("Register all bot commands"));
|
let label = story_short_label("293_story_register_all_bot_commands", Some("Register all bot commands"));
|
||||||
assert_eq!(label, "293 — Register all bot commands");
|
assert_eq!(label, "293 [story] — Register all bot commands");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn short_label_number_only_when_no_name() {
|
fn short_label_number_only_when_no_name() {
|
||||||
let label = story_short_label("297_story_improve_bot_status_command_formatting", None);
|
let label = story_short_label("297_story_improve_bot_status_command_formatting", None);
|
||||||
assert_eq!(label, "297");
|
assert_eq!(label, "297 [story]");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -224,6 +237,37 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn short_label_shows_bug_type() {
|
||||||
|
let label = story_short_label("375_bug_default_project_toml", Some("Default project.toml issue"));
|
||||||
|
assert_eq!(label, "375 [bug] — Default project.toml issue");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn short_label_shows_spike_type() {
|
||||||
|
let label = story_short_label("61_spike_filesystem_watcher_architecture", Some("Filesystem watcher architecture"));
|
||||||
|
assert_eq!(label, "61 [spike] — Filesystem watcher architecture");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn short_label_shows_refactor_type() {
|
||||||
|
let label = story_short_label("260_refactor_upgrade_libsqlite3_sys", Some("Upgrade libsqlite3-sys"));
|
||||||
|
assert_eq!(label, "260 [refactor] — Upgrade libsqlite3-sys");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn short_label_omits_unknown_type() {
|
||||||
|
let label = story_short_label("42_task_do_something", Some("Do something"));
|
||||||
|
assert_eq!(label, "42 — Do something");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn short_label_no_type_when_only_id() {
|
||||||
|
// Stem with only a numeric ID and no type segment
|
||||||
|
let label = story_short_label("42", Some("Some item"));
|
||||||
|
assert_eq!(label, "42 — Some item");
|
||||||
|
}
|
||||||
|
|
||||||
// -- build_pipeline_status formatting -----------------------------------
|
// -- build_pipeline_status formatting -----------------------------------
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -248,8 +292,8 @@ mod tests {
|
|||||||
"output must not show full filename stem: {output}"
|
"output must not show full filename stem: {output}"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
output.contains("293 — Register all bot commands"),
|
output.contains("293 [story] — Register all bot commands"),
|
||||||
"output must show number and title: {output}"
|
"output must show number, type, and title: {output}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +332,7 @@ mod tests {
|
|||||||
let output = build_pipeline_status(tmp.path(), &agents);
|
let output = build_pipeline_status(tmp.path(), &agents);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
output.contains("293 — Register all bot commands — $0.29"),
|
output.contains("293 [story] — Register all bot commands — $0.29"),
|
||||||
"output must show cost next to story: {output}"
|
"output must show cost next to story: {output}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -351,7 +395,7 @@ mod tests {
|
|||||||
let output = build_pipeline_status(tmp.path(), &agents);
|
let output = build_pipeline_status(tmp.path(), &agents);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
output.contains("293 — Register all bot commands — $0.29"),
|
output.contains("293 [story] — Register all bot commands — $0.29"),
|
||||||
"output must show aggregated cost: {output}"
|
"output must show aggregated cost: {output}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user