diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | src/lib.rs | 35 | ||||
-rw-r--r-- | tests/cli.rs | 27 |
3 files changed, 61 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index f57cb64..ec28d1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Updated crates.io metadata to mark the primary upstream repo as Codeberg. +- When deleting a repo, you are now asked first to confirm if you are sure + you're deleting the right repo. ## [0.2.0] - 2023-07-17 @@ -5,7 +5,7 @@ pub mod user_info; use comfy_table::Table; use humansize::{format_size, BINARY}; use parser::*; -use rustyline::error::ReadlineError; +use rustyline::{error::ReadlineError, DefaultEditor}; use std::{io, ops::ControlFlow}; use thiserror::Error; @@ -60,8 +60,15 @@ pub fn run_command(user_input: &str) -> Result<ControlFlow<(), ()>, ShackleError println!("Successfully created \"{}\"", init_result.path.display()); } Ok(ShackleCommand::Delete(DeleteArgs { directory })) => { - git::delete(&directory)?; - println!("Successfully deleted \"{}\"", directory.display()); + if confirm_risky_action(format!( + "Are you sure you want to delete \"{}\"?", + directory.display() + ))? { + git::delete(&directory)?; + println!("Successfully deleted \"{}\"", directory.display()); + } else { + println!("Action cancelled"); + } } Ok(ShackleCommand::Housekeeping(HousekeepingArgs { directory })) => match directory { Some(directory) => { @@ -92,6 +99,28 @@ pub fn run_command(user_input: &str) -> Result<ControlFlow<(), ()>, ShackleError Ok(ControlFlow::Continue(())) } +fn confirm_risky_action(prompt: String) -> Result<bool, ShackleError> { + let mut rl = DefaultEditor::new()?; + loop { + let user_input = rl + .readline(&format!("{} (yes/no) ", prompt)) + .map(|user_input| user_input.to_lowercase())?; + + match user_input.trim() { + "" => {} + "yes" => { + return Ok(true); + } + "no" => { + return Ok(false); + } + _ => { + println!("Please answer 'yes' or 'no'."); + } + } + } +} + #[derive(Error, Debug)] pub enum ShackleError { #[error(transparent)] diff --git a/tests/cli.rs b/tests/cli.rs index 34249c2..633c7bd 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -284,6 +284,11 @@ fn can_delete_a_repo() -> Result<()> { verify_repo_exists(&repo_dir); c.p.send_line(&format!("delete \"{repo_path}\""))?; + c.p.exp_string(&format!( + "Are you sure you want to delete \"{repo_path}\"? (yes/no)" + ))?; + + c.p.send_line("yes")?; c.p.exp_string(&format!("Successfully deleted \"{repo_path}\""))?; verify_repo_does_not_exist(&repo_dir); @@ -291,6 +296,28 @@ fn can_delete_a_repo() -> Result<()> { } #[test] +fn repo_is_not_deleted_if_you_say_youre_not_sure() -> Result<()> { + let mut c = TestContext::new_interactive()?; + let repo_path = personal_repo_path(REPO_NAME); + let repo_dir = c.personal_repo_dir(REPO_NAME); + + c.p.send_line(&format!("init {}", REPO_NAME))?; + c.expect_successful_init_message(&repo_path)?; + verify_repo_exists(&repo_dir); + + c.p.send_line(&format!("delete \"{repo_path}\""))?; + c.p.exp_string(&format!( + "Are you sure you want to delete \"{repo_path}\"? (yes/no)" + ))?; + + c.p.send_line("no")?; + c.p.exp_string(&format!("Action cancelled"))?; + verify_repo_exists(&repo_dir); + + Ok(()) +} + +#[test] fn git_housekeeping_repacks_objects() -> Result<()> { let mut c = TestContext::new_interactive()?; let repo_path = personal_repo_path(REPO_NAME); |