Skip to main content

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;