From 154d0a9d82483d19eb26e75e1d5f974e20c0a71d Mon Sep 17 00:00:00 2001 From: ivanlele Date: Thu, 14 May 2026 18:51:13 +0300 Subject: [PATCH] Refactor verbosity handling and add global configuration for debug symbols --- CHANGELOG.md | 4 ++ crates/cli/src/commands/core.rs | 6 +-- crates/cli/src/commands/error.rs | 3 ++ crates/cli/src/commands/test.rs | 8 ++-- crates/cli/src/config/core.rs | 15 +------ crates/cli/src/config/error.rs | 3 -- crates/sdk/src/global.rs | 71 +++++++++++++++++++++++++++----- crates/sdk/src/program/core.rs | 11 +++-- crates/test/src/config.rs | 23 ++--------- crates/test/src/context.rs | 8 +--- 10 files changed, 88 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85db4c8..6499b4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [Unreleased] + +- Rewrote verbosity configuration in both `simplex test` and SDK to check if debug symbols should be included in program compilation. + ## [0.0.5] ### Simplex diff --git a/crates/cli/src/commands/core.rs b/crates/cli/src/commands/core.rs index c579aea..41a542a 100644 --- a/crates/cli/src/commands/core.rs +++ b/crates/cli/src/commands/core.rs @@ -51,9 +51,9 @@ pub struct TestFlags { /// Run tests regardless of failure #[arg(long = "no-fail-fast")] pub no_fail_fast: bool, - /// Log simplicity pruning stack trace - #[arg(short = 'v', long)] - pub verbose: bool, + /// Verbosity level for test output (-v for debug, -vv for trace) + #[arg(short = 'v', long, action = clap::ArgAction::Count)] + pub verbose: u8, /// Display one character per test instead of one line #[arg(short = 'q', long)] pub quiet: bool, diff --git a/crates/cli/src/commands/error.rs b/crates/cli/src/commands/error.rs index 38e27c1..b9f3d19 100644 --- a/crates/cli/src/commands/error.rs +++ b/crates/cli/src/commands/error.rs @@ -22,6 +22,9 @@ pub enum CommandError { #[error("IO error: {0}")] Io(#[from] std::io::Error), + + #[error("Verbosity level should be either -v or -vv, got: -v x {0}")] + BadVersbosityMode(u8), } #[derive(thiserror::Error, Debug)] diff --git a/crates/cli/src/commands/test.rs b/crates/cli/src/commands/test.rs index 0e4ca98..dd6cdca 100644 --- a/crates/cli/src/commands/test.rs +++ b/crates/cli/src/commands/test.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use std::process::Stdio; -use smplx_test::config::Verbosity; +use smplx_sdk::global::Verbosity; use smplx_test::{SMPLX_TEST_MARKER, TestConfig}; use super::core::{TestArguments, TestFlags}; @@ -20,10 +20,12 @@ impl Test { pub fn run(mut config: TestConfig, args: &TestArguments, flags: &TestFlags) -> Result<(), CommandError> { let cache_path = Self::get_test_config_cache_name()?; - if flags.verbose { - config.verbosity = Some(Verbosity(4)); + if flags.verbose > Verbosity::MAX_VERBOSITY_LEVEL { + return Err(CommandError::BadVersbosityMode(flags.verbose)); } + config.verbosity = std::cmp::max(config.verbosity, Verbosity::new(flags.verbose)); + config.to_file(&cache_path)?; let mut cargo_test_command = Self::build_cargo_test_command(&cache_path, args, flags); diff --git a/crates/cli/src/config/core.rs b/crates/cli/src/config/core.rs index 616f4a5..882c8df 100644 --- a/crates/cli/src/config/core.rs +++ b/crates/cli/src/config/core.rs @@ -3,8 +3,7 @@ use std::path::{Path, PathBuf}; use smplx_build::BuildConfig; use smplx_regtest::RegtestConfig; -use smplx_sdk::program::TrackerLogLevel; -use smplx_test::{TestConfig, config::Verbosity}; +use smplx_test::TestConfig; use super::error::ConfigError; @@ -67,11 +66,6 @@ impl Config { } fn validate(config: &Config) -> Result<(), ConfigError> { - match config.test.verbosity { - Some(verbosity) => Self::validate_verbosity(verbosity), - None => Ok(()), - }?; - match config.test.esplora.clone() { Some(esplora_config) => { Self::validate_network(&esplora_config.network)?; @@ -86,13 +80,6 @@ impl Config { } } - fn validate_verbosity(verbosity: Verbosity) -> Result<(), ConfigError> { - match TryInto::::try_into(verbosity) { - Ok(_) => Ok(()), - Err(val) => Err(ConfigError::BadVersbosityMode(val.0)), - } - } - fn validate_network(network: &String) -> Result<(), ConfigError> { if network != "Liquid" && network != "LiquidTestnet" && network != "ElementsRegtest" { return Err(ConfigError::BadNetworkName(network.clone())); diff --git a/crates/cli/src/config/error.rs b/crates/cli/src/config/error.rs index 7c362b1..d76ca7b 100644 --- a/crates/cli/src/config/error.rs +++ b/crates/cli/src/config/error.rs @@ -25,7 +25,4 @@ pub enum ConfigError { #[error("Path doesn't exist: '{0}'")] PathNotExists(PathBuf), - - #[error("Verbosity level should be either 1, 2, 3, 4, got: {0}")] - BadVersbosityMode(u64), } diff --git a/crates/sdk/src/global.rs b/crates/sdk/src/global.rs index b4a6e2e..f578267 100644 --- a/crates/sdk/src/global.rs +++ b/crates/sdk/src/global.rs @@ -1,22 +1,59 @@ use std::sync::OnceLock; +use serde::{Deserialize, Serialize}; + use crate::program::TrackerLogLevel; +static GLOBAL_CONFIG: OnceLock = OnceLock::new(); + /// A structure to represent the global configuration settings for the application. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, Default)] pub struct GlobalConfig { - log_level: TrackerLogLevel, + verbosity: Verbosity, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)] +/// An enumeration to represent the verbosity levels of the Simplicity execution logging. +pub enum Verbosity { + /// No logs will be printed. + #[default] + None = 0, + /// The debug mode + Debug = 1, + /// The trace mode + Trace = 2, } -impl Default for GlobalConfig { - fn default() -> Self { - Self { - log_level: TrackerLogLevel::Debug, +impl Verbosity { + /// The maximum allowed verbosity level. + pub const MAX_VERBOSITY_LEVEL: u8 = 2; + + /// Creates a `Verbosity` instance from the number of verbosity flags provided (e.g., -v, -vv). + #[must_use] + pub fn new(flags: u8) -> Self { + match flags { + 0 => Verbosity::None, + 1 => Verbosity::Debug, + _ => Verbosity::Trace, } } -} -static GLOBAL_CONFIG: OnceLock = OnceLock::new(); + /// Converts the `Verbosity` level to a corresponding `TrackerLogLevel`. + #[must_use] + pub fn tracker_log_level(&self) -> TrackerLogLevel { + match self { + Verbosity::None => TrackerLogLevel::None, + Verbosity::Debug => TrackerLogLevel::Debug, + Verbosity::Trace => TrackerLogLevel::Trace, + } + } + + /// Determines if the current verbosity level includes debug symbols. + #[must_use] + pub fn include_debug_symbols(&self) -> bool { + matches!(self, Verbosity::Debug | Verbosity::Trace) + } +} /// Sets the global configuration for the SDK. /// @@ -26,13 +63,25 @@ static GLOBAL_CONFIG: OnceLock = OnceLock::new(); /// /// # Errors /// Returns an error containing the newly created `GlobalConfig` if the global configuration has already been initialized. -pub fn set_global_config(log_level: TrackerLogLevel) -> Result<(), GlobalConfig> { - GLOBAL_CONFIG.set(GlobalConfig { log_level }) +pub fn set_global_config(verbosity: Verbosity) -> Result<(), GlobalConfig> { + GLOBAL_CONFIG.set(GlobalConfig { verbosity }) } /// Returns the default log level if `GLOBAL_CONFIG` is not initialized pub fn get_log_level() -> TrackerLogLevel { GLOBAL_CONFIG .get() - .map_or(GlobalConfig::default().log_level, |config| config.log_level) + .map_or(GlobalConfig::default().verbosity.tracker_log_level(), |config| { + config.verbosity.tracker_log_level() + }) +} + +/// Returns whether the global configuration includes debug symbols, +/// defaulting to `false` if `GLOBAL_CONFIG` is not initialized. +pub fn get_include_debug_symbols() -> bool { + GLOBAL_CONFIG + .get() + .map_or(GlobalConfig::default().verbosity.include_debug_symbols(), |config| { + config.verbosity.include_debug_symbols() + }) } diff --git a/crates/sdk/src/program/core.rs b/crates/sdk/src/program/core.rs index 5dd47f9..637e341 100644 --- a/crates/sdk/src/program/core.rs +++ b/crates/sdk/src/program/core.rs @@ -13,7 +13,7 @@ use simplicityhl::simplicity::{BitMachine, RedeemNode, Value, leaf_version}; use simplicityhl::tracker::DefaultTracker; use simplicityhl::{Parameters, WitnessTypes, WitnessValues}; -use crate::global::get_log_level; +use crate::global::{get_include_debug_symbols, get_log_level}; use super::arguments::ArgumentsTrait; use super::error::ProgramError; @@ -301,8 +301,13 @@ impl Program { } fn load(&self) -> Result { - let compiled = CompiledProgram::new(self.source, self.arguments.build_arguments(), true) - .map_err(ProgramError::Compilation)?; + let compiled = CompiledProgram::new( + self.source, + self.arguments.build_arguments(), + get_include_debug_symbols(), + ) + .map_err(ProgramError::Compilation)?; + Ok(compiled) } diff --git a/crates/test/src/config.rs b/crates/test/src/config.rs index f410c87..bacb551 100644 --- a/crates/test/src/config.rs +++ b/crates/test/src/config.rs @@ -7,7 +7,7 @@ use std::path::Path; use serde::{Deserialize, Serialize}; use smplx_regtest::RegtestConfig; -use smplx_sdk::program::TrackerLogLevel; +use smplx_sdk::global::Verbosity; use super::error::TestError; @@ -22,7 +22,7 @@ pub struct TestConfig { pub bitcoins: u64, pub esplora: Option, pub rpc: Option, - pub verbosity: Option, + pub verbosity: Verbosity, } #[derive(Debug, Default, Clone, Serialize, Deserialize)] @@ -38,23 +38,6 @@ pub struct RpcConfig { pub password: String, } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] -pub struct Verbosity(pub u64); - -impl TryInto for Verbosity { - type Error = Self; - - fn try_into(self) -> Result { - match self { - Verbosity(1) => Ok(TrackerLogLevel::None), - Verbosity(2) => Ok(TrackerLogLevel::Warning), - Verbosity(3) => Ok(TrackerLogLevel::Debug), - Verbosity(4) => Ok(TrackerLogLevel::Trace), - _ => Err(self), - } - } -} - impl TestConfig { pub fn from_file(path: impl AsRef) -> Result { let mut content = String::new(); @@ -97,7 +80,7 @@ impl Default for TestConfig { bitcoins: DEFAULT_BITCOINS, esplora: None, rpc: None, - verbosity: Some(Verbosity(3)), + verbosity: Verbosity::None, } } } diff --git a/crates/test/src/context.rs b/crates/test/src/context.rs index 1f3bacb..3a8e4c6 100644 --- a/crates/test/src/context.rs +++ b/crates/test/src/context.rs @@ -30,13 +30,7 @@ impl TestContext { let config = TestConfig::from_file(&config_path)?; // error is ignored because we assume that all tests use the same verbosity - let _ = set_global_config( - config - .verbosity - .expect("This will be set") - .try_into() - .expect("Validated in CLI"), - ); + let _ = set_global_config(config.verbosity); let (signer, provider_info, client) = Self::setup(&config)?;