feat: hide done tasks by default in backlog show
Done tasks are hidden by default. Pass --done to show only done tasks.
Works with both human and JSON output formats.
diff --git a/src/bin/ranger/commands/backlog.rs b/src/bin/ranger/commands/backlog.rs
index 2d151b9..086244b 100644
--- a/src/bin/ranger/commands/backlog.rs
+++ b/src/bin/ranger/commands/backlog.rs
@@ -25,6 +25,10 @@ pub enum BacklogCommands {
/// Backlog name
#[arg(env = "RANGER_DEFAULT_BACKLOG")]
name: String,
+
+ /// Show only done tasks
+ #[arg(long)]
+ done: bool,
},
/// Rebalance task positions in a backlog
Rebalance {
@@ -51,12 +55,18 @@ pub async fn run(pool: &SqlitePool, command: BacklogCommands, json: bool) -> Res
let count = ops::task::rebalance(&mut conn, backlog.id).await?;
println!("Rebalanced {count} tasks in {name}");
}
- BacklogCommands::Show { name } => {
+ BacklogCommands::Show { name, done } => {
let backlog = ops::backlog::get_by_name(&mut conn, &name).await?;
+ let states: Vec<State> = if done {
+ vec![State::Done]
+ } else {
+ vec![State::InProgress, State::Queued, State::Icebox]
+ };
+
if json {
let mut state_groups = serde_json::Map::new();
- for state in [State::Done, State::InProgress, State::Queued, State::Icebox] {
+ for state in &states {
let filter = ListFilter {
state: Some(state.clone()),
..Default::default()
@@ -78,7 +88,7 @@ pub async fn run(pool: &SqlitePool, command: BacklogCommands, json: bool) -> Res
print_backlog_detail(&backlog);
- for state in [State::Done, State::InProgress, State::Queued, State::Icebox] {
+ for state in &states {
let filter = ListFilter {
state: Some(state.clone()),
..Default::default()
diff --git a/src/bin/ranger/main.rs b/src/bin/ranger/main.rs
index eb9772c..eb990ca 100644
--- a/src/bin/ranger/main.rs
+++ b/src/bin/ranger/main.rs
@@ -105,7 +105,7 @@ async fn main() -> color_eyre::Result<()> {
let backlog_name = std::env::var("RANGER_DEFAULT_BACKLOG").ok();
match backlog_name {
Some(name) => {
- let show_cmd = commands::backlog::BacklogCommands::Show { name };
+ let show_cmd = commands::backlog::BacklogCommands::Show { name, done: false };
commands::backlog::run(&pool, show_cmd, cli.json).await?;
}
None => {
diff --git a/tests/cli.rs b/tests/cli.rs
index 09d3d5d..f7b27ce 100644
--- a/tests/cli.rs
+++ b/tests/cli.rs
@@ -278,6 +278,69 @@ fn full_workflow() {
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("Ranger"));
+ // Mark a task as done for the --done test
+ let output = ranger(db_path)
+ .args(["task", "edit", &t1_key[..4], "--state", "done"])
+ .output()
+ .unwrap();
+ assert!(output.status.success());
+
+ // Backlog show hides done tasks by default
+ let output = ranger(db_path).args(["backlog", "show"]).output().unwrap();
+ assert!(output.status.success());
+ let stdout = String::from_utf8(output.stdout).unwrap();
+ assert!(
+ !stdout.contains("[done]"),
+ "should not show done section by default"
+ );
+
+ // Backlog show --done shows only done tasks
+ let output = ranger(db_path)
+ .args(["backlog", "show", "--done"])
+ .output()
+ .unwrap();
+ assert!(output.status.success());
+ let stdout = String::from_utf8(output.stdout).unwrap();
+ assert!(
+ stdout.contains("[done]"),
+ "should show done section with --done"
+ );
+ assert!(
+ !stdout.contains("[in_progress]"),
+ "--done should not show in_progress"
+ );
+ assert!(
+ !stdout.contains("[queued]"),
+ "--done should not show queued"
+ );
+ assert!(
+ !stdout.contains("[icebox]"),
+ "--done should not show icebox"
+ );
+
+ // Backlog show --done with JSON shows only done tasks
+ let output = ranger(db_path)
+ .args(["backlog", "show", "--done", "--json"])
+ .output()
+ .unwrap();
+ assert!(output.status.success());
+ let detail: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
+ assert!(detail["tasks"]["done"].is_array());
+ assert!(detail["tasks"]["queued"].is_null());
+ assert!(detail["tasks"]["in_progress"].is_null());
+
+ // Backlog show JSON without --done excludes done tasks
+ let output = ranger(db_path)
+ .args(["backlog", "show", "--json"])
+ .output()
+ .unwrap();
+ assert!(output.status.success());
+ let detail: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
+ assert!(
+ detail["tasks"]["done"].is_null(),
+ "JSON should exclude done without --done"
+ );
+
// Shell completions (no DB needed, but pass one anyway for the helper)
for shell in ["bash", "zsh", "fish", "elvish", "powershell"] {
let output = ranger(db_path)