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