mirror of
https://github.com/herdrdev/herdr.git
synced 2026-09-22 16:01:07 +00:00
refs #2171 Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
307 lines
9.5 KiB
Rust
307 lines
9.5 KiB
Rust
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<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]");
|
|
return Ok(2);
|
|
}
|
|
|
|
super::runtime::worktree_list(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]"
|
|
);
|
|
return Ok(2);
|
|
}
|
|
|
|
super::runtime::worktree_create(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]"
|
|
);
|
|
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]"
|
|
);
|
|
return Ok(2);
|
|
}
|
|
|
|
super::runtime::worktree_open(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]");
|
|
return Ok(2);
|
|
};
|
|
|
|
super::runtime::worktree_remove(WorktreeRemoveParams {
|
|
workspace_id,
|
|
force,
|
|
})
|
|
}
|
|
|
|
fn print_worktree_help() {
|
|
eprintln!("herdr worktree commands:");
|
|
eprintln!(" herdr worktree list [--workspace ID | --cwd PATH]");
|
|
eprintln!(
|
|
" herdr worktree create [--workspace ID | --cwd PATH] [--branch NAME] [--base REF] [--path PATH] [--label TEXT] [--focus] [--no-focus]"
|
|
);
|
|
eprintln!(
|
|
" herdr worktree open [--workspace ID | --cwd PATH] (--path PATH | --branch NAME) [--label TEXT] [--focus] [--no-focus]"
|
|
);
|
|
eprintln!(" herdr worktree remove --workspace ID [--force]");
|
|
}
|
|
|
|
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())
|
|
}
|