Skip to content

Commit 863f465

Browse files
Copilotjosecelano
andcommitted
refactor: organize create command into handler and subcommands
Co-authored-by: josecelano <58816+josecelano@users.noreply.github.com>
1 parent 6cc2ca0 commit 863f465

File tree

5 files changed

+131
-98
lines changed

5 files changed

+131
-98
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//! Create Command Handler
2+
//!
3+
//! This module handles the create command execution at the presentation layer,
4+
//! routing between different subcommands (environment creation or template generation).
5+
6+
use std::path::Path;
7+
8+
use crate::presentation::cli::commands::CreateAction;
9+
10+
use super::errors::CreateSubcommandError;
11+
use super::subcommands;
12+
13+
/// Handle the create command with its subcommands
14+
///
15+
/// This function routes between different create subcommands (environment or template).
16+
///
17+
/// # Arguments
18+
///
19+
/// * `action` - The create action to perform (environment creation or template generation)
20+
/// * `working_dir` - Root directory for environment data storage
21+
///
22+
/// # Returns
23+
///
24+
/// Returns `Ok(())` on success, or a `CreateSubcommandError` on failure.
25+
///
26+
/// # Errors
27+
///
28+
/// Returns an error if the subcommand execution fails.
29+
#[allow(clippy::result_large_err)] // Error contains detailed context for user guidance
30+
pub fn handle_create_command(
31+
action: CreateAction,
32+
working_dir: &Path,
33+
) -> Result<(), CreateSubcommandError> {
34+
match action {
35+
CreateAction::Environment { env_file } => {
36+
subcommands::handle_environment_creation(&env_file, working_dir)
37+
}
38+
CreateAction::Template { output_path } => {
39+
let template_path = output_path.unwrap_or_else(CreateAction::default_template_path);
40+
subcommands::handle_template_generation(&template_path)
41+
}
42+
}
43+
}

src/presentation/commands/create/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
//!
1616
//! - `config_loader` - Figment integration for JSON configuration loading
1717
//! - `errors` - Presentation layer error types with `.help()` methods
18-
//! - `subcommand` - Main command handler orchestrating the workflow
18+
//! - `handler` - Main command handler routing between subcommands
19+
//! - `subcommands` - Individual subcommand implementations (environment, template)
1920
//!
2021
//! ## Usage Example
2122
//!
@@ -36,12 +37,13 @@
3637
3738
pub mod config_loader;
3839
pub mod errors;
39-
pub mod subcommand;
40+
pub mod handler;
41+
pub mod subcommands;
4042

4143
#[cfg(test)]
4244
mod tests;
4345

4446
// Re-export commonly used types for convenience
4547
pub use config_loader::ConfigLoader;
4648
pub use errors::{ConfigFormat, CreateSubcommandError};
47-
pub use subcommand::handle_create_command;
49+
pub use handler::handle_create_command;

src/presentation/commands/create/subcommand.rs renamed to src/presentation/commands/create/subcommands/environment.rs

Lines changed: 7 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
//! Create Subcommand Handler
1+
//! Environment Creation Subcommand
22
//!
3-
//! This module handles the create subcommand execution at the presentation layer,
4-
//! including configuration file loading, argument processing, user interaction,
5-
//! and command execution.
3+
//! This module handles the environment creation subcommand for creating
4+
//! deployment environments from configuration files.
65
76
use std::path::Path;
87
use std::sync::Arc;
@@ -11,99 +10,11 @@ use std::time::Duration;
1110
use crate::application::command_handlers::create::CreateCommandHandler;
1211
use crate::domain::config::EnvironmentCreationConfig;
1312
use crate::infrastructure::persistence::repository_factory::RepositoryFactory;
14-
use crate::presentation::cli::commands::CreateAction;
1513
use crate::presentation::user_output::{UserOutput, VerbosityLevel};
1614
use crate::shared::{Clock, SystemClock};
1715

