Skip to main content

envvault/cli/commands/
env_delete.rs

1//! `envvault env delete` — delete a vault environment.
2
3use std::fs;
4
5use dialoguer::Confirm;
6
7use crate::cli::output;
8use crate::cli::{validate_env_name, Cli};
9use crate::errors::{EnvVaultError, Result};
10
11/// Execute `envvault env delete <name>`.
12pub fn execute(cli: &Cli, name: &str, force: bool) -> Result<()> {
13    validate_env_name(name)?;
14
15    let cwd = std::env::current_dir()?;
16    let vault_dir = cwd.join(&cli.vault_dir);
17    let vault_path = vault_dir.join(format!("{name}.vault"));
18
19    if !vault_path.exists() {
20        return Err(EnvVaultError::EnvironmentNotFound(name.to_string()));
21    }
22
23    // Prevent deleting the active environment unless --force is used.
24    if name == cli.env && !force {
25        output::warning(&format!(
26            "'{name}' is the currently active environment. Use --force to confirm."
27        ));
28        return Ok(());
29    }
30
31    if !force {
32        let confirmed = Confirm::new()
33            .with_prompt(format!(
34                "Delete environment '{name}'? This cannot be undone"
35            ))
36            .default(false)
37            .interact()
38            .map_err(|e| EnvVaultError::CommandFailed(format!("confirm prompt: {e}")))?;
39
40        if !confirmed {
41            output::info("Cancelled.");
42            return Ok(());
43        }
44    }
45
46    fs::remove_file(&vault_path)?;
47
48    crate::audit::log_audit(cli, "env-delete", None, Some(&format!("deleted {name}")));
49
50    output::success(&format!(
51        "Deleted environment '{name}' ({} removed)",
52        vault_path.display()
53    ));
54
55    Ok(())
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn delete_removes_vault_file() {
64        let dir = tempfile::TempDir::new().unwrap();
65        let vault_path = dir.path().join("staging.vault");
66        std::fs::write(&vault_path, b"test vault data").unwrap();
67        assert!(vault_path.exists());
68
69        std::fs::remove_file(&vault_path).unwrap();
70        assert!(!vault_path.exists());
71    }
72
73    #[test]
74    fn delete_fails_for_missing_env() {
75        let dir = tempfile::TempDir::new().unwrap();
76        let vault_path = dir.path().join("nonexistent.vault");
77        assert!(!vault_path.exists());
78    }
79
80    #[test]
81    fn validates_env_name_on_delete() {
82        assert!(validate_env_name("INVALID").is_err());
83        assert!(validate_env_name("valid-name").is_ok());
84    }
85}