(args: &[String], cwd: &Path)
| 201 | Ok(()) |
| 202 | } |
| 203 | |
| 204 | pub(crate) fn dev_command(args: &[String], cwd: &Path) -> Result<(), String> { |
| 205 | let target = parse_cli_target(args)?; |
| 206 | let headless = args.iter().any(|a| a == "--headless"); |
| 207 | if headless && target != CliTarget::Native { |
| 208 | return Err("`--headless` only supports `--target native`".to_string()); |
| 209 | } |
| 210 | if target == CliTarget::Web { |
| 211 | return dev_web_command(args, cwd); |
| 212 | } |
| 213 | if target == CliTarget::Android { |
| 214 | return dev_android_command(args, cwd); |
| 215 | } |
| 216 | let profile_requested = args.iter().any(|a| a == "--profile"); |
| 217 | let timings = args.iter().any(|a| a == "--timings"); |
| 218 | let ui_profile = args.iter().any(|a| a == "--ui-profile"); |
| 219 | let release = args.iter().any(|a| a == "--release"); |
| 220 | let demo = args.iter().any(|a| a == "--demo"); |
| 221 | let boot_scene = parse_boot_scene_flag(args)?; |
| 222 | let sim = parse_sim_flag(args)?; |
| 223 | let csv_profile_name = parse_optional_flag_value(args, "--csv-profile") |
| 224 | .map(|raw| PathBuf::from(raw.unwrap_or_else(|| "profiling.csv".to_string()))); |
| 225 | let profile = profile_requested || csv_profile_name.is_some(); |
| 226 | if headless && (timings || ui_profile) { |
| 227 | return Err("`--timings` + `--ui-profile` do not support `--headless`".to_string()); |
| 228 | } |
| 229 | let project_dir = parse_flag_value(args, "--path") |
| 230 | .map(|p| resolve_local_path(&p, cwd)) |
| 231 | .unwrap_or_else(|| cwd.to_path_buf()); |
| 232 | let project_dir = project_dir.canonicalize().unwrap_or(project_dir); |
| 233 | let mut phase = DevPhaseTimer::new(); |
| 234 | ensure_source_overrides(&project_dir) |
| 235 | .map_err(|err| format!("failed to sync generated project crates: {err}"))?; |
| 236 | // The CLI emits the script glue, the project links the engine; a version |
| 237 | // split between the two fails inside the dylib rather than at build time. |
| 238 | crate::version::ensure_engine_version_match(&project_dir)?; |
| 239 | phase.mark("ensure_source_overrides"); |
| 240 | let project_cfg = load_project_toml_with_demo(&project_dir, demo) |
| 241 | .map_err(|err| format!("failed to load project.toml: {err}"))?; |
| 242 | let profiling_dir = ensure_profiling_output_dir(&project_dir)?; |
| 243 | let csv_profile_path = csv_profile_name.as_ref().map(|name| { |
| 244 | profiling_dir.join( |
| 245 | name.file_name() |
| 246 | .unwrap_or_else(|| std::ffi::OsStr::new("profile_metrics.csv")), |
| 247 | ) |
| 248 | }); |
| 249 | if let Some(csv_profile_path) = &csv_profile_path { |
| 250 | fs::OpenOptions::new() |
| 251 | .create(true) |
| 252 | .append(true) |
| 253 | .open(csv_profile_path) |
| 254 | .map_err(|err| { |
| 255 | format!( |
| 256 | "failed to initialize profile csv {}: {err}", |
| 257 | csv_profile_path.display() |
| 258 | ) |
| 259 | })?; |
| 260 | } |
no test coverage detected