Implement clap parsing for unshell metadata

This commit is contained in:
Michael Mikovsky
2025-12-17 10:38:37 -07:00
parent f8acdfb2dd
commit 41c47048be
3 changed files with 48 additions and 18 deletions
+27 -9
View File
@@ -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<String>,
version: Option<String>,
authors: Option<Vec<String>>,
// 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<HashMap<String, ConfigStructField>>,
}
#[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<Vec<ComponentMetadata>, Box<dyn Error>> {
#[derive(Clone, Debug)]
pub struct ComponentState {
metadata: ComponentMetadata,
path: PathBuf,
}
pub fn load_config(path: &PathBuf) -> Result<Vec<ComponentState>, Box<dyn Error>> {
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<Vec<ComponentMetadata>, Box<dyn Err
// Load config from String
let config = toml::from_str::<ComponentMetadata>(&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<Vec<ComponentMetadata>, Box<dyn Err
config_vec.append(&mut config);
}
config_vec.insert(0, config);
config_vec.insert(
0,
ComponentState {
metadata: config,
path: PathBuf::from(parent_path),
},
);
Ok(config_vec)
}
+7 -3
View File
@@ -1,3 +1,5 @@
use std::{error::Error, path::PathBuf};
use unshell_server::{Server, start_api};
use clap::Parser;
@@ -22,11 +24,11 @@ pub struct Args {
/// Load config from path
#[clap(short, long, value_parser)]
pub config: Option<Vec<String>>,
pub config: Vec<PathBuf>,
}
#[tokio::main]
async fn main() {
async fn main() -> Result<(), Box<dyn Error>> {
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(())
}
+14 -6
View File
@@ -1,20 +1,28 @@
use std::{error::Error, path::PathBuf};
mod database;
mod manager;
#[derive(Clone)]
pub struct Server {
pub config: Vec<crate::config::ComponentMetadata>,
pub component_configs: Vec<crate::config::ComponentState>,
// pub manager: Arc<Mutex<Manager>>,
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<PathBuf>, database: String) -> Result<Self, Box<dyn Error>> {
let mut component_configs: Vec<crate::config::ComponentState> = 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)?,
})
}
}