18-
use super::config_loader::ConfigLoader;
19-
use super::errors::CreateSubcommandError;
20-
21-
/// Handle the create command with its subcommands
22-
///
23-
/// This function routes between different create subcommands (environment or template).
24-
///
25-
/// # Arguments
26-
///
27-
/// * `action` - The create action to perform (environment creation or template generation)
28-
/// * `working_dir` - Root directory for environment data storage
29-
///
30-
/// # Returns
31-
///
32-
/// Returns `Ok(())` on success, or a `CreateSubcommandError` on failure.
33-
///
34-
/// # Errors
35-
///
36-
/// Returns an error if the subcommand execution fails.
37-
#[allow(clippy::result_large_err)] // Error contains detailed context for user guidance
38-
pub fn handle_create_command(
39-
action: CreateAction,
40-
working_dir: &Path,
41-
) -> Result<(), CreateSubcommandError> {
42-
match action {
43-
CreateAction::Environment { env_file } => {
44-
handle_environment_creation(&env_file, working_dir)
45-
}
46-
CreateAction::Template { output_path } => {
47-
let template_path = output_path.unwrap_or_else(CreateAction::default_template_path);
48-
handle_template_generation(&template_path)
49-
}
50-
}
51-
}
52-
53-
/// Handle template generation
54-
///
55-
/// This function generates a configuration template file with placeholder values
56-
/// that users can edit to create their own environment configurations.
57-
///
58-
/// # Arguments
59-
///
60-
/// * `output_path` - Path where the template file should be created
61-
///
62-
/// # Returns
63-
///
64-
/// Returns `Ok(())` on success, or a `CreateSubcommandError` on failure.
65-
///
66-
/// # Errors
67-
///
68-
/// Returns an error if template file creation fails.
69-
#[allow(clippy::result_large_err)] // Error contains detailed context for user guidance
70-
fn handle_template_generation(output_path: &Path) -> Result<(), CreateSubcommandError> {
71-
// Create user output for progress messages
72-
let mut output = UserOutput::new(VerbosityLevel::Normal);
73-
74-
output.progress("Generating configuration template...");
75-
76-
// Call existing domain method - template generation implemented in PR #48
77-
// This is async, so we need to use tokio runtime
78-
tokio::runtime::Runtime::new()
79-
.expect("Failed to create tokio runtime")
80-
.block_on(async {
81-
EnvironmentCreationConfig::generate_template_file(output_path)
82-
.await
83-
.map_err(CreateSubcommandError::TemplateGenerationFailed)
84-
})?;
85-
86-
output.success(&format!(
87-
"Configuration template generated: {}",
88-
output_path.display()
89-
));
90-
println!();
91-
println!("Next steps:");
92-
println!("1. Edit the template file and replace placeholder values:");
93-
println!(" - REPLACE_WITH_ENVIRONMENT_NAME: Choose a unique environment name (e.g., 'dev', 'staging')");
94-
println!(" - REPLACE_WITH_SSH_PRIVATE_KEY_PATH: Path to your SSH private key");
95-
println!(" - REPLACE_WITH_SSH_PUBLIC_KEY_PATH: Path to your SSH public key");
96-
println!("2. Review default values:");
97-
println!(" - username: 'torrust' (can be changed if needed)");
98-
println!(" - port: 22 (standard SSH port)");
99-
println!("3. Create the environment:");
100-
println!(
101-
" torrust-tracker-deployer create environment --env-file {}",
102-
output_path.display()
103-
);
104-
105-
Ok(())
106-
}
16+
use super::super::config_loader::ConfigLoader;
17+
use super::super::errors::CreateSubcommandError;
10718

10819
/// Handle environment creation from configuration file
10920
///
@@ -135,7 +46,7 @@ fn handle_template_generation(output_path: &Path) -> Result<(), CreateSubcommand
13546
/// loaded, parsed, validated, or if the create command execution fails.
13647
/// All errors include detailed context and actionable troubleshooting guidance.
13748
#[allow(clippy::result_large_err)] // Error contains detailed context for user guidance
138-
fn handle_environment_creation(
49+
pub fn handle_environment_creation(
13950
env_file: &Path,
14051
working_dir: &Path,
14152
) -> Result<(), CreateSubcommandError> {
@@ -369,3 +280,4 @@ mod tests {
369280
);
370281
}
371282
}
283+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//! Create Subcommands Module
2+
//!
3+
//! This module contains the individual subcommands for the create command.
4+
5+
pub mod environment;
6+
pub mod template;
7+
8+
// Re-export subcommand handlers for convenience
9+
pub use environment::handle_environment_creation;
10+
pub use template::handle_template_generation;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//! Template Generation Subcommand
2+
//!
3+
//! This module handles the template generation subcommand for creating
4+
//! configuration file templates with placeholder values.
5+
6+
use std::path::Path;
7+
8+
use crate::domain::config::EnvironmentCreationConfig;
9+
use crate::presentation::user_output::{UserOutput, VerbosityLevel};
10+
11+
use super::super::errors::CreateSubcommandError;
12+
13+
/// Handle template generation
14+
///
15+
/// This function generates a configuration template file with placeholder values
16+
/// that users can edit to create their own environment configurations.
17+
///
18+
/// # Arguments
19+
///
20+
/// * `output_path` - Path where the template file should be created
21+
///
22+
/// # Returns
23+
///
24+
/// Returns `Ok(())` on success, or a `CreateSubcommandError` on failure.
25+
///
26+
/// # Errors
27+
///
28+
/// Returns an error if template file creation fails.
29+
#[allow(clippy::result_large_err)] // Error contains detailed context for user guidance
30+
pub fn handle_template_generation(output_path: &Path) -> Result<(), CreateSubcommandError> {
31+
// Create user output for progress messages
32+
let mut output = UserOutput::new(VerbosityLevel::Normal);
33+
34+
output.progress("Generating configuration template...");
35+
36+
// Call existing domain method - template generation implemented in PR #48
37+
// This is async, so we need to use tokio runtime
38+
tokio::runtime::Runtime::new()
39+
.expect("Failed to create tokio runtime")
40+
.block_on(async {
41+
EnvironmentCreationConfig::generate_template_file(output_path)
42+
.await
43+
.map_err(CreateSubcommandError::TemplateGenerationFailed)
44+
})?;
45+
46+
output.success(&format!(
47+
"Configuration template generated: {}",
48+
output_path.display()
49+
));
50+
println!();
51+
println!("Next steps:");
52+
println!("1. Edit the template file and replace placeholder values:");
53+
println!(" - REPLACE_WITH_ENVIRONMENT_NAME: Choose a unique environment name (e.g., 'dev', 'staging')");
54+
println!(" - REPLACE_WITH_SSH_PRIVATE_KEY_PATH: Path to your SSH private key");
55+
println!(" - REPLACE_WITH_SSH_PUBLIC_KEY_PATH: Path to your SSH public key");
56+
println!("2. Review default values:");
57+
println!(" - username: 'torrust' (can be changed if needed)");
58+
println!(" - port: 22 (standard SSH port)");
59+
println!("3. Create the environment:");
60+
println!(
61+
" torrust-tracker-deployer create environment --env-file {}",
62+
output_path.display()
63+
);
64+
65+
Ok(())
66+
}

0 commit comments

Comments
 (0)