0.5.1-pre.006

This commit is contained in:
2026-08-10 02:44:24 +02:00
parent b6a286a4df
commit 34a670eaec
72 changed files with 5589 additions and 1932 deletions

View File

@@ -1,8 +1,14 @@
<!-- file: kb-app-demo-desktop/CHANGELOG.md -->
<!-- version: 45 -->
<!-- version: 46 -->
# CHANGELOG — kb-app-demo-desktop
## `0.5.1-pre.006`
- remplace `config/app.config.json` par la composition dédiée `config/kb-app-demo-desktop.default.config.json`, sélectionnable via `KB_APP_DEMO_DESKTOP_CONFIG_PATH` ;
- résout les profils transport/listeners partagés via `ks-config` et sélectionne explicitement le profil logging déclaré par la composition ;
- conserve les contrats runtime et payloads Tauri actuels jusqu'au chantier public/diagnostic de `pre.008`.
## `0.5.1-pre.005`
- charge séparément `config/app.config.json` et `config/logging.config.json` ;

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/app_state.rs
// version: 13
// version: 14
//! Shared Tauri application state and startup initialization.
@@ -31,15 +31,26 @@ impl crate::AppState {
/// Initializes configuration, logging and shared runtime state.
pub(crate) fn initialize() -> ks_core::Result<crate::AppState> {
let config_path = resolve_config_path();
let logging_config_path = resolve_logging_config_path();
let workspace_root = crate::workspace_root_dir();
let app_config = match ks_config::read_config_json_file_with_environment(
let composed = match ks_config::read_composed_app_config_with_environment(
&config_path,
&workspace_root,
) {
std::result::Result::Ok(config) => config,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let composition_profile = match ks_config::active_composition_profile(&composed.composition)
{
std::result::Result::Ok(profile) => profile.clone(),
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let logging_source_path = ks_config::resolve_composition_source_path(
&workspace_root,
composed.composition.sources.logging.as_str(),
);
let logging_config_path =
resolve_logging_config_path(&workspace_root, &logging_source_path);
let app_config = composed.app_config;
let active_profile = match ks_config::active_profile(&app_config) {
std::result::Result::Ok(profile) => profile.clone(),
std::result::Result::Err(error) => return std::result::Result::Err(error),
@@ -51,7 +62,16 @@ impl crate::AppState {
std::result::Result::Ok(config) => config,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let logging_config = match ks_logging::active_logging_profile(&logging_document) {
for profile in &composed.composition.profiles {
match ks_logging::logging_profile(&logging_document, profile.logging_profile.as_str()) {
std::result::Result::Ok(_) => (),
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
}
let logging_config = match ks_logging::logging_profile(
&logging_document,
composition_profile.logging_profile.as_str(),
) {
std::result::Result::Ok(profile) => profile.clone(),
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
@@ -217,23 +237,38 @@ impl crate::AppState {
}
fn resolve_config_path() -> std::path::PathBuf {
let configured = std::env::var("KS_CONFIG_PATH").ok();
let configured = std::env::var("KB_APP_DEMO_DESKTOP_CONFIG_PATH").ok();
return resolve_config_path_from_value(configured.as_deref());
}
fn resolve_logging_config_path() -> std::path::PathBuf {
fn resolve_logging_config_path(
workspace_root: &std::path::Path,
composition_default: &std::path::Path,
) -> std::path::PathBuf {
let configured = std::env::var("KS_LOGGING_CONFIG_PATH").ok();
return resolve_logging_config_path_from_value(configured.as_deref());
return resolve_logging_config_path_from_value(
workspace_root,
configured.as_deref(),
composition_default,
);
}
fn resolve_logging_config_path_from_value(value: std::option::Option<&str>) -> std::path::PathBuf {
fn resolve_logging_config_path_from_value(
workspace_root: &std::path::Path,
value: std::option::Option<&str>,
composition_default: &std::path::Path,
) -> std::path::PathBuf {
if let std::option::Option::Some(configured) = value {
let trimmed = configured.trim();
if !trimmed.is_empty() {
return std::path::PathBuf::from(trimmed);
let path = std::path::PathBuf::from(trimmed);
if path.is_absolute() {
return path;
}
return workspace_root.join(path);
}
}
return crate::workspace_root_dir().join("config/logging.config.json");
return composition_default.to_path_buf();
}
fn resolve_config_path_from_value(value: std::option::Option<&str>) -> std::path::PathBuf {
@@ -243,26 +278,29 @@ fn resolve_config_path_from_value(value: std::option::Option<&str>) -> std::path
return std::path::PathBuf::from(trimmed);
}
}
return crate::workspace_root_dir().join("config/app.config.json");
return crate::workspace_root_dir().join("config/kb-app-demo-desktop.default.config.json");
}
#[cfg(test)]
mod tests {
#[test]
fn resolve_config_path_uses_workspace_default_by_default() {
fn resolve_config_path_uses_desktop_composition_by_default() {
let path = super::resolve_config_path_from_value(std::option::Option::None);
assert_eq!(
path.file_name().and_then(std::ffi::OsStr::to_str),
std::option::Option::Some("app.config.json")
std::option::Option::Some("kb-app-demo-desktop.default.config.json")
);
}
#[test]
fn resolve_logging_config_path_uses_workspace_default_by_default() {
let path = super::resolve_logging_config_path_from_value(std::option::Option::None);
assert_eq!(
path.file_name().and_then(std::ffi::OsStr::to_str),
std::option::Option::Some("logging.config.json")
fn logging_path_uses_composition_source_without_override() {
let root = std::path::Path::new("/workspace");
let fallback = root.join("config/logging.config.json");
let path = super::resolve_logging_config_path_from_value(
root,
std::option::Option::None,
&fallback,
);
assert_eq!(path, fallback);
}
}

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/demo_execution_solana_core.rs
// version: 15
// version: 16
//! Tauri adapter for bounded Solana Core execution on Devnet.
@@ -850,11 +850,12 @@ fn memo_summary_payload(
mod tests {
#[test]
fn example_config_exposes_one_devnet_execution_profile() {
let config =
match ks_config::parse_config_json(include_str!("../../config/app.config.json")) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("example config parse failed: {error}"),
};
let config = match ks_config::parse_config_json(include_str!(
"../../test-fixtures/config/resolved.app.config.json"
)) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("example config parse failed: {error}"),
};
let profiles = super::devnet_profile_options(&config);
assert_eq!(profiles.len(), 1);
assert_eq!(profiles[0].name, "local_devnet");
@@ -864,11 +865,12 @@ mod tests {
#[test]
fn profile_selection_rejects_mainnet_profiles() {
let config =
match ks_config::parse_config_json(include_str!("../../config/app.config.json")) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("example config parse failed: {error}"),
};
let config = match ks_config::parse_config_json(include_str!(
"../../test-fixtures/config/resolved.app.config.json"
)) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("example config parse failed: {error}"),
};
assert!(crate::select_devnet_profile(&config, "local_devnet").is_ok());
assert!(crate::select_devnet_profile(&config, "mainnet").is_err());
}

View File

@@ -286,7 +286,9 @@ pub(crate) fn demo_spl_token_2022_fixture(
let decimals = match decimals_text.parse::<u8>() {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => {
return std::result::Result::Err(format!("invalid KS_PUBLIC_DEVNET_TOKEN_2022_DECIMALS value: {error}"));
return std::result::Result::Err(format!(
"invalid KS_PUBLIC_DEVNET_TOKEN_2022_DECIMALS value: {error}"
));
},
};
return std::result::Result::Ok(crate::DemoSplToken2022FixturePayload {

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/tauri.rs
// version: 36
// version: 37
//! Tauri runtime assembly and private command wrappers.
@@ -20,7 +20,7 @@ pub fn run() -> ks_core::Result<()> {
};
tracing::info!(
target: crate::TRACING_TARGET,
config_path = app_state.config_path(),
composition_config_path = app_state.config_path(),
logging_config_path = app_state.logging_config_path(),
active_profile = app_state.active_profile().name.as_str(),
logging_routes = app_state.logging_route_count(),