dampen_cli/commands/
build.rs

1#![allow(clippy::print_stderr, clippy::print_stdout)]
2
3//! Build command - generates production Rust code from Dampen UI files
4
5use std::path::Path;
6
7/// Build command arguments
8#[derive(clap::Args)]
9pub struct BuildArgs {
10    /// Input directory containing .dampen files (default: ui/)
11    #[arg(short, long, default_value = "ui")]
12    input: String,
13
14    /// Output file for generated code (default: src/ui_generated.rs)
15    #[arg(short, long, default_value = "src/ui_generated.rs")]
16    output: String,
17
18    /// Model struct name (default: Model)
19    #[arg(long, default_value = "Model")]
20    model: String,
21
22    /// Message enum name (default: Message)
23    #[arg(long, default_value = "Message")]
24    message: String,
25
26    /// Verbose output
27    #[arg(short, long)]
28    verbose: bool,
29
30    /// Package to build (if workspace has multiple packages)
31    #[arg(short, long)]
32    package: Option<String>,
33
34    /// Additional features to enable (beyond codegen)
35    #[arg(long, value_delimiter = ',')]
36    features: Vec<String>,
37}
38
39/// Execute the build command
40///
41/// Builds the application in debug mode with codegen.
42///
43/// # Mode Behavior
44///
45/// - **Debug Mode with Codegen**: Compile-time code generation without optimizations
46/// - Faster compilation than release mode
47/// - Useful for debugging production codegen behavior
48/// - Use `dampen release` for optimized production builds
49///
50/// # Examples
51///
52/// ```bash
53/// # Basic debug build with codegen
54/// dampen build
55///
56/// # Build specific package in workspace
57/// dampen build -p my-app
58///
59/// # Enable additional features
60/// dampen build --features tokio,logging
61/// ```
62pub fn execute(args: &BuildArgs) -> Result<(), String> {
63    execute_production_build(args)
64}
65
66fn execute_production_build(args: &BuildArgs) -> Result<(), String> {
67    use std::process::Command;
68
69    if args.verbose {
70        eprintln!("Running debug build with codegen...");
71    }
72
73    if !Path::new("build.rs").exists() {
74        return Err(
75            "build.rs not found. This project may not be configured for codegen builds."
76                .to_string(),
77        );
78    }
79
80    if !Path::new("Cargo.toml").exists() {
81        return Err("Cargo.toml not found. Are you in a Rust project directory?".to_string());
82    }
83
84    let mut cmd = Command::new("cargo");
85    cmd.arg("build");
86
87    if let Some(ref package) = args.package {
88        cmd.arg("-p").arg(package);
89    }
90
91    if args.verbose {
92        cmd.arg("--verbose");
93    }
94
95    let mut all_features = vec!["codegen".to_string()];
96    all_features.extend(args.features.clone());
97
98    cmd.arg("--features").arg(all_features.join(","));
99
100    if args.verbose {
101        let features_str = all_features.join(",");
102        eprintln!("Executing: cargo build --features {}", features_str);
103    }
104
105    let status = cmd
106        .status()
107        .map_err(|e| format!("Failed to execute cargo: {}", e))?;
108
109    if !status.success() {
110        return Err("Build failed".to_string());
111    }
112
113    if args.verbose {
114        eprintln!("Build successful! Binary is in target/debug/");
115    }
116
117    eprintln!("Debug build completed successfully!");
118    eprintln!("Use 'dampen release' for optimized production builds.");
119    Ok(())
120}