diff --git a/iceoryx2-cal/Cargo.toml b/iceoryx2-cal/Cargo.toml index 2600d239b..55511bf88 100644 --- a/iceoryx2-cal/Cargo.toml +++ b/iceoryx2-cal/Cargo.toml @@ -22,6 +22,7 @@ iceoryx2-bb-threadsafe = { workspace = true } iceoryx2-bb-testing = { workspace = true } iceoryx2-pal-concurrency-sync = { workspace = true } +dirs = { workspace = true } once_cell = { workspace = true } lazy_static = { workspace = true } serde = { workspace = true } diff --git a/iceoryx2-cal/src/config_path/config_path.rs b/iceoryx2-cal/src/config_path/config_path.rs new file mode 100644 index 000000000..75d69d39a --- /dev/null +++ b/iceoryx2-cal/src/config_path/config_path.rs @@ -0,0 +1,25 @@ +// Copyright (c) 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache Software License 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license +// which is available at https://opensource.org/licenses/MIT. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT + +use dirs; + +pub trait ConfigPathProvider { + fn config_dir(&self) -> Option; +} + +pub struct DirsConfigPathProvider; + +impl ConfigPathProvider for DirsConfigPathProvider { + fn config_dir(&self) -> Option { + dirs::config_dir() + } +} diff --git a/iceoryx2-cal/src/config_path/mod.rs b/iceoryx2-cal/src/config_path/mod.rs new file mode 100644 index 000000000..53993e33b --- /dev/null +++ b/iceoryx2-cal/src/config_path/mod.rs @@ -0,0 +1,25 @@ +// Copyright (c) 2024 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache Software License 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license +// which is available at https://opensource.org/licenses/MIT. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT + +//! use iceoryx2_cal::config_path::config_dir; +//! +//! let config_dir = config_dir().unwrap(); +//! println!("Config dir: {:?}", config_dir); + +mod config_path; + +use crate::config_path::config_path::{ConfigPathProvider, DirsConfigPathProvider}; + +pub fn config_dir() -> Option { + let provider = DirsConfigPathProvider; + provider.config_dir() +} diff --git a/iceoryx2-cal/src/lib.rs b/iceoryx2-cal/src/lib.rs index 69b6a2ae8..1694b7422 100644 --- a/iceoryx2-cal/src/lib.rs +++ b/iceoryx2-cal/src/lib.rs @@ -11,6 +11,7 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT pub mod communication_channel; +pub mod config_path; pub mod dynamic_storage; pub mod event; pub mod hash; diff --git a/iceoryx2-cli/Cargo.toml b/iceoryx2-cli/Cargo.toml index 5c4a10e7f..c803b5b4f 100644 --- a/iceoryx2-cli/Cargo.toml +++ b/iceoryx2-cli/Cargo.toml @@ -41,6 +41,7 @@ iceoryx2-pal-posix = { workspace = true } iceoryx2-bb-posix = { workspace = true } iceoryx2-bb-system-types = { workspace = true } iceoryx2-bb-container = { workspace = true } +iceoryx2-cal = { workspace = true } anyhow = { workspace = true } better-panic = { workspace = true } diff --git a/iceoryx2-cli/iox2-config/src/cli.rs b/iceoryx2-cli/iox2-config/src/cli.rs index d6af1c26e..4dc524c02 100644 --- a/iceoryx2-cli/iox2-config/src/cli.rs +++ b/iceoryx2-cli/iox2-config/src/cli.rs @@ -30,10 +30,36 @@ pub struct Cli { pub action: Option, } +#[derive(Parser)] +#[command( + name = "iox2-config", + about = "Query information about iceoryx2 configuration", + long_about = None, + version = env!("CARGO_PKG_VERSION"), + disable_help_subcommand = true, + arg_required_else_help = false, + help_template = help_template("iox2 config show", false), +)] +pub struct Config { + #[clap(subcommand)] + pub action: Option, +} + +#[derive(Subcommand, Debug)] +pub enum ShowSubcommand { + #[clap(about = "Show system configuration")] + System, + #[clap(about = "Show current iceoryx2 configuration")] + Current, +} + #[derive(Subcommand)] pub enum Action { #[clap(about = "Show the currently used configuration")] - Show, + Show { + #[clap(subcommand)] + subcommand: Option, + }, #[clap(about = "Generate a default configuration file")] Generate, } diff --git a/iceoryx2-cli/iox2-config/src/commands.rs b/iceoryx2-cli/iox2-config/src/commands.rs index 3d19e04a5..15e8e65e5 100644 --- a/iceoryx2-cli/iox2-config/src/commands.rs +++ b/iceoryx2-cli/iox2-config/src/commands.rs @@ -16,6 +16,7 @@ use dialoguer::Confirm; use enum_iterator::all; use iceoryx2::config::Config; use iceoryx2_bb_posix::system_configuration::*; +use iceoryx2_cal::config_path::config_dir; use std::fs::{self, File}; use std::io::Write; use std::panic::catch_unwind; @@ -106,14 +107,25 @@ pub fn print_system_configuration() { } } -pub fn show() -> Result<()> { +pub fn show_system_config() -> Result<()> { print_system_configuration(); Ok(()) } +pub fn show_current_config() -> Result<()> { + let config = Config::global_config(); + let json_config = serde_json::to_value(&config).unwrap_or_else(|_| serde_json::json!({})); + let toml_config = toml::to_string_pretty(&json_config) + .unwrap_or_else(|_| "Failed to convert to TOML".to_string()); + + println!("{}", toml_config); + + Ok(()) +} + pub fn generate() -> Result<()> { - let config_dir = dirs::config_dir().unwrap().join("iceoryx2"); + let config_dir = config_dir().unwrap().join("iceoryx2"); fs::create_dir_all(&config_dir)?; let default_file_path = config_dir.join("config.toml"); diff --git a/iceoryx2-cli/iox2-config/src/main.rs b/iceoryx2-cli/iox2-config/src/main.rs index 178377d83..e1ce94b2c 100644 --- a/iceoryx2-cli/iox2-config/src/main.rs +++ b/iceoryx2-cli/iox2-config/src/main.rs @@ -17,6 +17,8 @@ use clap::CommandFactory; use clap::Parser; use cli::Action; use cli::Cli; +use cli::Config; +use cli::ShowSubcommand; use iceoryx2_bb_log::{set_log_level, LogLevel}; #[cfg(not(debug_assertions))] @@ -44,11 +46,23 @@ fn main() { Ok(cli) => { if let Some(action) = cli.action { match action { - Action::Show => { - if let Err(e) = commands::show() { - eprintln!("Failed to show options: {}", e); + Action::Show { subcommand } => match subcommand { + Some(ShowSubcommand::System) => { + if let Err(e) = commands::show_system_config() { + eprintln!("Failed to show options: {}", e); + } } - } + Some(ShowSubcommand::Current) => { + if let Err(e) = commands::show_current_config() { + eprintln!("Failed to show options: {}", e); + } + } + None => { + Config::command() + .print_help() + .expect("Failed to print help"); + } + }, Action::Generate => { if let Err(e) = commands::generate() { eprintln!("Failed to generate default configuration: {}", e); diff --git a/iceoryx2/Cargo.toml b/iceoryx2/Cargo.toml index fa71108d1..bf052f7b3 100644 --- a/iceoryx2/Cargo.toml +++ b/iceoryx2/Cargo.toml @@ -35,7 +35,6 @@ cdr = { workspace = true } toml = { workspace = true } sha1_smol = { workspace = true } tiny-fn = { workspace = true } -dirs = { workspace = true } [dev-dependencies] iceoryx2-bb-testing = { workspace = true } diff --git a/iceoryx2/src/config.rs b/iceoryx2/src/config.rs index 9f83e3e0c..56cb103f7 100644 --- a/iceoryx2/src/config.rs +++ b/iceoryx2/src/config.rs @@ -69,20 +69,23 @@ //! # } //! ``` -use dirs; use iceoryx2_bb_container::semantic_string::SemanticString; use iceoryx2_bb_elementary::lazy_singleton::*; use iceoryx2_bb_posix::{file::FileBuilder, shared_memory::AccessMode}; use iceoryx2_bb_system_types::file_name::FileName; use iceoryx2_bb_system_types::file_path::FilePath; use iceoryx2_bb_system_types::path::Path; +use iceoryx2_cal::config_path::config_dir; use serde::{Deserialize, Serialize}; -use std::{os::unix::ffi::OsStrExt, time::Duration}; +use std::time::Duration; use iceoryx2_bb_log::{fail, trace, warn}; use crate::service::port_factory::publisher::UnableToDeliverStrategy; +/// Path to the default config file +pub const DEFAULT_CONFIG_FILE: &[u8] = b"config/iceoryx2.toml"; + /// Failures occurring while creating a new [`Config`] object with [`Config::from_file()`] or /// [`Config::setup_global_config_from_file()`] #[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)] @@ -394,21 +397,21 @@ impl Config { /// config was already populated. pub fn global_config() -> &'static Config { - if !ICEORYX2_CONFIG.is_initialized() - && Config::setup_global_config_from_file(unsafe { - &FilePath::new_unchecked( - dirs::config_dir() - .unwrap() - .join("iceoryx2") - .join("config.toml") - .as_os_str() - .as_bytes(), - ) - }) - .is_err() - { - warn!(from "Config::global_config()", "Default config file found but unable to read data, populate config with default values."); - ICEORYX2_CONFIG.set_value(Config::default()); + if !ICEORYX2_CONFIG.is_initialized() { + let config_path = config_dir().unwrap().join("iceoryx2").join("config.toml"); + + match FilePath::new(config_path.as_os_str().as_encoded_bytes()) { + Ok(path) => { + if Config::setup_global_config_from_file(&path).is_err() { + warn!(from "Config::global_config()", "Default config file found but unable to read data, populate config with default values."); + ICEORYX2_CONFIG.set_value(Config::default()); + } + } + Err(e) => { + warn!(from "Config::global_config()", "Error: {:?}", e); + ICEORYX2_CONFIG.set_value(Config::default()); + } + } } ICEORYX2_CONFIG.get()