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