Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions src/presentation/commands/constants.rs
Original file line number Diff line number Diff line change
@@ -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;
8 changes: 4 additions & 4 deletions src/presentation/commands/create/subcommands/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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!(
Expand All @@ -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
Expand Down
5 changes: 3 additions & 2 deletions src/presentation/commands/create/subcommands/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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...");

Expand Down
9 changes: 4 additions & 5 deletions src/presentation/commands/destroy/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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}'..."));
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/presentation/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down