aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/command/dump_autoload_command.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-15 23:22:10 +0900
committernsfisis <nsfisis@gmail.com>2026-05-16 10:00:40 +0900
commitce4c12a311516aa429e04416a957a3b3939f8995 (patch)
treea9ea3da53f395f00c2e54b23ac50fbaf1739e91a /crates/shirabe/src/command/dump_autoload_command.rs
parent148586086312fa32887e580f232be30a7125a1a0 (diff)
downloadphp-shirabe-ce4c12a311516aa429e04416a957a3b3939f8995.tar.gz
php-shirabe-ce4c12a311516aa429e04416a957a3b3939f8995.tar.zst
php-shirabe-ce4c12a311516aa429e04416a957a3b3939f8995.zip
feat(port): port DumpAutoloadCommand.php
Diffstat (limited to 'crates/shirabe/src/command/dump_autoload_command.rs')
-rw-r--r--crates/shirabe/src/command/dump_autoload_command.rs155
1 files changed, 155 insertions, 0 deletions
diff --git a/crates/shirabe/src/command/dump_autoload_command.rs b/crates/shirabe/src/command/dump_autoload_command.rs
index b5aac69..7341124 100644
--- a/crates/shirabe/src/command/dump_autoload_command.rs
+++ b/crates/shirabe/src/command/dump_autoload_command.rs
@@ -1 +1,156 @@
//! ref: composer/src/Composer/Command/DumpAutoloadCommand.php
+
+use anyhow::Result;
+use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
+use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
+use shirabe_php_shim::{file_exists, InvalidArgumentException, PhpMixed};
+
+use crate::command::base_command::BaseCommand;
+use crate::console::input::input_option::InputOption;
+use crate::plugin::command_event::CommandEvent;
+use crate::plugin::plugin_events::PluginEvents;
+
+#[derive(Debug)]
+pub struct DumpAutoloadCommand {
+ inner: BaseCommand,
+}
+
+impl DumpAutoloadCommand {
+ pub fn configure(&mut self) {
+ self.inner
+ .set_name("dump-autoload")
+ .set_aliases(vec!["dumpautoload".to_string()])
+ .set_description("Dumps the autoloader")
+ .set_definition(vec![
+ InputOption::new("optimize", Some(PhpMixed::String("o".to_string())), Some(InputOption::VALUE_NONE), "Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.", None, vec![]),
+ InputOption::new("classmap-authoritative", Some(PhpMixed::String("a".to_string())), Some(InputOption::VALUE_NONE), "Autoload classes from the classmap only. Implicitly enables `--optimize`.", None, vec![]),
+ InputOption::new("apcu", None, Some(InputOption::VALUE_NONE), "Use APCu to cache found/not-found classes.", None, vec![]),
+ InputOption::new("apcu-prefix", None, Some(InputOption::VALUE_REQUIRED), "Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu", None, vec![]),
+ InputOption::new("dry-run", None, Some(InputOption::VALUE_NONE), "Outputs the operations but will not execute anything.", None, vec![]),
+ InputOption::new("dev", None, Some(InputOption::VALUE_NONE), "Enables autoload-dev rules. Composer will by default infer this automatically according to the last install or update --no-dev state.", None, vec![]),
+ InputOption::new("no-dev", None, Some(InputOption::VALUE_NONE), "Disables autoload-dev rules. Composer will by default infer this automatically according to the last install or update --no-dev state.", None, vec![]),
+ InputOption::new("ignore-platform-req", None, Some(InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY), "Ignore a specific platform requirement (php & ext- packages).", None, vec![]),
+ InputOption::new("ignore-platform-reqs", None, Some(InputOption::VALUE_NONE), "Ignore all platform requirements (php & ext- packages).", None, vec![]),
+ InputOption::new("strict-psr", None, Some(InputOption::VALUE_NONE), "Return a failed status code (1) if PSR-4 or PSR-0 mapping errors are present. Requires --optimize to work.", None, vec![]),
+ InputOption::new("strict-ambiguous", None, Some(InputOption::VALUE_NONE), "Return a failed status code (2) if the same class is found in multiple files. Requires --optimize to work.", None, vec![]),
+ ])
+ .set_help(
+ "<info>php composer.phar dump-autoload</info>\n\n\
+ Read more at https://getcomposer.org/doc/03-cli.md#dump-autoload-dumpautoload"
+ );
+ }
+
+ pub fn execute(&self, input: &dyn InputInterface, output: &dyn OutputInterface) -> Result<i64> {
+ let composer = self.inner.require_composer()?;
+
+ // TODO(plugin): dispatch CommandEvent
+ let command_event = CommandEvent::new(
+ PluginEvents::COMMAND.to_string(),
+ "dump-autoload".to_string(),
+ Box::new(input),
+ Box::new(output),
+ vec![],
+ vec![],
+ );
+ composer.get_event_dispatcher().dispatch(command_event.get_name(), &command_event);
+
+ let installation_manager = composer.get_installation_manager();
+ let local_repo = composer.get_repository_manager().get_local_repository();
+ let package = composer.get_package();
+ let config = composer.get_config();
+
+ let mut missing_dependencies = false;
+ for local_pkg in local_repo.get_canonical_packages() {
+ let install_path = installation_manager.get_install_path(&*local_pkg);
+ if install_path.as_deref().is_some_and(|p| !file_exists(p)) {
+ missing_dependencies = true;
+ self.inner.get_io().write("<warning>Not all dependencies are installed. Make sure to run a \"composer install\" to install missing dependencies</warning>");
+ break;
+ }
+ }
+
+ let optimize = input.get_option("optimize").as_bool().unwrap_or(false)
+ || config.get("optimize-autoloader").as_bool().unwrap_or(false);
+ let authoritative = input.get_option("classmap-authoritative").as_bool().unwrap_or(false)
+ || config.get("classmap-authoritative").as_bool().unwrap_or(false);
+ let apcu_prefix = input.get_option("apcu-prefix").as_string_opt().map(|s| s.to_string());
+ let apcu = apcu_prefix.is_some()
+ || input.get_option("apcu").as_bool().unwrap_or(false)
+ || config.get("apcu-autoloader").as_bool().unwrap_or(false);
+
+ if input.get_option("strict-psr").as_bool().unwrap_or(false) && !optimize && !authoritative {
+ return Err(InvalidArgumentException {
+ message: "--strict-psr mode only works with optimized autoloader, use --optimize or --classmap-authoritative if you want a strict return value.".to_string(),
+ code: 0,
+ }
+ .into());
+ }
+ if input.get_option("strict-ambiguous").as_bool().unwrap_or(false) && !optimize && !authoritative {
+ return Err(InvalidArgumentException {
+ message: "--strict-ambiguous mode only works with optimized autoloader, use --optimize or --classmap-authoritative if you want a strict return value.".to_string(),
+ code: 0,
+ }
+ .into());
+ }
+
+ if authoritative {
+ self.inner.get_io().write("<info>Generating optimized autoload files (authoritative)</info>");
+ } else if optimize {
+ self.inner.get_io().write("<info>Generating optimized autoload files</info>");
+ } else {
+ self.inner.get_io().write("<info>Generating autoload files</info>");
+ }
+
+ let generator = composer.get_autoload_generator();
+ if input.get_option("dry-run").as_bool().unwrap_or(false) {
+ generator.set_dry_run(true);
+ }
+ if input.get_option("no-dev").as_bool().unwrap_or(false) {
+ generator.set_dev_mode(false);
+ }
+ if input.get_option("dev").as_bool().unwrap_or(false) {
+ if input.get_option("no-dev").as_bool().unwrap_or(false) {
+ return Err(InvalidArgumentException {
+ message: "You can not use both --no-dev and --dev as they conflict with each other.".to_string(),
+ code: 0,
+ }
+ .into());
+ }
+ generator.set_dev_mode(true);
+ }
+ generator.set_class_map_authoritative(authoritative);
+ generator.set_run_scripts(true);
+ generator.set_apcu(apcu, apcu_prefix.as_deref());
+ generator.set_platform_requirement_filter(self.inner.get_platform_requirement_filter(input)?);
+ let class_map = generator.dump(
+ config,
+ &local_repo,
+ package,
+ installation_manager,
+ "composer",
+ optimize,
+ None,
+ composer.get_locker(),
+ input.get_option("strict-ambiguous").as_bool().unwrap_or(false),
+ )?;
+ let number_of_classes = class_map.len();
+
+ if authoritative {
+ self.inner.get_io().write(&format!("<info>Generated optimized autoload files (authoritative) containing {} classes</info>", number_of_classes));
+ } else if optimize {
+ self.inner.get_io().write(&format!("<info>Generated optimized autoload files containing {} classes</info>", number_of_classes));
+ } else {
+ self.inner.get_io().write("<info>Generated autoload files</info>");
+ }
+
+ if missing_dependencies || (input.get_option("strict-psr").as_bool().unwrap_or(false) && !class_map.get_psr_violations().is_empty()) {
+ return Ok(1);
+ }
+
+ if input.get_option("strict-ambiguous").as_bool().unwrap_or(false) && !class_map.get_ambiguous_classes(false).is_empty() {
+ return Ok(2);
+ }
+
+ Ok(0)
+ }
+}