diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-02-23 01:31:48 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-02-23 01:31:48 +0900 |
| commit | a0c17873aeb88cc81be769317fcad37161bb516c (patch) | |
| tree | ae767042cdb5d46248e07763553172f0d10990f4 /crates/mozart | |
| parent | c7a5859e1770dbc7cbc7cb1785c34b880162dfac (diff) | |
| download | php-mozart-a0c17873aeb88cc81be769317fcad37161bb516c.tar.gz php-mozart-a0c17873aeb88cc81be769317fcad37161bb516c.tar.zst php-mozart-a0c17873aeb88cc81be769317fcad37161bb516c.zip | |
fix(install): add CLI option validation, download-only wiring, and apcu-prefix implicit enable
- Restrict --prefer-install to source/dist/auto and --audit-format to
table/plain/json/summary via clap value_parser
- Error when --prefer-install is combined with --prefer-source/--prefer-dist
- Wire --download-only through InstallConfig to skip autoloader and installed.json
- Implicitly enable --apcu-autoloader when --apcu-autoloader-prefix is set
- Apply same validation fixes to update, require, remove, create-project commands
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart')
| -rw-r--r-- | crates/mozart/src/commands/create_project.rs | 5 | ||||
| -rw-r--r-- | crates/mozart/src/commands/install.rs | 45 | ||||
| -rw-r--r-- | crates/mozart/src/commands/remove.rs | 4 | ||||
| -rw-r--r-- | crates/mozart/src/commands/require.rs | 3 | ||||
| -rw-r--r-- | crates/mozart/src/commands/update.rs | 5 |
5 files changed, 40 insertions, 22 deletions
diff --git a/crates/mozart/src/commands/create_project.rs b/crates/mozart/src/commands/create_project.rs index 2156477..1aaa4c5 100644 --- a/crates/mozart/src/commands/create_project.rs +++ b/crates/mozart/src/commands/create_project.rs @@ -34,7 +34,7 @@ pub struct CreateProjectArgs { pub prefer_dist: bool, /// Forces usage of a specific install method (dist, source, auto) - #[arg(long)] + #[arg(long, value_parser = ["source", "dist", "auto"])] pub prefer_install: Option<String>, /// Add a custom repository to discover the package @@ -90,7 +90,7 @@ pub struct CreateProjectArgs { pub no_audit: bool, /// Audit output format - #[arg(long)] + #[arg(long, value_parser = ["table", "plain", "json", "summary"])] pub audit_format: Option<String>, /// Do not block on security advisories @@ -480,6 +480,7 @@ pub async fn execute( classmap_authoritative: false, apcu_autoloader: false, apcu_autoloader_prefix: None, + download_only: false, }, ) .await?; diff --git a/crates/mozart/src/commands/install.rs b/crates/mozart/src/commands/install.rs index f29c992..24c79b3 100644 --- a/crates/mozart/src/commands/install.rs +++ b/crates/mozart/src/commands/install.rs @@ -21,7 +21,7 @@ pub struct InstallArgs { pub prefer_dist: bool, /// Forces usage of a specific install method (dist, source, auto) - #[arg(long)] + #[arg(long, value_parser = ["source", "dist", "auto"])] pub prefer_install: Option<String>, /// Only output what would be changed, do not modify files @@ -65,7 +65,7 @@ pub struct InstallArgs { pub audit: bool, /// Audit output format - #[arg(long)] + #[arg(long, value_parser = ["table", "plain", "json", "summary"])] pub audit_format: Option<String>, /// Optimizes PSR-0 and PSR-4 packages to be loaded with classmaps @@ -115,6 +115,8 @@ pub struct InstallConfig { pub apcu_autoloader: bool, /// Custom prefix for APCu autoloader cache. pub apcu_autoloader_prefix: Option<String>, + /// Only download packages, skip autoloader generation and installed.json write. + pub download_only: bool, } impl Default for InstallConfig { @@ -130,6 +132,7 @@ impl Default for InstallConfig { classmap_authoritative: false, apcu_autoloader: false, apcu_autoloader_prefix: None, + download_only: false, } } } @@ -439,23 +442,25 @@ pub async fn install_from_lock( cleanup_empty_vendor_dirs(vendor_dir)?; } - // Step 8: Write updated vendor/composer/installed.json - let mut new_installed = installed::InstalledPackages::new(); - new_installed.dev = dev_mode; + // Step 8: Write updated vendor/composer/installed.json (unless download_only) + if !config.download_only { + let mut new_installed = installed::InstalledPackages::new(); + new_installed.dev = dev_mode; - // Collect dev package names from lock - if dev_mode && let Some(ref dev_pkgs) = lock.packages_dev { - new_installed.dev_package_names = dev_pkgs.iter().map(|p| p.name.clone()).collect(); - } + // Collect dev package names from lock + if dev_mode && let Some(ref dev_pkgs) = lock.packages_dev { + new_installed.dev_package_names = dev_pkgs.iter().map(|p| p.name.clone()).collect(); + } - for pkg in &packages_to_install { - new_installed.upsert(locked_to_installed_entry(pkg, vendor_dir)); - } + for pkg in &packages_to_install { + new_installed.upsert(locked_to_installed_entry(pkg, vendor_dir)); + } - new_installed.write(vendor_dir)?; + new_installed.write(vendor_dir)?; + } - // Step 9: Generate autoloader (unless no_autoloader) - if !config.no_autoloader { + // Step 9: Generate autoloader (unless no_autoloader or download_only) + if !config.no_autoloader && !config.download_only { eprintln!("Generating autoload files"); if config.classmap_authoritative { @@ -508,6 +513,13 @@ pub async fn execute( let working_dir = resolve_working_dir(cli); // Step 2: Validate arguments + if args.prefer_install.is_some() && (args.prefer_source || args.prefer_dist) { + return Err(mozart_core::exit_code::bail( + mozart_core::exit_code::GENERAL_ERROR, + "The --prefer-install option cannot be used together with --prefer-source or --prefer-dist.", + )); + } + if !args.packages.is_empty() { let pkgs = args.packages.join(" "); return Err(mozart_core::exit_code::bail( @@ -623,8 +635,9 @@ pub async fn execute( ignore_platform_req: args.ignore_platform_req.clone(), optimize_autoloader: args.optimize_autoloader, classmap_authoritative: args.classmap_authoritative, - apcu_autoloader: args.apcu_autoloader, + apcu_autoloader: args.apcu_autoloader || args.apcu_autoloader_prefix.is_some(), apcu_autoloader_prefix: args.apcu_autoloader_prefix.clone(), + download_only: args.download_only, }, ) .await diff --git a/crates/mozart/src/commands/remove.rs b/crates/mozart/src/commands/remove.rs index 2b1f1ec..d047ad3 100644 --- a/crates/mozart/src/commands/remove.rs +++ b/crates/mozart/src/commands/remove.rs @@ -36,7 +36,7 @@ pub struct RemoveArgs { pub no_audit: bool, /// Audit output format - #[arg(long)] + #[arg(long, value_parser = ["table", "plain", "json", "summary"])] pub audit_format: Option<String>, /// Do not block on security advisories @@ -430,6 +430,7 @@ pub async fn execute( classmap_authoritative: args.classmap_authoritative, apcu_autoloader: false, apcu_autoloader_prefix: None, + download_only: false, }, ) .await?; @@ -567,6 +568,7 @@ async fn remove_unused( classmap_authoritative: args.classmap_authoritative, apcu_autoloader: false, apcu_autoloader_prefix: None, + download_only: false, }, ) .await?; diff --git a/crates/mozart/src/commands/require.rs b/crates/mozart/src/commands/require.rs index 2082f43..bfd120e 100644 --- a/crates/mozart/src/commands/require.rs +++ b/crates/mozart/src/commands/require.rs @@ -59,7 +59,7 @@ pub struct RequireArgs { pub no_audit: bool, /// Audit output format - #[arg(long)] + #[arg(long, value_parser = ["table", "plain", "json", "summary"])] pub audit_format: Option<String>, /// Do not block on security advisories @@ -777,6 +777,7 @@ pub async fn execute( classmap_authoritative: args.classmap_authoritative, apcu_autoloader: false, apcu_autoloader_prefix: None, + download_only: false, }, ) .await?; diff --git a/crates/mozart/src/commands/update.rs b/crates/mozart/src/commands/update.rs index 8bd694b..f33f1b0 100644 --- a/crates/mozart/src/commands/update.rs +++ b/crates/mozart/src/commands/update.rs @@ -24,7 +24,7 @@ pub struct UpdateArgs { pub prefer_dist: bool, /// Forces usage of a specific install method (dist, source, auto) - #[arg(long)] + #[arg(long, value_parser = ["source", "dist", "auto"])] pub prefer_install: Option<String>, /// Only output what would be changed, do not modify files @@ -52,7 +52,7 @@ pub struct UpdateArgs { pub no_audit: bool, /// Audit output format - #[arg(long)] + #[arg(long, value_parser = ["table", "plain", "json", "summary"])] pub audit_format: Option<String>, /// Do not block on security advisories @@ -1142,6 +1142,7 @@ pub async fn execute( classmap_authoritative: args.classmap_authoritative, apcu_autoloader: false, apcu_autoloader_prefix: None, + download_only: false, }, ) .await?; |
