From 41c47048be384b5cf99e30b32f7c13bf177c9971 Mon Sep 17 00:00:00 2001 From: Michael Mikovsky <77305074+Astatin3@users.noreply.github.com> Date: Wed, 17 Dec 2025 10:38:37 -0700 Subject: [PATCH] Implement clap parsing for unshell metadata --- unshell-server/src/config/mod.rs | 36 ++++++++++++++++++++++++-------- unshell-server/src/main.rs | 10 ++++++--- unshell-server/src/server/mod.rs | 20 ++++++++++++------ 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/unshell-server/src/config/mod.rs b/unshell-server/src/config/mod.rs index 2029800..524f2fb 100644 --- a/unshell-server/src/config/mod.rs +++ b/unshell-server/src/config/mod.rs @@ -5,16 +5,17 @@ use std::{ path::{Path, PathBuf}, }; -use unshell_lib::debug; +use unshell_lib::{debug, info}; #[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct ComponentMetadata { +struct ComponentMetadata { name: String, description: Option, version: Option, authors: Option>, // Struct to contain build information + #[serde(default)] build_config: BuildConfig, // Other components that can be pointed to by this component @@ -23,7 +24,7 @@ pub struct ComponentMetadata { // config: Option>, } -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] +#[derive(Default, Debug, Clone, serde::Deserialize, serde::Serialize)] struct BuildConfig { // Cargo feature list of a component // (Name, Description) @@ -58,7 +59,13 @@ enum ConfigStructField { // ... } -pub fn load_config(path: &PathBuf) -> Result, Box> { +#[derive(Clone, Debug)] +pub struct ComponentState { + metadata: ComponentMetadata, + path: PathBuf, +} + +pub fn load_config(path: &PathBuf) -> Result, Box> { let path_absolute = fs::canonicalize(path.clone())?; debug!("Loading data from path: `{}`", path_absolute); @@ -68,11 +75,16 @@ pub fn load_config(path: &PathBuf) -> Result, Box(&config_str)?; - if config.child_components.is_empty() { - Ok(vec![config]) - } else { - let parent_path = path_absolute.parent().expect("Path must have parent"); + info!("Loaded component `{}`", config.name); + let parent_path = path_absolute.parent().expect("Path must have parent"); + + if config.child_components.is_empty() { + Ok(vec![ComponentState { + metadata: config, + path: PathBuf::from(parent_path), + }]) + } else { let mut config_vec = vec![]; // Load each child component @@ -82,7 +94,13 @@ pub fn load_config(path: &PathBuf) -> Result, Box>, + pub config: Vec, } #[tokio::main] -async fn main() { +async fn main() -> Result<(), Box> { let args = Args::parse(); unshell_lib::logger::PrettyLogger::init_output(|message| { @@ -35,7 +37,9 @@ async fn main() { } }); - let database = Server::new(args.database_name); + let database = Server::new(args.config, args.database_name)?; start_api(&format!("{}:{}", args.host, args.port), database).await; + + Ok(()) } diff --git a/unshell-server/src/server/mod.rs b/unshell-server/src/server/mod.rs index 90f10e2..ba55dbb 100644 --- a/unshell-server/src/server/mod.rs +++ b/unshell-server/src/server/mod.rs @@ -1,20 +1,28 @@ +use std::{error::Error, path::PathBuf}; + mod database; mod manager; #[derive(Clone)] pub struct Server { - pub config: Vec, + pub component_configs: Vec, // pub manager: Arc>, pub db: sled::Db, } impl Server { - pub fn new(database: String) -> Self { - Self { - config: Vec::new(), - // manager: Manager::start(&SERVER_CONFIG, Vec::new()), - db: sled::open(database).expect("Failed to open database"), + pub fn new(config_paths: Vec, database: String) -> Result> { + let mut component_configs: Vec = Vec::new(); + + for config in &config_paths { + component_configs.extend(crate::config::load_config(config)?); } + + Ok(Self { + component_configs, + // manager: Manager::start(&SERVER_CONFIG, Vec::new()), + db: sled::open(database)?, + }) } }