[WIP] tangled knot rust implementation
at main 2.0 kB view raw
1use std::path::PathBuf; 2 3use clap::{Parser, Subcommand}; 4 5use crate::{cmd, config::ConfigBuilder}; 6 7#[derive(Parser)] 8#[command( 9 author = "boltless.me", 10 version, 11 disable_version_flag = true, 12 about = "Knot cli" 13)] 14pub struct Cli { 15 /// Print version 16 #[arg(short = 'v', long, action = clap::builder::ArgAction::Version)] 17 version: (), 18 19 /// config file path 20 #[arg(short = 'c', long)] 21 config: Option<PathBuf>, 22 23 #[command(subcommand)] 24 command: Commands, 25} 26 27#[derive(Subcommand, Clone)] 28enum Commands { 29 /// run a knot server 30 Daemon, 31 /// fetch public keys from the knot server 32 Keys { 33 /// output format 34 #[arg(long, default_value_t, value_enum)] 35 output: cmd::keys::KeysOutputFormat, 36 }, 37 /// role-based access control for git over ssh (not for manual use) 38 Guard { 39 /// possible users accessing the repo 40 #[arg(short = 'u', long, required = true)] 41 users: Vec<String>, 42 }, 43 /// run git hooks 44 #[command(subcommand)] 45 Hook(HookCommands), 46} 47 48#[derive(Subcommand, Clone)] 49enum HookCommands { 50 /// sends a post-recieve hook to the knot (waits for stdin) 51 PostReceive { 52 /// git user's did 53 #[arg(long, required = true)] 54 user: String, 55 /// any push option from git 56 #[arg(long)] 57 push_options: Vec<String>, 58 }, 59} 60 61pub async fn run() -> anyhow::Result<()> { 62 let cli = Cli::parse(); 63 64 let config_path = cli.config.unwrap_or("config.toml".into()); 65 let config = ConfigBuilder::new(config_path)?.build()?; 66 67 match cli.command { 68 Commands::Daemon => cmd::daemon::daemon(config).await?, 69 Commands::Keys { output } => cmd::keys::keys(output).await?, 70 Commands::Guard { users } => cmd::guard::guard(users).await?, 71 Commands::Hook(command) => match command { 72 HookCommands::PostReceive { user, push_options } => { 73 cmd::hook::post_receive(user, push_options).await? 74 } 75 }, 76 } 77 Ok(()) 78}