use crate::api::schema::{ WorktreeCreateParams, WorktreeListParams, WorktreeOpenParams, WorktreeRemoveParams, }; // Worktree output is always JSON. The parsers retain `--json` as a hidden compatibility no-op. pub(super) fn run_worktree_command(args: &[String]) -> std::io::Result { let Some(subcommand) = args.first().map(|arg| arg.as_str()) else { print_worktree_help(); return Ok(2); }; match subcommand { "list" => worktree_list(&args[1..]), "create" => worktree_create(&args[1..]), "open" => worktree_open(&args[1..]), "remove" => worktree_remove(&args[1..]), "help" | "--help" | "-h" => { print_worktree_help(); Ok(0) } _ => { print_worktree_help(); Ok(2) } } } fn worktree_list(args: &[String]) -> std::io::Result { let mut workspace_id = None; let mut cwd = None; let mut trust_repository = false; let mut index = 0; while index < args.len() { match args[index].as_str() { "--workspace" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --workspace"); return Ok(2); }; workspace_id = Some(super::normalize_workspace_id(value)); index += 2; } "--cwd" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --cwd"); return Ok(2); }; cwd = Some(normalize_path_arg(value)?); index += 2; } "--trust-repository" => { trust_repository = true; index += 1; } "--json" => index += 1, other => { eprintln!("unknown option: {other}"); return Ok(2); } } } if workspace_id.is_some() && cwd.is_some() { eprintln!("usage: herdr worktree list [--workspace ID | --cwd PATH] [--trust-repository]"); return Ok(2); } super::runtime::worktree_list(WorktreeListParams { workspace_id, cwd, trust_repository, }) } fn worktree_create(args: &[String]) -> std::io::Result { let mut workspace_id = None; let mut cwd = None; let mut branch = None; let mut base = None; let mut path = None; let mut label = None; let mut focus = false; let mut trust_repository = false; let mut index = 0; while index < args.len() { match args[index].as_str() { "--workspace" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --workspace"); return Ok(2); }; workspace_id = Some(super::normalize_workspace_id(value)); index += 2; } "--cwd" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --cwd"); return Ok(2); }; cwd = Some(normalize_path_arg(value)?); index += 2; } "--branch" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --branch"); return Ok(2); }; branch = Some(value.clone()); index += 2; } "--base" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --base"); return Ok(2); }; base = Some(value.clone()); index += 2; } "--path" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --path"); return Ok(2); }; path = Some(normalize_path_arg(value)?); index += 2; } "--label" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --label"); return Ok(2); }; label = Some(value.clone()); index += 2; } "--focus" => { focus = true; index += 1; } "--no-focus" => { focus = false; index += 1; } "--trust-repository" => { trust_repository = true; index += 1; } "--json" => index += 1, other => { eprintln!("unknown option: {other}"); return Ok(2); } } } if workspace_id.is_some() && cwd.is_some() { eprintln!( "usage: herdr worktree create [--workspace ID | --cwd PATH] [--branch NAME] [--base REF] [--path PATH] [--label TEXT] [--focus] [--no-focus] [--trust-repository]" ); return Ok(2); } super::runtime::worktree_create(WorktreeCreateParams { workspace_id, cwd, branch, base, path, label, focus, trust_repository, }) } fn worktree_open(args: &[String]) -> std::io::Result { let mut workspace_id = None; let mut cwd = None; let mut path = None; let mut branch = None; let mut label = None; let mut focus = false; let mut trust_repository = false; let mut index = 0; while index < args.len() { match args[index].as_str() { "--workspace" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --workspace"); return Ok(2); }; workspace_id = Some(super::normalize_workspace_id(value)); index += 2; } "--cwd" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --cwd"); return Ok(2); }; cwd = Some(normalize_path_arg(value)?); index += 2; } "--path" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --path"); return Ok(2); }; path = Some(normalize_path_arg(value)?); index += 2; } "--branch" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --branch"); return Ok(2); }; branch = Some(value.clone()); index += 2; } "--label" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --label"); return Ok(2); }; label = Some(value.clone()); index += 2; } "--focus" => { focus = true; index += 1; } "--no-focus" => { focus = false; index += 1; } "--trust-repository" => { trust_repository = true; index += 1; } "--json" => index += 1, other => { eprintln!("unknown option: {other}"); return Ok(2); } } } if workspace_id.is_some() && cwd.is_some() { eprintln!( "usage: herdr worktree open [--workspace ID | --cwd PATH] (--path PATH | --branch NAME) [--label TEXT] [--focus] [--no-focus] [--trust-repository]" ); return Ok(2); } if path.is_some() == branch.is_some() { eprintln!( "usage: herdr worktree open [--workspace ID | --cwd PATH] (--path PATH | --branch NAME) [--label TEXT] [--focus] [--no-focus] [--trust-repository]" ); return Ok(2); } super::runtime::worktree_open(WorktreeOpenParams { workspace_id, cwd, path, branch, label, focus, trust_repository, }) } fn worktree_remove(args: &[String]) -> std::io::Result { let mut workspace_id = None; let mut force = false; let mut trust_repository = false; let mut index = 0; while index < args.len() { match args[index].as_str() { "--workspace" => { let Some(value) = args.get(index + 1) else { eprintln!("missing value for --workspace"); return Ok(2); }; workspace_id = Some(super::normalize_workspace_id(value)); index += 2; } "--force" => { force = true; index += 1; } "--trust-repository" => { trust_repository = true; index += 1; } "--json" => index += 1, other => { eprintln!("unknown option: {other}"); return Ok(2); } } } let Some(workspace_id) = workspace_id else { eprintln!("usage: herdr worktree remove --workspace ID [--force] [--trust-repository]"); return Ok(2); }; super::runtime::worktree_remove(WorktreeRemoveParams { workspace_id, force, trust_repository, }) } fn print_worktree_help() { eprintln!("herdr worktree commands:"); eprintln!(" herdr worktree list [--workspace ID | --cwd PATH] [--trust-repository]"); eprintln!( " herdr worktree create [--workspace ID | --cwd PATH] [--branch NAME] [--base REF] [--path PATH] [--label TEXT] [--focus] [--no-focus] [--trust-repository]" ); eprintln!( " herdr worktree open [--workspace ID | --cwd PATH] (--path PATH | --branch NAME) [--label TEXT] [--focus] [--no-focus] [--trust-repository]" ); eprintln!(" herdr worktree remove --workspace ID [--force] [--trust-repository]"); } fn normalize_path_arg(value: &str) -> std::io::Result { let path = crate::worktree::expand_tilde_path(value); let absolute = if path.is_absolute() { path } else { std::env::current_dir()?.join(path) }; Ok(absolute.display().to_string()) }