use crate::repo::RepoGroupManager; use crate::{Config, Global}; use axum::extract::FromRef; use axum::Router; use clap::Parser; use std::path::PathBuf; use std::sync::{Arc, RwLock}; use tower_http::trace::TraceLayer; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; #[derive(Parser)] #[command(author, version, about, long_about = None)] pub struct Cli { /// Port the server will listen on #[arg(short, long, value_name = "PORT", default_value_t = 8000)] pub port: u16, /// Log levels for the tracing #[arg( long, value_name = "LOG_LEVEL", default_value = "tower_http=debug,rieterd=debug" )] pub log: String, /// Directory where package archives will be stored pub pkg_dir: PathBuf, /// Directory where repository metadata is stored pub repo_dir: PathBuf, } impl FromRef for Arc> { fn from_ref(global: &Global) -> Self { Arc::clone(&global.repo_manager) } } impl Cli { pub fn init_tracing(&self) { tracing_subscriber::registry() .with(tracing_subscriber::EnvFilter::new(self.log.clone())) .with(tracing_subscriber::fmt::layer()) .init(); } pub async fn run(&self) { self.init_tracing(); let config = Config { repo_dir: self.repo_dir.clone(), pkg_dir: self.pkg_dir.clone(), }; let repo_manager = RepoGroupManager::new(&self.repo_dir, &self.pkg_dir); let global = Global { config, repo_manager: Arc::new(RwLock::new(repo_manager)), }; // build our application with a single route let app = Router::new() .merge(crate::repo::router()) .with_state(global) .layer(TraceLayer::new_for_http()); // run it with hyper on localhost:3000 axum::Server::bind(&format!("0.0.0.0:{}", self.port).parse().unwrap()) .serve(app.into_make_service()) .await .unwrap(); } }