From da8802d1fb0c5707877777ff4187238195eef16b Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Sat, 24 Jun 2023 21:52:37 +0200 Subject: Added a command to delete a repo --- CHANGELOG.md | 1 + README.md | 1 + src/git.rs | 13 +++++++++++++ src/lib.rs | 4 ++++ src/parser.rs | 9 +++++++++ tests/cli.rs | 29 +++++++++++++++++++++++++++++ 6 files changed, 57 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 598ff2b..dbe5758 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added feature flag "docker_tests". This only affects which tests are run by default, so that the CI environment can skip tests that require running docker. +- New command "delete", for deleting an existing repo. ## [0.1.1] - 2023-05-10 diff --git a/README.md b/README.md index 7227f07..e67bfc3 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,7 @@ tracker](https://codeberg.org/worthe-it/shackle-shell/issues). ## Roadmap +- [ ] confirmation on risky actions like deleting a repo - [ ] project website - [ ] functions correctly when the git path isn't created with correct permissions yet diff --git a/src/git.rs b/src/git.rs index 07ec775..c07615d 100644 --- a/src/git.rs +++ b/src/git.rs @@ -194,6 +194,19 @@ pub fn set_branch(directory: &Path, branch: &str) -> Result<(), ShackleError> { } } +pub fn delete(directory: &Path) -> Result<(), ShackleError> { + if !is_valid_git_repo_path(directory)? { + return Err(ShackleError::InvalidDirectory); + } + + if Repository::open_bare(directory).is_ok() { + fs::remove_dir_all(directory)?; + Ok(()) + } else { + Err(ShackleError::InvalidDirectory) + } +} + pub fn upload_pack(upload_pack_args: &GitUploadPackArgs) -> Result<(), ShackleError> { if !is_valid_git_repo_path(&upload_pack_args.directory)? { return Err(ShackleError::InvalidDirectory); diff --git a/src/lib.rs b/src/lib.rs index 45a7fd3..32d5770 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,6 +46,10 @@ pub fn run_command(user_input: &str) -> Result, ShackleError let init_result = git::init(&repo_name, &group, &description, &branch)?; println!("Successfully created \"{}\"", init_result.path.display()); } + Ok(ShackleCommand::Delete(DeleteArgs { directory })) => { + git::delete(&directory)?; + println!("Successfully deleted \"{}\"", directory.display()); + } Ok(ShackleCommand::GitUploadPack(upload_pack_args)) => { git::upload_pack(&upload_pack_args)?; } diff --git a/src/parser.rs b/src/parser.rs index ebd860b..30eb1e0 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -16,6 +16,8 @@ pub enum ShackleCommand { SetDescription(SetDescriptionArgs), /// Sets the main branch of the repository SetBranch(SetBranchArgs), + /// Deletes a repository + Delete(DeleteArgs), /// Quit the shell Exit, /// Server side command required to git fetch from the server @@ -57,6 +59,13 @@ pub struct SetBranchArgs { pub branch: String, } +#[derive(Parser, Clone, Debug, PartialEq, Eq)] +pub struct DeleteArgs { + /// The full relative path of the repository, for example git/shuckie/repo.git + #[arg(value_parser = RelativePathParser)] + pub directory: PathBuf, +} + #[derive(Parser, Clone, Debug, PartialEq, Eq)] pub struct GitUploadPackArgs { /// Do not try /.git/ if is no Git directory diff --git a/tests/cli.rs b/tests/cli.rs index 41fe145..7bda913 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -98,6 +98,10 @@ fn verify_repo_exists(repo_dir: &Path) { .stdout(""); } +fn verify_repo_does_not_exist(repo_dir: &Path) { + assert!(!repo_dir.exists()); +} + fn verify_current_branch(repo_dir: &Path, expected_ref: &str) { Command::new("git") .arg("symbolic-ref") @@ -423,3 +427,28 @@ fn can_change_the_main_branch_on_a_repo() -> Result<()> { Ok(()) } + +#[test] +fn can_delete_a_repo() -> Result<()> { + let mut c = spawn_interactive_process()?; + let username = get_username().unwrap(); + let repo_name = "an-old-repo"; + let repo_path = format!("git/{username}/{repo_name}.git"); + let repo_dir = c + .workdir + .as_ref() + .join("git") + .join(username) + .join(&format!("{}.git", repo_name)); + + c.p.send_line(&format!("init {}", repo_name))?; + c.p.exp_string(&format!("Successfully created \"{repo_path}\""))?; + verify_repo_exists(&repo_dir); + + c.p.send_line(&format!("delete \"{repo_path}\""))?; + c.p.exp_string(&format!("Successfully deleted \"{repo_path}\""))?; + + verify_repo_does_not_exist(&repo_dir); + + Ok(()) +} -- cgit v1.2.3