From 1da8ea923b518c93ccc7d95240a0b054d6ddc5fc Mon Sep 17 00:00:00 2001 From: Maaz Khokhar Date: Mon, 13 Jul 2026 20:27:09 -0500 Subject: [PATCH] added the deletion of projects --- .gitignore | 2 ++ crates/cli/src/lib.rs | 26 ++++++++++++--- crates/cli/src/main.rs | 76 +++++++++++++++++++++++++++++++++--------- 3 files changed, 84 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 1acb9e4..7119aa8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,8 @@ devenv.local.yaml # Nix result +harbor.db + # direnv .direnv diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index e4c9a8f..677389c 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -1,5 +1,6 @@ use base64::{Engine, engine::general_purpose::STANDARD}; use clap::{Parser, Subcommand}; +use colored::Colorize; use crypto::helper::gen_key; use keyring::Entry; use std::error::Error; @@ -77,17 +78,22 @@ pub mod interactions { ))) } - pub fn create_project(proj_name: &str) -> Result<(), Box> { + pub fn project_exists(proj_name: &str) -> Result> { let mut conn = establish_connection(); - // 1. Check if the project already exists let existing_project = projects .filter(project_name.eq(proj_name)) .select(Project::as_select()) .first::(&mut conn) .optional()?; - if let Some(_) = existing_project { + Ok(existing_project.is_some()) + } + + pub fn create_project(proj_name: &str) -> Result<(), Box> { + let mut conn = establish_connection(); + + if project_exists(proj_name)? { return construct_error("Project already exists"); } @@ -108,6 +114,18 @@ pub mod interactions { Err(err) => Err(Box::new(err)), } } + + pub fn delete_project(proj_name: &str) -> Result<(), Box> { + let mut conn = establish_connection(); + + if !project_exists(proj_name)? { + return construct_error("Project does not exist"); + } + + diesel::delete(projects.filter(project_name.eq(proj_name))).execute(&mut conn)?; + + Ok(()) + } } pub fn gen_or_get_key() -> Result> { @@ -135,7 +153,7 @@ pub fn gen_or_get_key() -> Result> { } } -pub fn get_input(message: &str, prompt: char, new_line: bool) -> Result> { +pub fn get_input(message: impl std::fmt::Display, prompt: char, new_line: bool) -> Result> { let mut input = String::new(); if new_line { diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 5891477..c2e56ab 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -9,10 +9,11 @@ use colored::*; const GIT_VERSION: &str = env!("GIT_VERSION"); fn main() { + use cli::{Commands, ConfigCommands, ProjectCommands}; let cli = Cli::parse(); if cli.version { - let top_msg = format!("Harbor version {}", crate_version!().green()).bright_blue(); + let top_msg = format!("Harbor version {}", crate_version!().green()).bright_cyan(); let bottom_msg = format!("An open source secrets management and distribution platform.").blue(); let commit_msg = format!("Git commit {}", GIT_VERSION).dimmed(); @@ -23,24 +24,24 @@ fn main() { match cli.command { Some(c) => match c { - cli::Commands::Add {} => { + Commands::Add {} => { println!("Add command executed"); } - cli::Commands::Config { command } => match command { - cli::ConfigCommands::List {} => { + Commands::Config { command } => match command { + ConfigCommands::List {} => { println!("Config list command executed"); } - cli::ConfigCommands::Create { project } => { + ConfigCommands::Create { project } => { println!("Config create command executed for project: {}", project); } - cli::ConfigCommands::Delete { project, name } => { + ConfigCommands::Delete { project, name } => { println!( "Config delete command executed for project: {}, name: {}", project, name ); } }, - cli::Commands::Inject { verbose, after } => { + Commands::Inject { verbose, after } => { println!( "Inject command executed with verbose: {}, after: {:?}", verbose, after @@ -48,14 +49,14 @@ fn main() { // for harbor inject -- bun dev // after = ["bun", "dev"] } - cli::Commands::List {} => { + Commands::List {} => { println!("List command executed"); } - cli::Commands::Project { command } => match command { - cli::ProjectCommands::List {} => { + Commands::Project { command } => match command { + ProjectCommands::List {} => { println!("Project list command executed"); } - cli::ProjectCommands::Create {} => { + ProjectCommands::Create {} => { let project_name = match get_input("Project name", ':', false) { Ok(name) => name, Err(e) => { @@ -65,21 +66,64 @@ fn main() { }; match cli::interactions::create_project(&project_name) { - Ok(()) => println!("{}", "Project created successfully".blue()), + Ok(()) => println!("{}", "Project created successfully.".cyan()), Err(e) => { eprintln!("Error creating project: {}", e); process::exit(1); } } } - cli::ProjectCommands::Delete { name } => { - println!("Project delete command executed for name: {}", name); + ProjectCommands::Delete { name } => { + // We'll check if the project exists before prompting for confirmation + let exists = match cli::interactions::project_exists(&name) { + Ok(exists) => exists, + Err(e) => { + eprintln!("Error checking if project exists: {}", e); + process::exit(1); + } + }; + + if !exists { + eprintln!("Project '{}' does not exist.", name); + process::exit(1); + } + + // Prompt for confirmation + let confirmation = match get_input( + format!( + "Are you sure you want to delete the project '{}'? (y/N)", + name + ) + .red(), + ':', + false, + ) { + Ok(input) => input, + Err(e) => { + eprintln!("Error getting confirmation: {}", e); + process::exit(1); + } + }; + + if confirmation.to_lowercase() == "y" { + match cli::interactions::delete_project(&name) { + Ok(()) => { + println!("{}", "Project deleted successfully.".cyan()) + } + Err(e) => { + eprintln!("Error deleting project: {}", e); + process::exit(1); + } + } + } else { + println!("Project deletion canceled."); + } } }, - cli::Commands::Shell {} => { + Commands::Shell {} => { println!("Shell command executed"); } - cli::Commands::Setup {} => { + Commands::Setup {} => { println!("Setup command executed"); } },