diff --git a/src/presentation/commands/constants.rs b/src/presentation/commands/constants.rs new file mode 100644 index 00000000..325033e2 --- /dev/null +++ b/src/presentation/commands/constants.rs @@ -0,0 +1,59 @@ +//! Constants for command handlers +//! +//! This module provides centralized configuration constants used across command handlers. +//! These constants help eliminate duplicate magic numbers and make configuration explicit. +//! +//! ## Constants +//! +//! - [`DEFAULT_LOCK_TIMEOUT`]: Default timeout for file lock operations in repository +//! - [`DEFAULT_VERBOSITY`]: Default verbosity level for user output +//! +//! ## Benefits +//! +//! - Eliminates duplicate magic numbers across command handlers +//! - Makes configuration values explicit and discoverable +//! - Easier to adjust behavior without searching through code +//! - Better documentation for why specific values are used +//! +//! ## Usage Example +//! +//! ```rust +//! use torrust_tracker_deployer_lib::presentation::commands::constants::{DEFAULT_LOCK_TIMEOUT, DEFAULT_VERBOSITY}; +//! use torrust_tracker_deployer_lib::infrastructure::persistence::repository_factory::RepositoryFactory; +//! use torrust_tracker_deployer_lib::presentation::user_output::UserOutput; +//! +//! // Use default lock timeout for repository operations +//! let repository_factory = RepositoryFactory::new(DEFAULT_LOCK_TIMEOUT); +//! +//! // Use default verbosity for user output +//! let mut output = UserOutput::new(DEFAULT_VERBOSITY); +//! ``` + +use std::time::Duration; + +use crate::presentation::user_output::VerbosityLevel; + +/// Default timeout for file lock operations in repository +/// +/// This timeout is used when acquiring file locks during repository operations +/// to prevent indefinite blocking. A 30-second timeout provides a balance between: +/// +/// - Allowing sufficient time for legitimate operations to complete +/// - Preventing indefinite hangs in case of issues +/// - Providing reasonable user experience (users won't wait forever) +/// +/// This value is used across all command handlers that interact with the repository. +pub const DEFAULT_LOCK_TIMEOUT: Duration = Duration::from_secs(30); + +/// Default verbosity level for user output +/// +/// This verbosity level is used as the default for user-facing output across all commands. +/// `VerbosityLevel::Normal` provides essential progress and results without overwhelming +/// users with details, making it suitable for typical command execution. +/// +/// Users can override this default through command-line flags if they need: +/// - Less output (Quiet) for automation/scripting +/// - More output (Verbose/Debug) for troubleshooting +/// +/// This value is used across all command handlers for consistent user experience. +pub const DEFAULT_VERBOSITY: VerbosityLevel = VerbosityLevel::Normal; diff --git a/src/presentation/commands/create/subcommands/environment.rs b/src/presentation/commands/create/subcommands/environment.rs index 84affa35..b7ea6412 100644 --- a/src/presentation/commands/create/subcommands/environment.rs +++ b/src/presentation/commands/create/subcommands/environment.rs @@ -5,12 +5,12 @@ use std::path::Path; use std::sync::Arc; -use std::time::Duration; use crate::application::command_handlers::create::config::EnvironmentCreationConfig; use crate::application::command_handlers::create::CreateCommandHandler; use crate::infrastructure::persistence::repository_factory::RepositoryFactory; -use crate::presentation::user_output::{UserOutput, VerbosityLevel}; +use crate::presentation::commands::constants::{DEFAULT_LOCK_TIMEOUT, DEFAULT_VERBOSITY}; +use crate::presentation::user_output::UserOutput; use crate::shared::{Clock, SystemClock}; use super::super::config_loader::ConfigLoader; @@ -51,7 +51,7 @@ pub fn handle_environment_creation( working_dir: &Path, ) -> Result<(), CreateSubcommandError> { // Create user output with default stdout/stderr channels - let mut output = UserOutput::new(VerbosityLevel::Normal); + let mut output = UserOutput::new(DEFAULT_VERBOSITY); // Display initial progress (to stderr) output.progress(&format!( @@ -72,7 +72,7 @@ pub fn handle_environment_creation( // Step 2: Create repository for environment persistence // Use the working directory from CLI args (supports testing and custom locations) - let repository_factory = RepositoryFactory::new(Duration::from_secs(30)); + let repository_factory = RepositoryFactory::new(DEFAULT_LOCK_TIMEOUT); let repository = repository_factory.create(working_dir.to_path_buf()); // Step 3: Create clock for timing information diff --git a/src/presentation/commands/create/subcommands/template.rs b/src/presentation/commands/create/subcommands/template.rs index be28f14f..104c75a5 100644 --- a/src/presentation/commands/create/subcommands/template.rs +++ b/src/presentation/commands/create/subcommands/template.rs @@ -6,7 +6,8 @@ use std::path::Path; use crate::application::command_handlers::create::config::EnvironmentCreationConfig; -use crate::presentation::user_output::{UserOutput, VerbosityLevel}; +use crate::presentation::commands::constants::DEFAULT_VERBOSITY; +use crate::presentation::user_output::UserOutput; use super::super::errors::CreateSubcommandError; @@ -34,7 +35,7 @@ use super::super::errors::CreateSubcommandError; #[allow(clippy::result_large_err)] // Error contains detailed context for user guidance pub fn handle_template_generation(output_path: &Path) -> Result<(), CreateSubcommandError> { // Create user output for progress messages - let mut output = UserOutput::new(VerbosityLevel::Normal); + let mut output = UserOutput::new(DEFAULT_VERBOSITY); output.progress("Generating configuration template..."); diff --git a/src/presentation/commands/destroy/handler.rs b/src/presentation/commands/destroy/handler.rs index 46dbf324..b09af30c 100644 --- a/src/presentation/commands/destroy/handler.rs +++ b/src/presentation/commands/destroy/handler.rs @@ -3,12 +3,11 @@ //! This module handles the destroy command execution at the presentation layer, //! including environment validation, repository initialization, and user interaction. -use std::time::Duration; - use crate::application::command_handlers::DestroyCommandHandler; use crate::domain::environment::name::EnvironmentName; use crate::infrastructure::persistence::repository_factory::RepositoryFactory; -use crate::presentation::user_output::{UserOutput, VerbosityLevel}; +use crate::presentation::commands::constants::{DEFAULT_LOCK_TIMEOUT, DEFAULT_VERBOSITY}; +use crate::presentation::user_output::UserOutput; use super::errors::DestroySubcommandError; @@ -55,7 +54,7 @@ pub fn handle_destroy_command( working_dir: &std::path::Path, ) -> Result<(), DestroySubcommandError> { // Create user output with default stdout/stderr channels - let mut output = UserOutput::new(VerbosityLevel::Normal); + let mut output = UserOutput::new(DEFAULT_VERBOSITY); // Display initial progress (to stderr) output.progress(&format!("Destroying environment '{environment_name}'...")); @@ -71,7 +70,7 @@ pub fn handle_destroy_command( })?; // Create repository for loading environment state - let repository_factory = RepositoryFactory::new(Duration::from_secs(30)); + let repository_factory = RepositoryFactory::new(DEFAULT_LOCK_TIMEOUT); let repository = repository_factory.create(working_dir.to_path_buf()); // Create clock for timing information diff --git a/src/presentation/commands/mod.rs b/src/presentation/commands/mod.rs index d7a7d029..0173aab9 100644 --- a/src/presentation/commands/mod.rs +++ b/src/presentation/commands/mod.rs @@ -8,6 +8,7 @@ use crate::presentation::cli::Commands; use crate::presentation::errors::CommandError; // Re-export command modules +pub mod constants; pub mod create; pub mod destroy;