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 return;
87 }
88
89 // Check if first arg after binary is a run-specific flag or subcommand
90 let first_arg = args.get(1).map(|s| s.as_str()).unwrap_or("");
91
92 // Check if we're in legacy mode (-- followed by a command)
93 let is_legacy_mode = first_arg == "--";
94
95 // Check for run mode indicators
96 let is_run_flag = first_arg == "--run" || first_arg == "--dev" || first_arg == "-r";
97 let is_run_subcommand = first_arg == "run";
98 let is_run_mode = is_run_flag || is_run_subcommand;
99
100 // Check for build mode indicators (subcommand or flags)
101 let is_build_subcommand = first_arg == "build";
102
103 // CLI flags that indicate we should use the build CLI mode
104 let build_cli_flags = [
105 "--list-profiles",
106 "--show-profile",
107 "--validate-profile",
108 "--profile",
109 "--dry-run",
110 "--help",
111 "-h",
112 "--version",
113 "-V",
114 "list-profiles",
115 "show-profile",
116 "validate-profile",
117 "resolve",
118 ];
119
120 // Check if first arg is a build CLI flag
121 let is_build_cli_mode = if !is_run_mode && !is_legacy_mode && !is_build_subcommand {
122 build_cli_flags
123 .iter()
124 .any(|flag| first_arg == *flag || first_arg.starts_with(&format!("{}=", flag)))
125 || (!first_arg.starts_with('-') && !is_build_subcommand)
126 } else {
127 false
128 };
129
130 if is_run_mode {
131 // Strip the --run/--dev/-r flag or 'run' subcommand before passing to Run CLI
132 // This allows Run::CLI to parse the remaining arguments correctly
133 if is_run_flag {
134 // Remove the flag (and its position) from args
135 args.remove(1);
136 } else if is_run_subcommand {
137 // Replace 'run' subcommand with arguments that Run CLI expects
138 args.remove(1);
139 }
140
141 // Use Run mode (development workflow)
142 // Use try_parse_from with our modified args, not try_parse() which reads from
143 // env::args()
144 match Run::CLI::Cli::try_parse_from(args) {
145 Ok(cli) => {
146 if let Err(e) = cli.execute() {
147 eprintln!("Error: {}", e);
148 std::process::exit(1);
149 }
150 },
151 Err(e) => {
152 // If parsing fails, it might be a --help or --version request
153 // or invalid arguments - let clap handle it
154 e.print().expect("Failed to print error");
155 std::process::exit(e.exit_code());
156 },
157 }
158 } else if is_build_subcommand {
159 // Handle 'build' subcommand - strip it and pass to Build CLI
160 args.remove(1);
161
162 // Use try_parse_from with our modified args
163 match Build::CLI::Cli::try_parse_from(args) {
164 Ok(cli) => {
165 if let Err(e) = cli.execute() {
166 eprintln!("Error: {}", e);
167 std::process::exit(1);
168 }
169 },
170 Err(e) => {
171 e.print().expect("Failed to print error");
172 std::process::exit(e.exit_code());
173 },
174 }
175 } else if is_build_cli_mode {
176 // Use Build CLI mode (configuration based)
177 match Build::CLI::Cli::try_parse() {
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 // If parsing fails, it might be a --help or --version request
186 // or invalid arguments - let clap handle it
187 e.print().expect("Failed to print error");
188 std::process::exit(e.exit_code());
189 },
190 }
191 } else {
192 // Use legacy build mode (environment variable based)
193 // This handles: ./Maintain -- pnpm tauri build
194 Build::Fn::Fn();
195 }
196}
197
198// =============================================================================
199// MODULE DECLARATIONS
200// =============================================================================
201
202/// Build Orchestrator Module.
203///
204/// This module contains all the build orchestration logic, including:
205///
206/// - **CLI**: Command-line interface for configuration-based builds
207/// - **Constant**: File paths, delimiters, and environment variable names
208/// - **Definition**: Data structures for arguments, manifests, and file guards
209/// - **Error**: Comprehensive error types for build operations
210/// - **Fn**: Main build orchestration function
211/// - **GetTauriTargetTriple**: Target triple detection
212/// - **JsonEdit**: JSON configuration editing
213/// - **Logger**: Logging utilities
214/// - **Pascalize**: PascalCase conversion utilities
215/// - **Process**: Process management
216/// - **Rhai**: Rhai scripting support
217/// - **TomlEdit**: TOML configuration editing
218/// - **WordsFromPascal**: Extract words from PascalCase strings
219///
220/// See the Build module documentation for detailed information about the
221/// build system's capabilities and usage.
222pub mod Build;
223
224/// Development Run Module.
225///
226/// This module contains all the development run orchestration logic, including:
227///
228/// - **CLI**: Command-line interface for configuration-based runs
229/// - **Constant**: File paths, delimiters, and environment variable names
230/// - **Definition**: Data structures for arguments and run configuration
231/// - **Environment**: Environment variable resolution and management
232/// - **Error**: Comprehensive error types for run operations
233/// - **Fn**: Main run orchestration function
234/// - **Logger**: Logging utilities
235/// - **Process**: Process management for development servers
236/// - **Profile**: Profile resolution and management
237///
238/// See the Run module documentation for detailed information about the
239/// development run system's capabilities and usage.
240pub mod Run;
241pub mod Architecture;