huskies: merge 1029

This commit is contained in:
dave
2026-05-14 12:53:01 +00:00
parent 0a45805f7b
commit a80d0a497a
4 changed files with 293 additions and 16 deletions
+159
View File
@@ -1155,3 +1155,162 @@ fn display_section_returns_closed_for_new_terminal_variants() {
Some("Closed")
);
}
// -- Story 1029: working tree dirty-files summary in status output -------
/// Initialise a bare-minimum git repo in `dir` with one commit.
fn init_git_repo(dir: &std::path::Path) {
use std::process::Command;
Command::new("git")
.args(["init", "-b", "main"])
.current_dir(dir)
.output()
.unwrap();
Command::new("git")
.args(["config", "user.email", "test@test.com"])
.current_dir(dir)
.output()
.unwrap();
Command::new("git")
.args(["config", "user.name", "Test"])
.current_dir(dir)
.output()
.unwrap();
// Create an initial commit so the repo has a HEAD.
std::fs::write(dir.join("README.md"), "# test").unwrap();
Command::new("git")
.args(["add", "README.md"])
.current_dir(dir)
.output()
.unwrap();
Command::new("git")
.args(["commit", "-m", "init"])
.current_dir(dir)
.output()
.unwrap();
}
#[test]
fn status_shows_working_tree_info_when_coder_has_uncommitted_changes() {
use std::fs;
use tempfile::TempDir;
let tmp = TempDir::new().unwrap();
let project_root = tmp.path();
let story_id = "1029_story_dirty_worktree";
// Set up a fake worktree with committed + uncommitted changes.
let wt_path = project_root
.join(".huskies")
.join("worktrees")
.join(story_id);
fs::create_dir_all(&wt_path).unwrap();
init_git_repo(&wt_path);
// Modify a tracked file (unstaged) and add an untracked file.
fs::write(wt_path.join("README.md"), "# changed").unwrap();
fs::write(wt_path.join("new_feature.rs"), "fn foo() {}").unwrap();
let items = vec![make_item(
story_id,
"Dirty Worktree Story",
Stage::Coding {
claim: None,
plan: Default::default(),
retries: 0,
},
)];
let agents = AgentPool::new_test(3000);
let output = build_status_from_items(project_root, &agents, &items);
assert!(
output.contains("Working tree:"),
"status should show working tree summary when changes exist: {output}"
);
assert!(
output.contains("(uncommitted)"),
"working tree line should say '(uncommitted)': {output}"
);
// Should list the dirty files.
assert!(
output.contains("README.md") || output.contains("new_feature.rs"),
"status should list at least one dirty file: {output}"
);
}
#[test]
fn status_clean_worktree_shows_no_working_tree_line() {
use std::fs;
use tempfile::TempDir;
let tmp = TempDir::new().unwrap();
let project_root = tmp.path();
let story_id = "1029_story_clean_worktree";
// Set up a clean worktree with only committed changes.
let wt_path = project_root
.join(".huskies")
.join("worktrees")
.join(story_id);
fs::create_dir_all(&wt_path).unwrap();
init_git_repo(&wt_path);
let items = vec![make_item(
story_id,
"Clean Worktree Story",
Stage::Coding {
claim: None,
plan: Default::default(),
retries: 0,
},
)];
let agents = AgentPool::new_test(3000);
let output = build_status_from_items(project_root, &agents, &items);
assert!(
!output.contains("Working tree:"),
"status should not show working tree line when working tree is clean: {output}"
);
}
#[test]
fn status_dirty_files_capped_at_twenty_with_overflow_line() {
use std::fs;
use tempfile::TempDir;
let tmp = TempDir::new().unwrap();
let project_root = tmp.path();
let story_id = "1029_story_many_files";
let wt_path = project_root
.join(".huskies")
.join("worktrees")
.join(story_id);
fs::create_dir_all(&wt_path).unwrap();
init_git_repo(&wt_path);
// Create 25 untracked files.
for i in 0..25 {
fs::write(wt_path.join(format!("file_{i:02}.rs")), "fn f() {}").unwrap();
}
let items = vec![make_item(
story_id,
"Many Files Story",
Stage::Coding {
claim: None,
plan: Default::default(),
retries: 0,
},
)];
let agents = AgentPool::new_test(3000);
let output = build_status_from_items(project_root, &agents, &items);
assert!(
output.contains("...and 5 more"),
"overflow line should appear when more than 20 files: {output}"
);
}