huskies: merge 1244 refactor Deduplicate the worktree module cluster (cleanup/remove/sweep/create/lifecycle share ~60-line clones)
This commit is contained in:
@@ -184,39 +184,11 @@ pub(crate) async fn on_terminal_transition(project_root: &Path, story_id: &str)
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::worktree::test_support::init_git_repo;
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn init_git_repo(dir: &Path) {
|
||||
use crate::git_test_support::git_ok;
|
||||
git_ok(
|
||||
Command::new("git").args(["init"]).current_dir(dir).output(),
|
||||
"git init",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.email", "test@test.com"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.email",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.name", "Test"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.name",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["commit", "--allow-empty", "-m", "init"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git commit",
|
||||
);
|
||||
}
|
||||
|
||||
fn setup_project(tmp: &TempDir) -> PathBuf {
|
||||
let root = tmp.path().join("project");
|
||||
fs::create_dir_all(root.join(".huskies")).unwrap();
|
||||
|
||||
@@ -169,81 +169,11 @@ pub fn format_report(report: &CleanupReport, confirm: bool) -> String {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::config::WatcherConfig;
|
||||
use chrono::Utc;
|
||||
use crate::worktree::test_support::{done_stage, empty_config, init_git_repo};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn init_git_repo(dir: &std::path::Path) {
|
||||
use crate::git_test_support::git_ok;
|
||||
git_ok(
|
||||
Command::new("git").args(["init"]).current_dir(dir).output(),
|
||||
"git init",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.email", "test@test.com"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.email",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.name", "Test"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.name",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["commit", "--allow-empty", "-m", "init"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git commit",
|
||||
);
|
||||
}
|
||||
|
||||
fn empty_config() -> ProjectConfig {
|
||||
ProjectConfig {
|
||||
component: vec![],
|
||||
agent: vec![],
|
||||
watcher: WatcherConfig::default(),
|
||||
disk_watch: Default::default(),
|
||||
default_qa: "server".to_string(),
|
||||
default_coder_model: None,
|
||||
max_coders: None,
|
||||
max_retries: 2,
|
||||
base_branch: None,
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
discord_status_consumer: true,
|
||||
whatsapp_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
crdt_require_token: false,
|
||||
crdt_tokens: Vec::new(),
|
||||
max_mesh_peers: 3,
|
||||
gateway_url: None,
|
||||
gateway_project: None,
|
||||
status_push_enabled: true,
|
||||
merge_failure_block_threshold: 3,
|
||||
gc_min_free_gb: 0,
|
||||
snapshot_interval_ops: 5000,
|
||||
}
|
||||
}
|
||||
|
||||
fn done_stage() -> Stage {
|
||||
Stage::Done {
|
||||
merged_at: Utc::now(),
|
||||
merge_commit: crate::pipeline_state::GitSha("abc123".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
async fn setup_project_with_real_worktree(story_id: &str) -> (TempDir, PathBuf) {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let project_root = tmp.path().join("project");
|
||||
|
||||
@@ -210,72 +210,12 @@ pub(crate) async fn run_shell_command(cmd: &str, cwd: &Path) -> Result<(), Strin
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::config::{ComponentConfig, WatcherConfig};
|
||||
use crate::config::ComponentConfig;
|
||||
use crate::worktree::test_support::{empty_config, init_git_repo};
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn init_git_repo(dir: &Path) {
|
||||
use crate::git_test_support::git_ok;
|
||||
git_ok(
|
||||
Command::new("git").args(["init"]).current_dir(dir).output(),
|
||||
"git init",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.email", "test@test.com"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.email",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.name", "Test"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.name",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["commit", "--allow-empty", "-m", "init"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git commit",
|
||||
);
|
||||
}
|
||||
|
||||
fn empty_config() -> ProjectConfig {
|
||||
ProjectConfig {
|
||||
component: vec![],
|
||||
agent: vec![],
|
||||
watcher: WatcherConfig::default(),
|
||||
disk_watch: Default::default(),
|
||||
default_qa: "server".to_string(),
|
||||
default_coder_model: None,
|
||||
max_coders: None,
|
||||
max_retries: 2,
|
||||
base_branch: None,
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
discord_status_consumer: true,
|
||||
whatsapp_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
crdt_require_token: false,
|
||||
crdt_tokens: Vec::new(),
|
||||
max_mesh_peers: 3,
|
||||
gateway_url: None,
|
||||
gateway_project: None,
|
||||
status_push_enabled: true,
|
||||
merge_failure_block_threshold: 3,
|
||||
gc_min_free_gb: 0,
|
||||
snapshot_interval_ops: 5000,
|
||||
}
|
||||
}
|
||||
|
||||
fn failing_setup_config() -> ProjectConfig {
|
||||
ProjectConfig {
|
||||
component: vec![ComponentConfig {
|
||||
|
||||
@@ -232,38 +232,10 @@ pub fn migrate_slug_paths(project_root: &Path, migrations: &[(String, String)])
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::worktree::test_support::init_git_repo;
|
||||
use std::fs;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn init_git_repo(dir: &Path) {
|
||||
use crate::git_test_support::git_ok;
|
||||
git_ok(
|
||||
Command::new("git").args(["init"]).current_dir(dir).output(),
|
||||
"git init",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.email", "test@test.com"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.email",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.name", "Test"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.name",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["commit", "--allow-empty", "-m", "init"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git commit",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn branch_name_format() {
|
||||
assert_eq!(branch_name("42_my_story"), "feature/story-42_my_story");
|
||||
|
||||
@@ -6,6 +6,10 @@ mod create;
|
||||
mod git;
|
||||
mod remove;
|
||||
mod sweep;
|
||||
/// Shared test fixtures (`init_git_repo`, `empty_config`) reused across the
|
||||
/// worktree module's test suites and the pool worktree-lifecycle tests.
|
||||
#[cfg(test)]
|
||||
pub(crate) mod test_support;
|
||||
|
||||
pub use cleanup::{format_report, run_cleanup};
|
||||
pub use create::create_worktree;
|
||||
|
||||
@@ -68,72 +68,10 @@ pub async fn remove_worktree_by_story_id(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::config::WatcherConfig;
|
||||
use crate::worktree::test_support::{empty_config, init_git_repo};
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn init_git_repo(dir: &std::path::Path) {
|
||||
use crate::git_test_support::git_ok;
|
||||
git_ok(
|
||||
Command::new("git").args(["init"]).current_dir(dir).output(),
|
||||
"git init",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.email", "test@test.com"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.email",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.name", "Test"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.name",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["commit", "--allow-empty", "-m", "init"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git commit",
|
||||
);
|
||||
}
|
||||
|
||||
fn empty_config() -> ProjectConfig {
|
||||
ProjectConfig {
|
||||
component: vec![],
|
||||
agent: vec![],
|
||||
watcher: WatcherConfig::default(),
|
||||
disk_watch: Default::default(),
|
||||
default_qa: "server".to_string(),
|
||||
default_coder_model: None,
|
||||
max_coders: None,
|
||||
max_retries: 2,
|
||||
base_branch: None,
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
discord_status_consumer: true,
|
||||
whatsapp_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
crdt_require_token: false,
|
||||
crdt_tokens: Vec::new(),
|
||||
max_mesh_peers: 3,
|
||||
gateway_url: None,
|
||||
gateway_project: None,
|
||||
status_push_enabled: true,
|
||||
merge_failure_block_threshold: 3,
|
||||
gc_min_free_gb: 0,
|
||||
snapshot_interval_ops: 5000,
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn remove_worktree_by_story_id_returns_err_when_not_found() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
|
||||
@@ -89,82 +89,13 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::config::WatcherConfig;
|
||||
use crate::worktree::test_support::{done_stage, empty_config, init_git_repo};
|
||||
use chrono::Utc;
|
||||
use std::fs;
|
||||
use std::num::NonZeroU32;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn init_git_repo(dir: &Path) {
|
||||
use crate::git_test_support::git_ok;
|
||||
git_ok(
|
||||
Command::new("git").args(["init"]).current_dir(dir).output(),
|
||||
"git init",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.email", "test@test.com"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.email",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.name", "Test"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.name",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["commit", "--allow-empty", "-m", "init"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git commit",
|
||||
);
|
||||
}
|
||||
|
||||
fn empty_config() -> ProjectConfig {
|
||||
ProjectConfig {
|
||||
component: vec![],
|
||||
agent: vec![],
|
||||
watcher: WatcherConfig::default(),
|
||||
disk_watch: Default::default(),
|
||||
default_qa: "server".to_string(),
|
||||
default_coder_model: None,
|
||||
max_coders: None,
|
||||
max_retries: 2,
|
||||
base_branch: None,
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
discord_status_consumer: true,
|
||||
whatsapp_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
crdt_require_token: false,
|
||||
crdt_tokens: Vec::new(),
|
||||
max_mesh_peers: 3,
|
||||
gateway_url: None,
|
||||
gateway_project: None,
|
||||
status_push_enabled: true,
|
||||
merge_failure_block_threshold: 3,
|
||||
gc_min_free_gb: 0,
|
||||
snapshot_interval_ops: 5000,
|
||||
}
|
||||
}
|
||||
|
||||
fn done_stage() -> Stage {
|
||||
Stage::Done {
|
||||
merged_at: Utc::now(),
|
||||
merge_commit: crate::pipeline_state::GitSha("abc123".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn archived_stage() -> Stage {
|
||||
Stage::Archived {
|
||||
archived_at: Utc::now(),
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
//! Shared test fixtures for worktree module tests: a throwaway git repo and a
|
||||
//! minimal [`ProjectConfig`] with no components, used by the worktree
|
||||
//! create/remove/cleanup/sweep tests and the pool worktree-lifecycle
|
||||
//! subscriber tests so each doesn't hand-roll its own copy.
|
||||
|
||||
use crate::config::{ProjectConfig, WatcherConfig};
|
||||
use crate::git_test_support::git_ok;
|
||||
use crate::pipeline_state::{GitSha, Stage};
|
||||
use chrono::Utc;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
/// Initialize a git repo at `dir` with test identity configured and a
|
||||
/// committed empty initial commit, so worktree creation has a valid base
|
||||
/// branch to fork from.
|
||||
pub(crate) fn init_git_repo(dir: &Path) {
|
||||
git_ok(
|
||||
Command::new("git").args(["init"]).current_dir(dir).output(),
|
||||
"git init",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.email", "test@test.com"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.email",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["config", "user.name", "Test"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git config user.name",
|
||||
);
|
||||
git_ok(
|
||||
Command::new("git")
|
||||
.args(["commit", "--allow-empty", "-m", "init"])
|
||||
.current_dir(dir)
|
||||
.output(),
|
||||
"git commit",
|
||||
);
|
||||
}
|
||||
|
||||
/// A minimal [`ProjectConfig`] with no components, suitable for worktree
|
||||
/// tests that don't exercise setup/teardown commands.
|
||||
pub(crate) fn empty_config() -> ProjectConfig {
|
||||
ProjectConfig {
|
||||
component: vec![],
|
||||
agent: vec![],
|
||||
watcher: WatcherConfig::default(),
|
||||
disk_watch: Default::default(),
|
||||
default_qa: "server".to_string(),
|
||||
default_coder_model: None,
|
||||
max_coders: None,
|
||||
max_retries: 2,
|
||||
base_branch: None,
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
discord_status_consumer: true,
|
||||
whatsapp_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
crdt_require_token: false,
|
||||
crdt_tokens: Vec::new(),
|
||||
max_mesh_peers: 3,
|
||||
gateway_url: None,
|
||||
gateway_project: None,
|
||||
status_push_enabled: true,
|
||||
merge_failure_block_threshold: 3,
|
||||
gc_min_free_gb: 0,
|
||||
snapshot_interval_ops: 5000,
|
||||
}
|
||||
}
|
||||
|
||||
/// A `Stage::Done` fixture for tests that need a terminal-stage story.
|
||||
pub(crate) fn done_stage() -> Stage {
|
||||
Stage::Done {
|
||||
merged_at: Utc::now(),
|
||||
merge_commit: GitSha("abc123".to_string()),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user