From 4623874d1c95414dcd5ae194d2561f2d98b40982 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Tue, 5 May 2026 17:14:07 +0900 Subject: feat(dump-autoload): warn and exit 1 on missing installed packages Mirror Composer's DumpAutoloadCommand by scanning the local repository for packages whose install path is absent on disk, emitting the same "Not all dependencies are installed" warning, and returning exit code 1 when any are missing. Also reorders the surrounding flow to follow Composer's command sequence. --- crates/mozart/src/commands/dump_autoload.rs | 67 +++++++++++++++++++---------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/crates/mozart/src/commands/dump_autoload.rs b/crates/mozart/src/commands/dump_autoload.rs index 15253e8..c7af429 100644 --- a/crates/mozart/src/commands/dump_autoload.rs +++ b/crates/mozart/src/commands/dump_autoload.rs @@ -52,19 +52,31 @@ pub async fn execute( cli: &super::Cli, console: &mozart_core::console::Console, ) -> anyhow::Result<()> { - // A: --dev / --no-dev conflict detection - if args.dev && args.no_dev { - anyhow::bail!("You can not use both --no-dev and --dev as they conflict with each other."); - } - let working_dir = cli.working_dir()?; + let composer = mozart_core::composer::Composer::require(&working_dir)?; + + let composer_config = composer.config(); let vendor_dir = working_dir.join("vendor"); - let dev_mode = !args.no_dev; - // B: Load Composer state (composer.json is required for dump-autoload) - let composer = mozart_core::composer::Composer::require(&working_dir)?; - let composer_config = composer.config(); + let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?; + let vendor_composer_dir = vendor_dir.join("composer"); + let mut missing_dependencies = false; + for pkg in &installed.packages { + if let Some(rel) = &pkg.install_path { + let install_path = vendor_composer_dir.join(rel); + if !install_path.exists() { + missing_dependencies = true; + console.info(&format!( + "{}", + mozart_core::console::warning( + "Not all dependencies are installed. Make sure to run a \"composer install\" to install missing dependencies" + ) + )); + break; + } + } + } let optimize = args.optimize || composer_config @@ -76,27 +88,26 @@ pub async fn execute( .get("classmap-authoritative") .and_then(|v| v.as_bool()) .unwrap_or(false); - let apcu = args.apcu - || args.apcu_prefix.is_some() + let apcu_prefix = args.apcu_prefix.clone(); + let apcu = apcu_prefix.is_some() + || args.apcu || composer_config .get("apcu-autoloader") .and_then(|v| v.as_bool()) .unwrap_or(false); - // C: Validate --strict-psr and --strict-ambiguous require optimize - let effective_optimize = optimize || classmap_authoritative; - if args.strict_psr && !effective_optimize { + let do_optimize = optimize || classmap_authoritative; + if args.strict_psr && !do_optimize { anyhow::bail!( "--strict-psr mode only works with optimized autoloader, use --optimize or --classmap-authoritative." ); } - if args.strict_ambiguous && !effective_optimize { + if args.strict_ambiguous && !do_optimize { anyhow::bail!( "--strict-ambiguous mode only works with optimized autoloader, use --optimize or --classmap-authoritative." ); } - // D: Pre-generation output message if classmap_authoritative { console.info("Generating optimized autoload files (authoritative)"); } else if optimize { @@ -105,7 +116,10 @@ pub async fn execute( console.info("Generating autoload files"); } - // Determine suffix: read from existing autoload.php, or from lock file, or generate + if args.dev && args.no_dev { + anyhow::bail!("You can not use both --no-dev and --dev as they conflict with each other."); + } + let suffix = mozart_autoload::autoload::determine_suffix(&working_dir, &vendor_dir)?; if args.dry_run { @@ -113,26 +127,29 @@ pub async fn execute( return Ok(()); } - // E: AutoloadConfig construction using config-merged values let autoload_config = mozart_autoload::autoload::AutoloadConfig { project_dir: working_dir, vendor_dir, - dev_mode, + dev_mode: !args.no_dev, suffix, classmap_authoritative, optimize, apcu, - apcu_prefix: args.apcu_prefix.clone(), + apcu_prefix, strict_psr: args.strict_psr, strict_ambiguous: args.strict_ambiguous, platform_check: mozart_autoload::autoload::PlatformCheckMode::Full, ignore_platform_reqs: args.ignore_platform_reqs, }; - // F: Handle GenerateResult and post-generation messages let result = mozart_autoload::autoload::generate(&autoload_config)?; - if effective_optimize || classmap_authoritative { + if classmap_authoritative { + console.info(&format!( + "Generated optimized autoload files (authoritative) containing {} classes", + result.class_count + )); + } else if optimize { console.info(&format!( "Generated optimized autoload files containing {} classes", result.class_count @@ -141,6 +158,12 @@ pub async fn execute( console.info("Generated autoload files"); } + if missing_dependencies { + return Err(mozart_core::exit_code::bail_silent( + mozart_core::exit_code::GENERAL_ERROR, + )); + } + if args.strict_ambiguous && result.has_ambiguous_classes { return Err(mozart_core::exit_code::bail_silent(2)); } -- cgit v1.3.1