mirror of
https://codeberg.org/tyy/aspm
synced 2025-01-10 05:19:29 -07:00
Add profiles delete command
This commit is contained in:
parent
77f545b32e
commit
561cc3fb42
3 changed files with 115 additions and 0 deletions
112
src/commands/profiles/delete.rs
Normal file
112
src/commands/profiles/delete.rs
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
use anstyle::{AnsiColor, Reset, Style as Anstyle};
|
||||||
|
use anyhow::Context;
|
||||||
|
use clap::Parser;
|
||||||
|
use dialoguer::{theme::ColorfulTheme, Confirm, Select};
|
||||||
|
use indoc::writedoc;
|
||||||
|
use sea_orm::{EntityTrait, ModelTrait};
|
||||||
|
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
use crate::{commands::AspmSubcommand, entities::prelude::*};
|
||||||
|
|
||||||
|
/// Deletes a saved profile
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
pub struct ProfilesDeleteCommand {
|
||||||
|
/// Will disable any confirmation prompts. This is not recommended unless you knowingly give a full fingerprint, as it is easy to accidentally (and permanently) delete wrong keys otherwise.
|
||||||
|
#[arg(long)]
|
||||||
|
no_confirm: bool,
|
||||||
|
/// The profile to edit. If not provided, it will be queried for interactively.
|
||||||
|
profile: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl AspmSubcommand for ProfilesDeleteCommand {
|
||||||
|
async fn execute(&self, state: crate::AspmState) -> Result<(), anyhow::Error> {
|
||||||
|
let profile = match &self.profile {
|
||||||
|
Some(key) => Profiles::find_by_id(key)
|
||||||
|
.one(&state.db)
|
||||||
|
.await
|
||||||
|
.context("Unable to query database for profile")?
|
||||||
|
.context("No profile found for the specified key")?,
|
||||||
|
None => {
|
||||||
|
let mut profiles = Profiles::find()
|
||||||
|
.all(&state.db)
|
||||||
|
.await
|
||||||
|
.context("Unable to query database for profiles")?;
|
||||||
|
let choice = Select::with_theme(&ColorfulTheme::default())
|
||||||
|
.with_prompt("Please select the profile to delete")
|
||||||
|
.items(
|
||||||
|
profiles
|
||||||
|
.iter()
|
||||||
|
.map(|profile| &profile.key)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.as_slice(),
|
||||||
|
)
|
||||||
|
.default(0)
|
||||||
|
.interact()
|
||||||
|
.context("Unable to prompt on stderr")?;
|
||||||
|
|
||||||
|
profiles.swap_remove(choice)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let claims = profile
|
||||||
|
.find_related(Claims)
|
||||||
|
.all(&state.db)
|
||||||
|
.await
|
||||||
|
.context("Unable to fetch claims from database")?;
|
||||||
|
|
||||||
|
if !self.no_confirm {
|
||||||
|
// Construct styles
|
||||||
|
let reset = Reset.render();
|
||||||
|
let alias_style = Anstyle::new()
|
||||||
|
.underline()
|
||||||
|
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightCyan)))
|
||||||
|
.render();
|
||||||
|
let key_style = Anstyle::new()
|
||||||
|
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightGreen)))
|
||||||
|
.render();
|
||||||
|
let value_style = Anstyle::new()
|
||||||
|
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightYellow)))
|
||||||
|
.render();
|
||||||
|
let _ = writedoc! {
|
||||||
|
std::io::stdout(),
|
||||||
|
"
|
||||||
|
{alias_style}{alias}{reset}:
|
||||||
|
{key_style}Fingerprint{reset} {value_style}{fingerprint}{reset}
|
||||||
|
{key_style}Name{reset} {value_style}{name}{reset}
|
||||||
|
{key_style}Email{reset} {value_style}{email}{reset}
|
||||||
|
{key_style}Description{reset} {value_style}{description}{reset}
|
||||||
|
{key_style}Avatar URL{reset} {value_style}{avatar_url}{reset}
|
||||||
|
{key_style}Color{reset} {value_style}{color}{reset}
|
||||||
|
{key_style}Claims{reset}
|
||||||
|
{claims}
|
||||||
|
",
|
||||||
|
alias = profile.alias.clone(),
|
||||||
|
fingerprint = profile.key.clone(),
|
||||||
|
name = profile.name.clone(),
|
||||||
|
description = profile.description.clone().unwrap_or("None".to_string()),
|
||||||
|
avatar_url = profile.avatar_url.clone().unwrap_or("None".to_string()),
|
||||||
|
email = profile.email.clone().unwrap_or("None".to_string()),
|
||||||
|
color = profile.color.clone().unwrap_or("None".to_string()),
|
||||||
|
claims = claims.into_iter().map(|claim| format!("\t\t- {value_style}{uri}{reset}", uri = claim.uri)).collect::<Vec<_>>().join("\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
let confirmation = Confirm::with_theme(&ColorfulTheme::default())
|
||||||
|
.with_prompt("Are you sure you want to delete this profile?")
|
||||||
|
.interact()
|
||||||
|
.context("Unable to prompt on stderr")?;
|
||||||
|
|
||||||
|
if !confirmation {
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
profile.delete(&state.db)
|
||||||
|
.await
|
||||||
|
.context("Unable to delete profile and claims from database")?;
|
||||||
|
|
||||||
|
println!("Successfully deleted profile");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ pub mod create;
|
||||||
pub mod edit;
|
pub mod edit;
|
||||||
pub mod export;
|
pub mod export;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
|
pub mod delete;
|
||||||
|
|
||||||
/// A subcommand to allow the management of keys, which can then be used to create, modify, or delete profiles.
|
/// A subcommand to allow the management of keys, which can then be used to create, modify, or delete profiles.
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
|
@ -18,4 +19,5 @@ pub enum ProfilesSubcommands {
|
||||||
Export(export::ProfilesExportCommand),
|
Export(export::ProfilesExportCommand),
|
||||||
List(list::ProfilesListCommand),
|
List(list::ProfilesListCommand),
|
||||||
Edit(edit::ProfilesEditCommand),
|
Edit(edit::ProfilesEditCommand),
|
||||||
|
Delete(delete::ProfilesDeleteCommand),
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,6 +161,7 @@ fn cli(parsed: AspmCommand) -> Result<(), anyhow::Error> {
|
||||||
ProfilesSubcommands::Export(subcommand) => subcommand.execute_sync(state, runtime),
|
ProfilesSubcommands::Export(subcommand) => subcommand.execute_sync(state, runtime),
|
||||||
ProfilesSubcommands::List(subcommand) => subcommand.execute_sync(state, runtime),
|
ProfilesSubcommands::List(subcommand) => subcommand.execute_sync(state, runtime),
|
||||||
ProfilesSubcommands::Edit(subcommand) => subcommand.execute_sync(state, runtime),
|
ProfilesSubcommands::Edit(subcommand) => subcommand.execute_sync(state, runtime),
|
||||||
|
ProfilesSubcommands::Delete(subcommand) => subcommand.execute_sync(state, runtime),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue