Maintain/Library.rs
1/*=============================================================================*/
2/* File Path: Element/Maintain/Source/Library.rs */
3/*=============================================================================*/
4/* Module: Library */
5/* */
6/* Brief Description: Entry point for the Maintain binary supporting both */
7/* Build and Run workflows. */
8/* */
9/* RESPONSIBILITIES: */
10/* ================ */
11/* */
12/* Primary: */
13/* - Serve as the entry point for the Maintain orchestrator */
14/* - Initialize Build and Run modules based on CLI arguments */
15/* - Route commands to appropriate workflow handlers */
16/* */
17/* Secondary: */
18/* - Provide unified CLI interface for build and run operations */
19/* - Support legacy mode for backward compatibility */
20/* */
21/* ARCHITECTURAL ROLE: */
22/* =================== */
23/* */
24/* Position: */
25/* - Entry point layer */
26/* - Binary initialization and routing */
27/* */
28/* Dependencies (What this module requires): */
29/* - External crates: clap, std */
30/* - Internal modules: Build, Run */
31/* - Traits implemented: None */
32/* */
33/* Dependents (What depends on this module): */
34/* - Cargo.toml (binary definition) */
35/* - Build system entry point */
36/* - Development run entry point */
37/* */
38/*=============================================================================*/
39/* IMPLEMENTATION */
40/*=============================================================================*/
41
42// Disable Windows console for release builds
43#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
44
45// Allow PascalCase naming for function names
46#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
47
48/*=============================================================================*/
49/* MAIN ENTRY POINT */
50/*=============================================================================*/
51
52/// The primary entry point for the Maintain Orchestrator binary.
53///
54/// This function serves as the bridge between the Cargo binary definition
55/// and the Build/Run modules' orchestration logic. It supports three modes:
56///
57/// ## Mode 1: Run Mode (--run flag)
58///
59/// When called with the `--run` flag, uses the development run workflow:
60/// ```bash
61/// cargo run --bin Maintain -- --run --profile debug-mountain
62/// cargo run --bin Maintain -- --run --list-profiles
63/// ```
64///
65/// ## Mode 2: Build Mode (default or --build flag)
66///
67/// When called with CLI arguments (without --run), uses the build workflow:
68/// ```bash
69/// cargo run --bin Maintain -- --profile debug-mountain
70/// cargo run --bin Maintain -- --list-profiles
71/// ```
72///
73/// ## Mode 3: Legacy Mode (environment variable based)
74///
75/// When called with a `--` separator followed by a build command, uses the
76/// traditional environment variable-based build system:
77/// ```bash
78/// ./Target/release/Maintain -- pnpm tauri build --debug
79/// ./Target/release/Maintain -- pnpm tauri dev
80/// ```
81///
82/// The function is marked as `#[allow(dead_code)]` because when this file
83/// is used as a library module, the main function may not be called directly.
84/// However, when compiled as a binary, this main function is the entry point.
85#[allow(dead_code)]
86fn main() {
87 use clap::Parser;
88 use std::env;
89
90 // Collect all arguments
91 let mut args: Vec<String> = env::args().collect();
92
93 // Determine the mode based on arguments:
94 // - Run mode: --run/-r flag, --dev flag, or 'run' subcommand
95 // - Build mode: Direct flags like --list-profiles, --profile, --show-profile, or 'build' subcommand
96 // - Legacy mode: -- followed by a build command (like pnpm, cargo, npm)
97 // - No args: Show help
98
99 if args.len() == 1 {
100 // No arguments - show build help (default)
101 let _ = Build::CLI::Cli::try_parse();
102 return;
103 }
104
105 // Check if first arg after binary is a run-specific flag or subcommand
106 let first_arg = args.get(1).map(|s| s.as_str()).unwrap_or("");
107
108 // Check if we're in legacy mode (-- followed by a command)
109 let is_legacy_mode = first_arg == "--";
110
111 // Check for run mode indicators
112 let is_run_flag = first_arg == "--run" || first_arg == "--dev" || first_arg == "-r";
113 let is_run_subcommand = first_arg == "run";
114 let is_run_mode = is_run_flag || is_run_subcommand;
115
116 // Check for build mode indicators (subcommand or flags)
117 let is_build_subcommand = first_arg == "build";
118
119 // CLI flags that indicate we should use the build CLI mode
120 let build_cli_flags = [
121 "--list-profiles",
122 "--show-profile",
123 "--validate-profile",
124 "--profile",
125 "--dry-run",
126 "--help",
127 "-h",
128 "--version",
129 "-V",
130 "list-profiles",
131 "show-profile",
132 "validate-profile",
133 "resolve",
134 ];
135
136 // Check if first arg is a build CLI flag
137 let is_build_cli_mode = if !is_run_mode && !is_legacy_mode && !is_build_subcommand {
138 build_cli_flags.iter().any(|flag| {
139 first_arg == *flag || first_arg.starts_with(&format!("{}=", flag))
140 }) || (!first_arg.starts_with('-') && !is_build_subcommand)
141 } else {
142 false
143 };
144
145 if is_run_mode {
146 // Strip the --run/--dev/-r flag or 'run' subcommand before passing to Run CLI
147 // This allows Run::CLI to parse the remaining arguments correctly
148 if is_run_flag {
149 // Remove the flag (and its position) from args
150 args.remove(1);
151 } else if is_run_subcommand {
152 // Replace 'run' subcommand with arguments that Run CLI expects
153 args.remove(1);
154 }
155
156 // Use Run mode (development workflow)
157 // Use try_parse_from with our modified args, not try_parse() which reads from env::args()
158 match Run::CLI::Cli::try_parse_from(args) {
159 Ok(cli) => {
160 if let Err(e) = cli.execute() {
161 eprintln!("Error: {}", e);
162 std::process::exit(1);
163 }
164 }
165 Err(e) => {
166 // If parsing fails, it might be a --help or --version request
167 // or invalid arguments - let clap handle it
168 e.print().expect("Failed to print error");
169 std::process::exit(e.exit_code());
170 }
171 }
172 } else if is_build_subcommand {
173 // Handle 'build' subcommand - strip it and pass to Build CLI
174 args.remove(1);
175
176 // Use try_parse_from with our modified args
177 match Build::CLI::Cli::try_parse_from(args) {
178 Ok(cli) => {
179 if let Err(e) = cli.execute() {
180 eprintln!("Error: {}", e);
181 std::process::exit(1);
182 }
183 }
184 Err(e) => {
185 e.print().expect("Failed to print error");
186 std::process::exit(e.exit_code());
187 }
188 }
189 } else if is_build_cli_mode {
190 // Use Build CLI mode (configuration based)
191 match Build::CLI::Cli::try_parse() {
192 Ok(cli) => {
193 if let Err(e) = cli.execute() {
194 eprintln!("Error: {}", e);
195 std::process::exit(1);
196 }
197 }
198 Err(e) => {
199 // If parsing fails, it might be a --help or --version request
200 // or invalid arguments - let clap handle it
201 e.print().expect("Failed to print error");
202 std::process::exit(e.exit_code());
203 }
204 }
205 } else {
206 // Use legacy build mode (environment variable based)
207 // This handles: ./Maintain -- pnpm tauri build
208 Build::Fn::Fn();
209 }
210}
211
212/*=============================================================================*/
213/* MODULE DECLARATIONS */
214/*=============================================================================*/
215
216/// Build Orchestrator Module.
217///
218/// This module contains all the build orchestration logic, including:
219///
220/// - **CLI**: Command-line interface for configuration-based builds
221/// - **Constant**: File paths, delimiters, and environment variable names
222/// - **Definition**: Data structures for arguments, manifests, and file guards
223/// - **Error**: Comprehensive error types for build operations
224/// - **Fn**: Main build orchestration function
225/// - **GetTauriTargetTriple**: Target triple detection
226/// - **JsonEdit**: JSON configuration editing
227/// - **Logger**: Logging utilities
228/// - **Pascalize**: PascalCase conversion utilities
229/// - **Process**: Process management
230/// - **Rhai**: Rhai scripting support
231/// - **TomlEdit**: TOML configuration editing
232/// - **WordsFromPascal**: Extract words from PascalCase strings
233///
234/// See the Build module documentation for detailed information about the
235/// build system's capabilities and usage.
236pub mod Build;
237
238/// Development Run Module.
239///
240/// This module contains all the development run orchestration logic, including:
241///
242/// - **CLI**: Command-line interface for configuration-based runs
243/// - **Constant**: File paths, delimiters, and environment variable names
244/// - **Definition**: Data structures for arguments and run configuration
245/// - **Environment**: Environment variable resolution and management
246/// - **Error**: Comprehensive error types for run operations
247/// - **Fn**: Main run orchestration function
248/// - **Logger**: Logging utilities
249/// - **Process**: Process management for development servers
250/// - **Profile**: Profile resolution and management
251///
252/// See the Run module documentation for detailed information about the
253/// development run system's capabilities and usage.
254pub mod Run;