xbp 10.46.0

XBP is a zero-config build pack that can also interact with proxies, kafka, sockets, synthetic monitors.
Documentation
//! Legacy local project deploy helpers (deprecated).
//!
//! Canonical release orchestration is `xbp deploy <target>` via `deploy_engine`.
//! This module remains for any external library callers that still use
//! auto-detect + local process start.

use crate::strategies::{DeploymentConfig, DeploymentExecutor};
use std::path::PathBuf;
use tracing::debug;

/// Execute advanced deployment with automatic project detection.
///
/// Deprecated: prefer `xbp deploy <target>` / `crate::commands::run_deploy`.
#[deprecated(
    note = "use xbp deploy <target> (deploy_engine::run_deploy) for service-first deploy"
)]
pub async fn deploy_application(
    app_name: Option<String>,
    port: Option<u16>,
    app_dir: Option<PathBuf>,
    config_path: Option<PathBuf>,
    debug: bool,
) -> Result<(), String> {
    if debug {
        debug!("Starting advanced deployment...");
        debug!("App name: {:#?}", app_name);
        debug!("Port: {:#?}", port);
        debug!("App dir: {:#?}", app_dir);
        debug!("Config path: {:#?}", config_path);
    }

    let config: DeploymentConfig =
        DeploymentConfig::from_args_or_config(app_name, port, app_dir, config_path).await?;

    if debug {
        debug!("Final deployment config:");
        debug!("  App name: {:#?}", config.app_name);
        debug!("  Port: {:#?}", config.port);
        debug!("  App dir: {:#?}", config.app_dir.display());
        debug!("  Build command: {:#?}", config.build_command);
        debug!("  Start command: {:#?}", config.start_command);
        debug!("  Install command: {:#?}", config.install_command);
    }

    // Create and execute deployment
    let mut executor: DeploymentExecutor = DeploymentExecutor::new(config, debug);
    executor.deploy().await?;

    Ok(())
}

/// Parse CLI arguments for the deploy command
pub fn parse_deploy_args(
    args: &[String],
) -> (
    Option<String>,
    Option<u16>,
    Option<PathBuf>,
    Option<PathBuf>,
) {
    let mut app_name: Option<String> = None;
    let mut port: Option<u16> = None;
    let mut app_dir: Option<PathBuf> = None;
    let mut config_path: Option<PathBuf> = None;

    let mut i: usize = 0;
    while i < args.len() {
        match args[i].as_str() {
            "--app-name" if i + 1 < args.len() => {
                app_name = Some(args[i + 1].clone());
                i += 2;
            }
            "--port" if i + 1 < args.len() => {
                if let Ok(p) = args[i + 1].parse::<u16>() {
                    port = Some(p);
                }
                i += 2;
            }
            "--app-dir" if i + 1 < args.len() => {
                app_dir = Some(PathBuf::from(&args[i + 1]));
                i += 2;
            }
            "--config" if i + 1 < args.len() => {
                config_path = Some(PathBuf::from(&args[i + 1]));
                i += 2;
            }
            "--app-name" | "--port" | "--app-dir" | "--config" => {
                i += 1;
            }
            _ => {
                i += 1;
            }
        }
    }

    (app_name, port, app_dir, config_path)
}