summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--README.md1
-rw-r--r--src/git.rs13
-rw-r--r--src/lib.rs4
-rw-r--r--src/parser.rs9
-rw-r--r--tests/cli.rs29
6 files changed, 57 insertions, 0 deletions
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<ControlFlow<(), ()>, 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
@@ -58,6 +60,13 @@ pub struct SetBranchArgs {
}
#[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 <directory>/.git/ if <directory> is no Git directory
#[arg(long, default_value_t = true)]
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(())
+}