aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart/src/commands
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-02 17:30:27 +0900
committernsfisis <nsfisis@gmail.com>2026-05-02 17:30:27 +0900
commit99a33b951502d3e80eb70f53551413b9dc0f4d6c (patch)
tree9716d7ac568070032ea7b3141b6763c3443c4589 /crates/mozart/src/commands
parent43efd895d24b7ccd2853fa5bcf08ad0e621f33ce (diff)
downloadphp-mozart-99a33b951502d3e80eb70f53551413b9dc0f4d6c.tar.gz
php-mozart-99a33b951502d3e80eb70f53551413b9dc0f4d6c.tar.zst
php-mozart-99a33b951502d3e80eb70f53551413b9dc0f4d6c.zip
refactor(commands): split install/update into CLI execute + library run
Carve commands::install::execute and commands::update::execute into thin CLI-arg-driven wrappers + run() entry points that take (working_dir, args, console, repositories, executor) directly. The wrappers build a production RepositorySet (Packagist) + FilesystemExecutor from cli, then dispatch to run; in-process tests will call run directly with an empty RepositorySet (Composer's `'packagist' => false` test config) and a tracing InstallerExecutor. The install -> update fallback (no composer.lock present) now goes through update::run, forwarding the caller's repositories + executor so test mocks survive the edge. Also drop the now-dead InstallConfig::no_cache field — install_from_lock stopped consuming the cache when FilesystemExecutor was extracted in the earlier DI plumbing pass, so the field has no effect. All 136 enabled installer fixtures + 114 mozart-registry tests + 541 mozart lib tests still green; clippy clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart/src/commands')
-rw-r--r--crates/mozart/src/commands/create_project.rs1
-rw-r--r--crates/mozart/src/commands/install.rs42
-rw-r--r--crates/mozart/src/commands/remove.rs2
-rw-r--r--crates/mozart/src/commands/require.rs1
-rw-r--r--crates/mozart/src/commands/update.rs45
5 files changed, 60 insertions, 31 deletions
diff --git a/crates/mozart/src/commands/create_project.rs b/crates/mozart/src/commands/create_project.rs
index 01b337e..c2c4f92 100644
--- a/crates/mozart/src/commands/create_project.rs
+++ b/crates/mozart/src/commands/create_project.rs
@@ -522,7 +522,6 @@ pub async fn execute(
apcu_autoloader_prefix: None,
download_only: false,
prefer_source: args.prefer_source,
- no_cache: cli.no_cache,
},
console,
&mut executor,
diff --git a/crates/mozart/src/commands/install.rs b/crates/mozart/src/commands/install.rs
index 5053783..c8b0431 100644
--- a/crates/mozart/src/commands/install.rs
+++ b/crates/mozart/src/commands/install.rs
@@ -121,8 +121,6 @@ pub struct InstallConfig {
pub download_only: bool,
/// Prefer installing from VCS source rather than dist archives.
pub prefer_source: bool,
- /// Disable the files cache entirely.
- pub no_cache: bool,
}
impl Default for InstallConfig {
@@ -140,7 +138,6 @@ impl Default for InstallConfig {
apcu_autoloader_prefix: None,
download_only: false,
prefer_source: false,
- no_cache: false,
}
}
}
@@ -606,14 +603,37 @@ pub async fn install_from_lock(
Ok(())
}
+/// CLI entry point. Builds production [`mozart_registry::repository::RepositorySet`]
+/// (Packagist) and [`FilesystemExecutor`] from `cli`, then dispatches to [`run`].
pub async fn execute(
args: &InstallArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
- // Step 1: Resolve the working directory
+ let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
+ let repositories = std::sync::Arc::new(
+ mozart_registry::repository::RepositorySet::with_packagist(
+ mozart_registry::cache::Cache::repo(&cache_config),
+ ),
+ );
+ let mut executor = FilesystemExecutor::new(mozart_registry::cache::Cache::files(&cache_config));
let working_dir = resolve_working_dir(cli);
+ run(&working_dir, args, console, repositories, &mut executor).await
+}
+/// Library entry point — pure logic, no `Cli` access.
+///
+/// In-process tests construct an empty `RepositorySet` (Composer's
+/// `'packagist' => false` test config) and a tracing `InstallerExecutor`,
+/// then call this function directly to exercise the install flow without
+/// spawning the binary.
+pub async fn run(
+ working_dir: &Path,
+ args: &InstallArgs,
+ console: &mozart_core::console::Console,
+ repositories: std::sync::Arc<mozart_registry::repository::RepositorySet>,
+ executor: &mut dyn InstallerExecutor,
+) -> anyhow::Result<()> {
// Step 2: Validate arguments
if args.prefer_install.is_some() && (args.prefer_source || args.prefer_dist) {
return Err(mozart_core::exit_code::bail(
@@ -691,7 +711,10 @@ pub async fn execute(
root_reqs: false,
bump_after_update: None,
};
- return super::update::execute(&update_args, cli, console).await;
+ // Forward the caller's repositories + executor so in-process tests
+ // see their mocks honored across the install→update fallback edge.
+ return super::update::run(working_dir, &update_args, console, repositories, executor)
+ .await;
}
let lock = lockfile::LockFile::read_from_file(&lock_path)?;
@@ -758,12 +781,10 @@ pub async fn execute(
let vendor_dir = working_dir.join("vendor");
// Step 7: Delegate to shared install_from_lock()
- let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
- let files_cache = mozart_registry::cache::Cache::files(&cache_config);
- let mut executor = FilesystemExecutor::new(files_cache);
+ let _ = repositories; // unused — install_from_lock has no resolver phase
install_from_lock(
&lock,
- &working_dir,
+ working_dir,
&vendor_dir,
&InstallConfig {
dev_mode,
@@ -778,10 +799,9 @@ pub async fn execute(
apcu_autoloader_prefix: args.apcu_autoloader_prefix.clone(),
download_only: args.download_only,
prefer_source,
- no_cache: cli.no_cache,
},
console,
- &mut executor,
+ executor,
)
.await
}
diff --git a/crates/mozart/src/commands/remove.rs b/crates/mozart/src/commands/remove.rs
index 8794a10..e499af0 100644
--- a/crates/mozart/src/commands/remove.rs
+++ b/crates/mozart/src/commands/remove.rs
@@ -452,7 +452,6 @@ pub async fn execute(
apcu_autoloader_prefix: args.apcu_autoloader_prefix.clone(),
download_only: false,
prefer_source: false,
- no_cache: cli.no_cache,
},
console,
&mut executor,
@@ -606,7 +605,6 @@ async fn remove_unused(
apcu_autoloader_prefix: args.apcu_autoloader_prefix.clone(),
download_only: false,
prefer_source: false,
- no_cache,
},
console,
&mut executor,
diff --git a/crates/mozart/src/commands/require.rs b/crates/mozart/src/commands/require.rs
index ead632f..50aa29f 100644
--- a/crates/mozart/src/commands/require.rs
+++ b/crates/mozart/src/commands/require.rs
@@ -872,7 +872,6 @@ pub async fn execute(
apcu_autoloader_prefix: args.apcu_autoloader_prefix.clone(),
download_only: false,
prefer_source: args.prefer_source,
- no_cache: cli.no_cache,
},
console,
&mut executor,
diff --git a/crates/mozart/src/commands/update.rs b/crates/mozart/src/commands/update.rs
index fd533fd..8a0bef7 100644
--- a/crates/mozart/src/commands/update.rs
+++ b/crates/mozart/src/commands/update.rs
@@ -720,17 +720,39 @@ fn major_minor(version: &str) -> (u64, u64) {
// Main execute function
// ─────────────────────────────────────────────────────────────────────────────
+/// CLI entry point. Builds production [`RepositorySet`] (Packagist) and
+/// [`FilesystemExecutor`] from `cli`, then dispatches to [`run`].
pub async fn execute(
args: &UpdateArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
- let repo_cache = mozart_registry::cache::Cache::repo(&cache_config);
-
- // Step 1: Resolve the working directory
+ let repositories = std::sync::Arc::new(
+ mozart_registry::repository::RepositorySet::with_packagist(
+ mozart_registry::cache::Cache::repo(&cache_config),
+ ),
+ );
+ let mut executor = mozart_registry::installer_executor::FilesystemExecutor::new(
+ mozart_registry::cache::Cache::files(&cache_config),
+ );
let working_dir = super::install::resolve_working_dir(cli);
+ run(&working_dir, args, console, repositories, &mut executor).await
+}
+/// Library entry point — pure logic, no CLI / Cli access.
+///
+/// In-process tests construct a `RepositorySet` without `PackagistRepository`
+/// (Composer's `'packagist' => false` test config) and a tracing
+/// `InstallerExecutor`, then call this function directly to exercise the
+/// update flow without spawning the binary.
+pub async fn run(
+ working_dir: &std::path::Path,
+ args: &UpdateArgs,
+ console: &mozart_core::console::Console,
+ repositories: std::sync::Arc<mozart_registry::repository::RepositorySet>,
+ executor: &mut dyn mozart_registry::installer_executor::InstallerExecutor,
+) -> anyhow::Result<()> {
// Step 2: Handle deprecated flags
if args.dev {
console.info(&console_format!(
@@ -863,9 +885,7 @@ pub async fn execute(
platform: PlatformConfig::new(),
ignore_platform_reqs: args.ignore_platform_reqs,
ignore_platform_req_list: args.ignore_platform_req.clone(),
- repositories: std::sync::Arc::new(
- mozart_registry::repository::RepositorySet::with_packagist(repo_cache.clone()),
- ),
+ repositories: repositories.clone(),
temporary_constraints,
raw_repositories: composer_json.repositories.clone(),
};
@@ -1023,9 +1043,7 @@ pub async fn execute(
composer_json_content: composer_json_content.clone(),
composer_json: composer_json.clone(),
include_dev: dev_mode,
- repositories: std::sync::Arc::new(
- mozart_registry::repository::RepositorySet::with_packagist(repo_cache.clone()),
- ),
+ repositories: repositories.clone(),
})
.await?;
@@ -1222,13 +1240,9 @@ pub async fn execute(
.map(|s| s.eq_ignore_ascii_case("source"))
.unwrap_or(false);
- let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
- let files_cache = mozart_registry::cache::Cache::files(&cache_config);
- let mut executor =
- mozart_registry::installer_executor::FilesystemExecutor::new(files_cache);
super::install::install_from_lock(
&new_lock,
- &working_dir,
+ working_dir,
&vendor_dir,
&super::install::InstallConfig {
dev_mode,
@@ -1243,10 +1257,9 @@ pub async fn execute(
apcu_autoloader_prefix: args.apcu_autoloader_prefix.clone(),
download_only: false,
prefer_source,
- no_cache: cli.no_cache,
},
console,
- &mut executor,
+ executor,
)
.await?;
}