2023-07-16 20:52:03 +02:00
|
|
|
use crate::repo::RepoGroupManager;
|
|
|
|
use crate::{Config, Global};
|
|
|
|
|
|
|
|
use axum::extract::FromRef;
|
|
|
|
use axum::Router;
|
|
|
|
use clap::Parser;
|
2023-08-01 15:30:38 +02:00
|
|
|
use std::io;
|
2023-07-16 20:52:03 +02:00
|
|
|
use std::path::PathBuf;
|
|
|
|
use std::sync::{Arc, RwLock};
|
|
|
|
use tower_http::trace::TraceLayer;
|
2023-08-01 15:30:38 +02:00
|
|
|
use tracing::debug;
|
2023-07-16 20:52:03 +02:00
|
|
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
|
|
|
|
|
|
|
#[derive(Parser)]
|
|
|
|
#[command(author, version, about, long_about = None)]
|
|
|
|
pub struct Cli {
|
2023-08-01 15:30:38 +02:00
|
|
|
/// Directory where package archives will be stored
|
|
|
|
pub pkg_dir: PathBuf,
|
|
|
|
/// Directory where repository metadata & SQLite database is stored
|
|
|
|
pub data_dir: PathBuf,
|
|
|
|
|
|
|
|
/// Database connection URL; either sqlite:// or postgres://. Defaults to rieter.sqlite in the
|
|
|
|
/// data directory
|
|
|
|
#[arg(short, long)]
|
|
|
|
pub database_url: Option<String>,
|
2023-07-16 20:52:03 +02:00
|
|
|
/// 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,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromRef<Global> for Arc<RwLock<RepoGroupManager>> {
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-08-01 15:30:38 +02:00
|
|
|
pub async fn run(&self) -> crate::Result<()> {
|
2023-07-16 20:52:03 +02:00
|
|
|
self.init_tracing();
|
|
|
|
|
2023-08-01 15:30:38 +02:00
|
|
|
let db_url = if let Some(url) = &self.database_url {
|
|
|
|
url.clone()
|
|
|
|
} else {
|
|
|
|
format!(
|
|
|
|
"sqlite://{}",
|
|
|
|
self.data_dir.join("rieter.sqlite").to_string_lossy()
|
|
|
|
)
|
|
|
|
};
|
|
|
|
|
|
|
|
debug!("Connecting to database with URL {}", db_url);
|
|
|
|
|
|
|
|
let db = crate::db::init(db_url).await?;
|
2023-08-01 14:38:50 +02:00
|
|
|
// let db = crate::db::init("postgres://rieter:rieter@localhost:5432/rieter")
|
2023-08-01 15:30:38 +02:00
|
|
|
// .await
|
|
|
|
// .unwrap();
|
2023-07-30 15:52:11 +02:00
|
|
|
|
2023-07-16 20:52:03 +02:00
|
|
|
let config = Config {
|
2023-08-01 15:30:38 +02:00
|
|
|
data_dir: self.data_dir.clone(),
|
|
|
|
repo_dir: self.data_dir.join("repos"),
|
2023-07-16 20:52:03 +02:00
|
|
|
pkg_dir: self.pkg_dir.clone(),
|
|
|
|
};
|
2023-08-01 15:30:38 +02:00
|
|
|
let repo_manager = RepoGroupManager::new(&config.repo_dir, &self.pkg_dir);
|
2023-07-16 20:52:03 +02:00
|
|
|
|
|
|
|
let global = Global {
|
|
|
|
config,
|
|
|
|
repo_manager: Arc::new(RwLock::new(repo_manager)),
|
2023-07-30 18:21:07 +02:00
|
|
|
db,
|
2023-07-16 20:52:03 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// build our application with a single route
|
|
|
|
let app = Router::new()
|
2023-07-30 16:55:44 +02:00
|
|
|
.nest("/api", crate::api::router())
|
2023-08-02 21:15:12 +02:00
|
|
|
.merge(crate::repo::router())
|
2023-07-16 20:52:03 +02:00
|
|
|
.with_state(global)
|
|
|
|
.layer(TraceLayer::new_for_http());
|
|
|
|
|
|
|
|
// run it with hyper on localhost:3000
|
2023-08-01 15:30:38 +02:00
|
|
|
Ok(
|
|
|
|
axum::Server::bind(&format!("0.0.0.0:{}", self.port).parse().unwrap())
|
|
|
|
.serve(app.into_make_service())
|
|
|
|
.await
|
|
|
|
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?,
|
|
|
|
)
|
2023-07-16 20:52:03 +02:00
|
|
|
}
|
|
|
|
}
|