#[cfg(feature = "async")]
use crate::Claude;
use crate::command::ClaudeCommand;
#[cfg(feature = "async")]
use crate::error::Result;
#[cfg(feature = "async")]
use crate::exec;
use crate::exec::CommandOutput;
#[derive(Debug, Clone, Default)]
pub struct ProjectPurgeCommand {
path: Option<String>,
all: bool,
dry_run: bool,
interactive: bool,
yes: bool,
}
impl ProjectPurgeCommand {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn path(mut self, path: impl Into<String>) -> Self {
self.path = Some(path.into());
self
}
#[must_use]
pub fn all(mut self) -> Self {
self.all = true;
self
}
#[must_use]
pub fn dry_run(mut self) -> Self {
self.dry_run = true;
self
}
#[must_use]
pub fn interactive(mut self) -> Self {
self.interactive = true;
self
}
#[must_use]
pub fn yes(mut self) -> Self {
self.yes = true;
self
}
}
impl ClaudeCommand for ProjectPurgeCommand {
type Output = CommandOutput;
fn args(&self) -> Vec<String> {
let mut args = vec!["project".to_string(), "purge".to_string()];
if self.all {
args.push("--all".to_string());
}
if self.dry_run {
args.push("--dry-run".to_string());
}
if self.interactive {
args.push("--interactive".to_string());
}
if self.yes {
args.push("--yes".to_string());
}
if let Some(ref path) = self.path {
args.push(path.clone());
}
args
}
#[cfg(feature = "async")]
async fn execute(&self, claude: &Claude) -> Result<CommandOutput> {
exec::run_claude(claude, self.args()).await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn purge_defaults_to_bare_subcommand() {
let cmd = ProjectPurgeCommand::new();
assert_eq!(ClaudeCommand::args(&cmd), vec!["project", "purge"]);
}
#[test]
fn purge_with_path_passes_positional() {
let cmd = ProjectPurgeCommand::new().path("/tmp/old-project");
assert_eq!(
ClaudeCommand::args(&cmd),
vec!["project", "purge", "/tmp/old-project"]
);
}
#[test]
fn purge_all_emits_flag() {
let cmd = ProjectPurgeCommand::new().all().yes();
assert_eq!(
ClaudeCommand::args(&cmd),
vec!["project", "purge", "--all", "--yes"]
);
}
#[test]
fn purge_dry_run_with_yes_is_safe_preview() {
let cmd = ProjectPurgeCommand::new().dry_run().yes();
assert_eq!(
ClaudeCommand::args(&cmd),
vec!["project", "purge", "--dry-run", "--yes"]
);
}
#[test]
fn purge_all_flags() {
let cmd = ProjectPurgeCommand::new()
.path("/proj")
.all()
.dry_run()
.interactive()
.yes();
assert_eq!(
ClaudeCommand::args(&cmd),
vec![
"project",
"purge",
"--all",
"--dry-run",
"--interactive",
"--yes",
"/proj"
]
);
}
#[test]
fn purge_path_lands_last_so_positional_is_unambiguous() {
let cmd = ProjectPurgeCommand::new().yes().path("./me");
let args = ClaudeCommand::args(&cmd);
assert_eq!(args.last().map(String::as_str), Some("./me"));
}
}