diff options
Diffstat (limited to 'src/cli/worktree.rs')
| -rw-r--r-- | src/cli/worktree.rs | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/src/cli/worktree.rs b/src/cli/worktree.rs new file mode 100644 index 00000000..53ad685b --- /dev/null +++ b/src/cli/worktree.rs @@ -0,0 +1,318 @@ +use crate::api::schema::{ + Method, Request, WorktreeCreateParams, WorktreeListParams, WorktreeOpenParams, + WorktreeRemoveParams, +}; + +pub(super) fn run_worktree_command(args: &[String]) -> std::io::Result<i32> { + 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<i32> { + let mut workspace_id = None; + let mut cwd = None; + + 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; + } + "--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] [--json]"); + return Ok(2); + } + + super::print_response(&super::send_request(&Request { + id: "cli:worktree:list".into(), + method: Method::WorktreeList(WorktreeListParams { workspace_id, cwd }), + })?) +} + +fn worktree_create(args: &[String]) -> std::io::Result<i32> { + 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 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; + } + "--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] [--json]" + ); + return Ok(2); + } + + super::print_response(&super::send_request(&Request { + id: "cli:worktree:create".into(), + method: Method::WorktreeCreate(WorktreeCreateParams { + workspace_id, + cwd, + branch, + base, + path, + label, + focus, + }), + })?) +} + +fn worktree_open(args: &[String]) -> std::io::Result<i32> { + 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 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; + } + "--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] [--json]" + ); + 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] [--json]" + ); + return Ok(2); + } + + super::print_response(&super::send_request(&Request { + id: "cli:worktree:open".into(), + method: Method::WorktreeOpen(WorktreeOpenParams { + workspace_id, + cwd, + path, + branch, + label, + focus, + }), + })?) +} + +fn worktree_remove(args: &[String]) -> std::io::Result<i32> { + let mut workspace_id = None; + let mut force = 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; + } + "--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] [--json]"); + return Ok(2); + }; + + super::print_response(&super::send_request(&Request { + id: "cli:worktree:remove".into(), + method: Method::WorktreeRemove(WorktreeRemoveParams { + workspace_id, + force, + }), + })?) +} + +fn print_worktree_help() { + eprintln!("herdr worktree commands:"); + eprintln!(" herdr worktree list [--workspace ID | --cwd PATH] [--json]"); + eprintln!( + " herdr worktree create [--workspace ID | --cwd PATH] [--branch NAME] [--base REF] [--path PATH] [--label TEXT] [--focus] [--no-focus] [--json]" + ); + eprintln!( + " herdr worktree open [--workspace ID | --cwd PATH] (--path PATH | --branch NAME) [--label TEXT] [--focus] [--no-focus] [--json]" + ); + eprintln!(" herdr worktree remove --workspace ID [--force] [--json]"); +} + +fn normalize_path_arg(value: &str) -> std::io::Result<String> { + 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()) +} |
