Your music, beautifully tracked. All yours. (coming soon) teal.fm
teal-fm atproto
at main 2.5 kB view raw
1use anyhow::Result; 2use clap::{Parser, Subcommand}; 3 4use std::path::PathBuf; 5 6mod crypto; 7 8#[derive(Parser)] 9#[command(name = "teal")] 10#[command(about = "Teal management utilities")] 11#[command(version = "0.1.0")] 12struct Cli { 13 #[command(subcommand)] 14 command: Commands, 15} 16 17#[derive(Subcommand)] 18enum Commands { 19 /// Generate a new K256 key pair 20 GenKey { 21 /// Key name/identifier 22 #[arg(short, long, default_value = "repo")] 23 name: String, 24 25 /// Output directory (defaults to ~/.teal/keys) 26 #[arg(short, long)] 27 output: Option<PathBuf>, 28 29 /// Overwrite existing keys 30 #[arg(short, long)] 31 force: bool, 32 33 /// Output format: json, multibase, or files 34 #[arg(long, default_value = "files")] 35 format: String, 36 }, 37 38 /// Extract public key multibase from private key 39 ExtractPubkey { 40 /// Path to private key file 41 #[arg(short, long)] 42 private_key: PathBuf, 43 44 /// Output format 45 #[arg(short, long, default_value = "multibase")] 46 format: String, 47 }, 48 49 /// List available keys 50 List { 51 /// Keys directory (defaults to ~/.teal/keys) 52 #[arg(short, long)] 53 directory: Option<PathBuf>, 54 }, 55 56 /// Rotate keys (generate new, backup old) 57 Rotate { 58 /// Key name to rotate 59 #[arg(short, long)] 60 name: String, 61 62 /// Backup directory 63 #[arg(short, long)] 64 backup_dir: Option<PathBuf>, 65 }, 66} 67 68fn get_default_keys_dir() -> PathBuf { 69 dirs::home_dir() 70 .unwrap_or_else(|| PathBuf::from(".")) 71 .join(".teal") 72 .join("keys") 73} 74 75#[tokio::main] 76async fn main() -> Result<()> { 77 let cli = Cli::parse(); 78 79 match cli.command { 80 Commands::GenKey { 81 name, 82 output, 83 force, 84 format, 85 } => { 86 let keys_dir = output.unwrap_or_else(get_default_keys_dir); 87 crypto::generate_key(name, keys_dir, force, format).await 88 } 89 Commands::ExtractPubkey { 90 private_key, 91 format, 92 } => crypto::extract_pubkey(private_key, format).await, 93 Commands::List { directory } => { 94 let keys_dir = directory.unwrap_or_else(get_default_keys_dir); 95 crypto::list_keys(keys_dir).await 96 } 97 Commands::Rotate { name, backup_dir } => { 98 let keys_dir = get_default_keys_dir(); 99 crypto::rotate_key(keys_dir, name, backup_dir).await 100 } 101 } 102}