orbiton/commands/
config.rs1use anyhow::Result;
4use clap::{Args, Subcommand};
5use console::style;
6use std::path::PathBuf;
7
8use crate::config::OrbitonConfig;
9
10#[derive(Args)]
11pub struct ConfigArgs {
12 #[command(subcommand)]
13 command: ConfigCommand,
14}
15
16#[derive(Subcommand)]
17enum ConfigCommand {
18 Show {
20 #[arg(short, long)]
22 dir: Option<PathBuf>,
23 },
24 Init {
26 #[arg(short, long)]
28 dir: Option<PathBuf>,
29 },
30 Validate {
32 #[arg(short, long)]
34 dir: Option<PathBuf>,
35 },
36}
37
38pub fn execute(args: ConfigArgs) -> Result<()> {
39 match args.command {
40 ConfigCommand::Show { dir } => show_config(dir),
41 ConfigCommand::Init { dir } => init_config(dir),
42 ConfigCommand::Validate { dir } => validate_config(dir),
43 }
44}
45
46fn get_project_dir(dir: Option<PathBuf>) -> Result<PathBuf> {
47 match dir {
48 Some(d) => Ok(d),
49 None => std::env::current_dir()
50 .map_err(|e| anyhow::anyhow!("Failed to get current directory: {}", e)),
51 }
52}
53
54fn show_config(dir: Option<PathBuf>) -> Result<()> {
55 let project_dir = get_project_dir(dir)?;
56
57 println!(
58 "{} configuration for project at {project_dir:?}",
59 style("Showing").bold().blue()
60 );
61
62 let config = OrbitonConfig::load_from_project(&project_dir)?;
63
64 println!("\n{}", style("Project Configuration:").bold().underlined());
65 println!(
66 " Source directory: {}",
67 style(&config.project.src_dir).cyan()
68 );
69 println!(
70 " Output directory: {}",
71 style(&config.project.dist_dir).cyan()
72 );
73 println!(
74 " Entry point: {}",
75 style(&config.project.entry_point).cyan()
76 );
77
78 println!("\n{}", style("Development Server:").bold().underlined());
79 println!(" Port: {}", style(config.dev_server.port).cyan());
80 println!(" Host: {}", style(&config.dev_server.host).cyan());
81 println!(
82 " Auto-open browser: {}",
83 style(config.dev_server.auto_open).cyan()
84 );
85
86 println!("\n{}", style("Hot Module Reload:").bold().underlined());
87 println!(" Enabled: {}", style(config.hmr.enabled).cyan());
88 println!(
89 " Debounce time: {}ms",
90 style(config.hmr.debounce_ms).cyan()
91 );
92 println!(
93 " Preserve state: {}",
94 style(config.hmr.preserve_state).cyan()
95 );
96 println!(" Max retries: {}", style(config.hmr.max_retries).cyan());
97
98 println!("\n{}", style("Build Configuration:").bold().underlined());
99 println!(
100 " Use beta toolchain: {}",
101 style(config.build.use_beta_toolchain).cyan()
102 );
103 println!(" Release mode: {}", style(config.build.release).cyan());
104 if let Some(target) = &config.build.target {
105 println!(" Target: {}", style(target).cyan());
106 }
107
108 println!("\n{}", style("Lint Configuration:").bold().underlined());
109 println!(" Enabled: {}", style(config.lint.enabled).cyan());
110
111 Ok(())
112}
113
114fn init_config(dir: Option<PathBuf>) -> Result<()> {
115 let project_dir = get_project_dir(dir)?;
116
117 println!(
118 "{} default configuration in {project_dir:?}",
119 style("Creating").bold().green()
120 );
121
122 let config_path = OrbitonConfig::create_default_config(&project_dir)?;
123
124 println!(
125 "{} Configuration file created at: {}",
126 style("Success!").bold().green(),
127 style(config_path.display()).cyan()
128 );
129
130 println!("\nYou can now customize the configuration by editing the .orbiton.toml file.");
131
132 Ok(())
133}
134
135fn validate_config(dir: Option<PathBuf>) -> Result<()> {
136 let project_dir = get_project_dir(dir)?;
137
138 println!(
139 "{} configuration for project at {project_dir:?}",
140 style("Validating").bold().yellow()
141 );
142
143 let config = OrbitonConfig::load_from_project(&project_dir)?;
144
145 match config.validate() {
146 Ok(()) => {
147 println!(
148 "{} Configuration is valid!",
149 style("Success!").bold().green()
150 );
151 }
152 Err(e) => {
153 println!(
154 "{} Configuration validation failed:",
155 style("Error:").bold().red()
156 );
157 println!(" {e}");
158 return Err(e);
159 }
160 }
161
162 Ok(())
163}
164
165#[cfg(test)]
166mod tests {
167 use super::*;
168 use tempfile::tempdir;
169
170 #[test]
171 fn test_config_init() {
172 let temp_dir = tempdir().unwrap();
173 let result = init_config(Some(temp_dir.path().to_path_buf()));
174 assert!(result.is_ok());
175
176 let config_path = temp_dir.path().join(".orbiton.toml");
177 assert!(config_path.exists());
178 }
179
180 #[test]
181 fn test_config_validate() {
182 let temp_dir = tempdir().unwrap();
183
184 let _ = init_config(Some(temp_dir.path().to_path_buf()));
186
187 let result = validate_config(Some(temp_dir.path().to_path_buf()));
189 assert!(result.is_ok());
190 }
191}