Skip to main content

xbp_cli/commands/
deploy.rs

1//! Advanced deployment command module
2//!
3//! This module provides an intelligent deployment system that automatically
4//! detects project types and configures deployment strategies accordingly.
5
6use crate::strategies::{DeploymentConfig, DeploymentExecutor};
7use std::path::PathBuf;
8use tracing::debug;
9
10/// Execute advanced deployment with automatic project detection
11///
12/// # Arguments
13///
14/// * `app_name` - Optional application name (will be detected from project if not provided)
15/// * `port` - Optional port number (will use default based on project type if not provided)
16/// * `app_dir` - Optional application directory (defaults to current directory)
17/// * `config_path` - Optional path to xbp.yaml/xbp.json configuration file
18/// * `debug` - Whether to enable debug output
19///
20/// # Returns
21///
22/// * `Ok(())` if deployment was successful
23/// * `Err(String)` if deployment failed
24pub async fn deploy_application(
25    app_name: Option<String>,
26    port: Option<u16>,
27    app_dir: Option<PathBuf>,
28    config_path: Option<PathBuf>,
29    debug: bool,
30) -> Result<(), String> {
31    if debug {
32        debug!("Starting advanced deployment...");
33        debug!("App name: {:#?}", app_name);
34        debug!("Port: {:#?}", port);
35        debug!("App dir: {:#?}", app_dir);
36        debug!("Config path: {:#?}", config_path);
37    }
38
39    let config: DeploymentConfig =
40        DeploymentConfig::from_args_or_config(app_name, port, app_dir, config_path).await?;
41
42    if debug {
43        debug!("Final deployment config:");
44        debug!("  App name: {:#?}", config.app_name);
45        debug!("  Port: {:#?}", config.port);
46        debug!("  App dir: {:#?}", config.app_dir.display());
47        debug!("  Build command: {:#?}", config.build_command);
48        debug!("  Start command: {:#?}", config.start_command);
49        debug!("  Install command: {:#?}", config.install_command);
50    }
51
52    // Create and execute deployment
53    let mut executor: DeploymentExecutor = DeploymentExecutor::new(config, debug);
54    executor.deploy().await?;
55
56    Ok(())
57}
58
59/// Parse CLI arguments for the deploy command
60pub fn parse_deploy_args(
61    args: &[String],
62) -> (
63    Option<String>,
64    Option<u16>,
65    Option<PathBuf>,
66    Option<PathBuf>,
67) {
68    let mut app_name: Option<String> = None;
69    let mut port: Option<u16> = None;
70    let mut app_dir: Option<PathBuf> = None;
71    let mut config_path: Option<PathBuf> = None;
72
73    let mut i: usize = 0;
74    while i < args.len() {
75        match args[i].as_str() {
76            "--app-name" if i + 1 < args.len() => {
77                app_name = Some(args[i + 1].clone());
78                i += 2;
79            }
80            "--port" if i + 1 < args.len() => {
81                if let Ok(p) = args[i + 1].parse::<u16>() {
82                    port = Some(p);
83                }
84                i += 2;
85            }
86            "--app-dir" if i + 1 < args.len() => {
87                app_dir = Some(PathBuf::from(&args[i + 1]));
88                i += 2;
89            }
90            "--config" if i + 1 < args.len() => {
91                config_path = Some(PathBuf::from(&args[i + 1]));
92                i += 2;
93            }
94            "--app-name" | "--port" | "--app-dir" | "--config" => {
95                i += 1;
96            }
97            _ => {
98                i += 1;
99            }
100        }
101    }
102
103    (app_name, port, app_dir, config_path)
104}