aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart/src/commands
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mozart/src/commands')
-rw-r--r--crates/mozart/src/commands/about.rs2
-rw-r--r--crates/mozart/src/commands/archive.rs11
-rw-r--r--crates/mozart/src/commands/audit.rs4
-rw-r--r--crates/mozart/src/commands/browse.rs8
-rw-r--r--crates/mozart/src/commands/bump.rs44
-rw-r--r--crates/mozart/src/commands/check_platform_reqs.rs2
-rw-r--r--crates/mozart/src/commands/clear_cache.rs2
-rw-r--r--crates/mozart/src/commands/completion.rs2
-rw-r--r--crates/mozart/src/commands/config.rs2
-rw-r--r--crates/mozart/src/commands/create_project.rs15
-rw-r--r--crates/mozart/src/commands/depends.rs2
-rw-r--r--crates/mozart/src/commands/diagnose.rs38
-rw-r--r--crates/mozart/src/commands/dump_autoload.rs2
-rw-r--r--crates/mozart/src/commands/exec.rs2
-rw-r--r--crates/mozart/src/commands/fund.rs2
-rw-r--r--crates/mozart/src/commands/global.rs4
-rw-r--r--crates/mozart/src/commands/init.rs2
-rw-r--r--crates/mozart/src/commands/install.rs8
-rw-r--r--crates/mozart/src/commands/licenses.rs2
-rw-r--r--crates/mozart/src/commands/outdated.rs8
-rw-r--r--crates/mozart/src/commands/prohibits.rs2
-rw-r--r--crates/mozart/src/commands/reinstall.rs5
-rw-r--r--crates/mozart/src/commands/remove.rs24
-rw-r--r--crates/mozart/src/commands/repository.rs2
-rw-r--r--crates/mozart/src/commands/require.rs38
-rw-r--r--crates/mozart/src/commands/run_script.rs2
-rw-r--r--crates/mozart/src/commands/search.rs4
-rw-r--r--crates/mozart/src/commands/self_update.rs47
-rw-r--r--crates/mozart/src/commands/show.rs50
-rw-r--r--crates/mozart/src/commands/status.rs5
-rw-r--r--crates/mozart/src/commands/suggests.rs2
-rw-r--r--crates/mozart/src/commands/update.rs17
-rw-r--r--crates/mozart/src/commands/validate.rs2
33 files changed, 197 insertions, 165 deletions
diff --git a/crates/mozart/src/commands/about.rs b/crates/mozart/src/commands/about.rs
index d436526..9c3ca95 100644
--- a/crates/mozart/src/commands/about.rs
+++ b/crates/mozart/src/commands/about.rs
@@ -4,7 +4,7 @@ use mozart_core::console;
#[derive(Args)]
pub struct AboutArgs {}
-pub fn execute(
+pub async fn execute(
_args: &AboutArgs,
_cli: &super::Cli,
_console: &console::Console,
diff --git a/crates/mozart/src/commands/archive.rs b/crates/mozart/src/commands/archive.rs
index 687e116..08e6bcf 100644
--- a/crates/mozart/src/commands/archive.rs
+++ b/crates/mozart/src/commands/archive.rs
@@ -82,7 +82,7 @@ impl Drop for PackageMeta {
// ─── Main entry point ─────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &ArchiveArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
@@ -148,7 +148,7 @@ pub fn execute(
// 5. Determine source directory and package metadata
let meta: PackageMeta = if let Some(ref pkg_name) = args.package {
// Remote package mode
- resolve_remote_package(pkg_name, args.version.as_deref())?
+ resolve_remote_package(pkg_name, args.version.as_deref()).await?
} else {
// Root package mode
if !composer_json_path.exists() {
@@ -239,7 +239,7 @@ pub fn execute(
// ─── Remote package resolution ────────────────────────────────────────────────
-fn resolve_remote_package(
+async fn resolve_remote_package(
package_name: &str,
version_constraint: Option<&str>,
) -> anyhow::Result<PackageMeta> {
@@ -247,7 +247,7 @@ fn resolve_remote_package(
use mozart_registry::version::find_best_candidate;
// Fetch versions from Packagist
- let versions = mozart_registry::packagist::fetch_package_versions(package_name, None)?;
+ let versions = mozart_registry::packagist::fetch_package_versions(package_name, None).await?;
if versions.is_empty() {
anyhow::bail!("No versions found for package \"{}\"", package_name);
}
@@ -293,7 +293,8 @@ fn resolve_remote_package(
std::fs::create_dir_all(&temp_dir)?;
let bytes =
- mozart_registry::downloader::download_dist(&dist.url, dist.shasum.as_deref(), None, None)?;
+ mozart_registry::downloader::download_dist(&dist.url, dist.shasum.as_deref(), None, None)
+ .await?;
match dist.dist_type.as_str() {
"zip" => mozart_registry::downloader::extract_zip(&bytes, &temp_dir)?,
diff --git a/crates/mozart/src/commands/audit.rs b/crates/mozart/src/commands/audit.rs
index 7fd271f..8f15ef0 100644
--- a/crates/mozart/src/commands/audit.rs
+++ b/crates/mozart/src/commands/audit.rs
@@ -70,7 +70,7 @@ struct AuditResult {
// ─── Main entry point ─────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &AuditArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
@@ -111,7 +111,7 @@ pub fn execute(
// Fetch advisories
let names: Vec<&str> = packages.iter().map(|p| p.name.as_str()).collect();
- let all_advisories = match mozart_registry::packagist::fetch_security_advisories(&names) {
+ let all_advisories = match mozart_registry::packagist::fetch_security_advisories(&names).await {
Ok(a) => a,
Err(e) => {
if args.ignore_unreachable {
diff --git a/crates/mozart/src/commands/browse.rs b/crates/mozart/src/commands/browse.rs
index d662ec0..51ca340 100644
--- a/crates/mozart/src/commands/browse.rs
+++ b/crates/mozart/src/commands/browse.rs
@@ -18,7 +18,7 @@ pub struct BrowseArgs {
// ─── Main entry point ────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &BrowseArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
@@ -45,7 +45,7 @@ pub fn execute(
let mut exit_code = 0i32;
for package_name in &packages {
- match resolve_url(package_name, &working_dir, args.homepage)? {
+ match resolve_url(package_name, &working_dir, args.homepage).await? {
Some(url) => {
if args.show {
println!("{}", url);
@@ -76,7 +76,7 @@ pub fn execute(
// ─── URL resolution ───────────────────────────────────────────────────────────
-fn resolve_url(
+async fn resolve_url(
package_name: &str,
working_dir: &Path,
prefer_homepage: bool,
@@ -109,7 +109,7 @@ fn resolve_url(
}
// 3. Fall back to Packagist API
- match mozart_registry::packagist::fetch_package_versions(package_name, None) {
+ match mozart_registry::packagist::fetch_package_versions(package_name, None).await {
Ok(versions) => {
// Find the latest stable version (first non-dev, or fallback to first)
let best = versions
diff --git a/crates/mozart/src/commands/bump.rs b/crates/mozart/src/commands/bump.rs
index af2809d..42b0d82 100644
--- a/crates/mozart/src/commands/bump.rs
+++ b/crates/mozart/src/commands/bump.rs
@@ -22,7 +22,7 @@ pub struct BumpArgs {
// ─── Main entry point ─────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &BumpArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
@@ -324,8 +324,8 @@ mod tests {
// ── Basic bump ─────────────────────────────────────────────────────────
- #[test]
- fn test_basic_bump_modifies_composer_json() {
+ #[tokio::test]
+ async fn test_basic_bump_modifies_composer_json() {
let dir = tempdir().unwrap();
let composer_json = r#"{
"name": "test/project",
@@ -351,7 +351,7 @@ mod tests {
verbosity: mozart_core::console::Verbosity::Normal,
decorated: false,
};
- execute(&args, &cli, &console).unwrap();
+ execute(&args, &cli, &console).await.unwrap();
let updated = std::fs::read_to_string(dir.path().join("composer.json")).unwrap();
let parsed: serde_json::Value = serde_json::from_str(&updated).unwrap();
@@ -360,8 +360,8 @@ mod tests {
// ── Dry run ────────────────────────────────────────────────────────────
- #[test]
- fn test_dry_run_does_not_modify_files() {
+ #[tokio::test]
+ async fn test_dry_run_does_not_modify_files() {
let dir = tempdir().unwrap();
let composer_json = r#"{
"name": "test/project",
@@ -387,7 +387,7 @@ mod tests {
verbosity: mozart_core::console::Verbosity::Normal,
decorated: false,
};
- execute(&args, &cli, &console).unwrap();
+ execute(&args, &cli, &console).await.unwrap();
// composer.json should be unchanged
let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap();
@@ -397,8 +397,8 @@ mod tests {
// ── No changes ─────────────────────────────────────────────────────────
- #[test]
- fn test_no_changes_when_already_bumped() {
+ #[tokio::test]
+ async fn test_no_changes_when_already_bumped() {
let dir = tempdir().unwrap();
let composer_json = r#"{
"name": "test/project",
@@ -424,7 +424,7 @@ mod tests {
verbosity: mozart_core::console::Verbosity::Normal,
decorated: false,
};
- execute(&args, &cli, &console).unwrap();
+ execute(&args, &cli, &console).await.unwrap();
// No changes should be made
let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap();
@@ -434,8 +434,8 @@ mod tests {
// ── Dev-only flag ──────────────────────────────────────────────────────
- #[test]
- fn test_dev_only_flag_only_bumps_require_dev() {
+ #[tokio::test]
+ async fn test_dev_only_flag_only_bumps_require_dev() {
let dir = tempdir().unwrap();
let composer_json = r#"{
"name": "test/project",
@@ -467,7 +467,7 @@ mod tests {
verbosity: mozart_core::console::Verbosity::Normal,
decorated: false,
};
- execute(&args, &cli, &console).unwrap();
+ execute(&args, &cli, &console).await.unwrap();
let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap();
let parsed: serde_json::Value = serde_json::from_str(&content).unwrap();
@@ -479,8 +479,8 @@ mod tests {
// ── No-dev-only flag ───────────────────────────────────────────────────
- #[test]
- fn test_no_dev_only_flag_only_bumps_require() {
+ #[tokio::test]
+ async fn test_no_dev_only_flag_only_bumps_require() {
let dir = tempdir().unwrap();
let composer_json = r#"{
"name": "test/project",
@@ -512,7 +512,7 @@ mod tests {
verbosity: mozart_core::console::Verbosity::Normal,
decorated: false,
};
- execute(&args, &cli, &console).unwrap();
+ execute(&args, &cli, &console).await.unwrap();
let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap();
let parsed: serde_json::Value = serde_json::from_str(&content).unwrap();
@@ -569,8 +569,8 @@ mod tests {
// ── Lock file hash updated ─────────────────────────────────────────────
- #[test]
- fn test_lock_file_hash_updated_after_bump() {
+ #[tokio::test]
+ async fn test_lock_file_hash_updated_after_bump() {
let dir = tempdir().unwrap();
let composer_json = r#"{
"name": "test/project",
@@ -596,7 +596,7 @@ mod tests {
verbosity: mozart_core::console::Verbosity::Normal,
decorated: false,
};
- execute(&args, &cli, &console).unwrap();
+ execute(&args, &cli, &console).await.unwrap();
// The lock file content-hash should now match the updated composer.json
let updated_composer = std::fs::read_to_string(dir.path().join("composer.json")).unwrap();
@@ -609,8 +609,8 @@ mod tests {
// ── Package filter ─────────────────────────────────────────────────────
- #[test]
- fn test_package_filter_only_bumps_specified_packages() {
+ #[tokio::test]
+ async fn test_package_filter_only_bumps_specified_packages() {
let dir = tempdir().unwrap();
let composer_json = r#"{
"name": "test/project",
@@ -643,7 +643,7 @@ mod tests {
verbosity: mozart_core::console::Verbosity::Normal,
decorated: false,
};
- execute(&args, &cli, &console).unwrap();
+ execute(&args, &cli, &console).await.unwrap();
let content = std::fs::read_to_string(dir.path().join("composer.json")).unwrap();
let parsed: serde_json::Value = serde_json::from_str(&content).unwrap();
diff --git a/crates/mozart/src/commands/check_platform_reqs.rs b/crates/mozart/src/commands/check_platform_reqs.rs
index 71728d3..295f9b7 100644
--- a/crates/mozart/src/commands/check_platform_reqs.rs
+++ b/crates/mozart/src/commands/check_platform_reqs.rs
@@ -52,7 +52,7 @@ struct CheckResult {
// ─── Main entry point ────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &CheckPlatformReqsArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/clear_cache.rs b/crates/mozart/src/commands/clear_cache.rs
index afab64d..e0ae111 100644
--- a/crates/mozart/src/commands/clear_cache.rs
+++ b/crates/mozart/src/commands/clear_cache.rs
@@ -8,7 +8,7 @@ pub struct ClearCacheArgs {
pub gc: bool,
}
-pub fn execute(
+pub async fn execute(
args: &ClearCacheArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/completion.rs b/crates/mozart/src/commands/completion.rs
index 4c2f4a8..d095ce6 100644
--- a/crates/mozart/src/commands/completion.rs
+++ b/crates/mozart/src/commands/completion.rs
@@ -9,7 +9,7 @@ pub struct CompletionArgs {
pub shell: Shell,
}
-pub fn execute(
+pub async fn execute(
args: &CompletionArgs,
_cli: &super::Cli,
_console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/config.rs b/crates/mozart/src/commands/config.rs
index 2a3ab85..2b7d7ba 100644
--- a/crates/mozart/src/commands/config.rs
+++ b/crates/mozart/src/commands/config.rs
@@ -603,7 +603,7 @@ fn render_value(v: &serde_json::Value) -> String {
// ─── execute() ───────────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &ConfigArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/create_project.rs b/crates/mozart/src/commands/create_project.rs
index e9a1911..d5a9b06 100644
--- a/crates/mozart/src/commands/create_project.rs
+++ b/crates/mozart/src/commands/create_project.rs
@@ -170,7 +170,7 @@ fn is_dir_non_empty(path: &Path) -> bool {
.unwrap_or(false)
}
-pub fn execute(
+pub async fn execute(
args: &CreateProjectArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
@@ -278,7 +278,7 @@ pub fn execute(
));
console.info("Loading composer repositories with package information");
- let versions = packagist::fetch_package_versions(&package_name, None)?;
+ let versions = packagist::fetch_package_versions(&package_name, None).await?;
// Find the best candidate matching the version constraint and stability
let best = if let Some(ref constraint) = version_constraint {
@@ -331,7 +331,8 @@ pub fn execute(
);
let bytes =
- downloader::download_dist(&dist.url, dist.shasum.as_deref(), Some(&mut progress), None)?;
+ downloader::download_dist(&dist.url, dist.shasum.as_deref(), Some(&mut progress), None)
+ .await?;
progress.finish();
@@ -422,7 +423,7 @@ pub fn execute(
console.info("Resolving dependencies...");
- let resolved = resolver::resolve(&request).map_err(|e| {
+ let resolved = resolver::resolve(&request).await.map_err(|e| {
mozart_core::exit_code::bail(
mozart_core::exit_code::DEPENDENCY_RESOLUTION_FAILED,
e.to_string(),
@@ -437,7 +438,8 @@ pub fn execute(
composer_json: raw.clone(),
include_dev: dev_mode,
repo_cache: None,
- })?;
+ })
+ .await?;
// Print change report (all will be installs for a new project)
let changes = super::update::compute_update_changes(None, &new_lock, dev_mode);
@@ -498,7 +500,8 @@ pub fn execute(
apcu_autoloader: false,
apcu_autoloader_prefix: None,
},
- )?;
+ )
+ .await?;
Ok(())
}
diff --git a/crates/mozart/src/commands/depends.rs b/crates/mozart/src/commands/depends.rs
index 91b3829..7e7ad70 100644
--- a/crates/mozart/src/commands/depends.rs
+++ b/crates/mozart/src/commands/depends.rs
@@ -19,7 +19,7 @@ pub struct DependsArgs {
pub locked: bool,
}
-pub fn execute(
+pub async fn execute(
args: &DependsArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/diagnose.rs b/crates/mozart/src/commands/diagnose.rs
index 606d00e..da37137 100644
--- a/crates/mozart/src/commands/diagnose.rs
+++ b/crates/mozart/src/commands/diagnose.rs
@@ -76,12 +76,12 @@ fn check_version() -> CheckResult {
/// Check 2 & 3: HTTP/HTTPS connectivity to Packagist.
///
/// Returns Ok if reachable, Fail if not, Skip if network is disabled.
-fn check_http_connectivity(url: &str) -> CheckResult {
+async fn check_http_connectivity(url: &str) -> CheckResult {
if std::env::var("COMPOSER_DISABLE_NETWORK").is_ok() {
return CheckResult::Skip("COMPOSER_DISABLE_NETWORK is set".to_string());
}
- let client = match reqwest::blocking::Client::builder()
+ let client = match reqwest::Client::builder()
.timeout(std::time::Duration::from_secs(10))
.user_agent(concat!("mozart/", env!("CARGO_PKG_VERSION")))
.build()
@@ -90,7 +90,7 @@ fn check_http_connectivity(url: &str) -> CheckResult {
Err(e) => return CheckResult::Fail(format!("Could not build HTTP client: {e}")),
};
- match client.get(url).send() {
+ match client.get(url).send().await {
Ok(resp) => {
let status = resp.status();
if status.is_success() || status.is_redirection() {
@@ -104,12 +104,12 @@ fn check_http_connectivity(url: &str) -> CheckResult {
}
/// Check 4: GitHub API connectivity.
-fn check_github_api() -> CheckResult {
+async fn check_github_api() -> CheckResult {
if std::env::var("COMPOSER_DISABLE_NETWORK").is_ok() {
return CheckResult::Skip("COMPOSER_DISABLE_NETWORK is set".to_string());
}
- let client = match reqwest::blocking::Client::builder()
+ let client = match reqwest::Client::builder()
.timeout(std::time::Duration::from_secs(10))
.user_agent(concat!("mozart/", env!("CARGO_PKG_VERSION")))
.build()
@@ -119,7 +119,7 @@ fn check_github_api() -> CheckResult {
};
let url = "https://api.github.com/";
- match client.get(url).send() {
+ match client.get(url).send().await {
Ok(resp) => {
let status = resp.status();
if status.is_success() || status.is_redirection() {
@@ -371,7 +371,7 @@ fn check_cache_dir(cache_dir: &Path) -> CheckResult {
// ─── Main execute function ─────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
_args: &DiagnoseArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
@@ -402,7 +402,7 @@ pub fn execute(
println!();
// 2. HTTPS connectivity to Packagist
- let https_result = check_http_connectivity("https://repo.packagist.org/packages.json");
+ let https_result = check_http_connectivity("https://repo.packagist.org/packages.json").await;
print_check(
"https connectivity to packagist",
&https_result,
@@ -410,7 +410,7 @@ pub fn execute(
);
// 3. HTTP connectivity to Packagist
- let http_result = check_http_connectivity("http://repo.packagist.org/packages.json");
+ let http_result = check_http_connectivity("http://repo.packagist.org/packages.json").await;
print_check(
"http connectivity to packagist",
&http_result,
@@ -418,7 +418,7 @@ pub fn execute(
);
// 4. GitHub API connectivity
- let github_result = check_github_api();
+ let github_result = check_github_api().await;
print_check("github.com connectivity", &github_result, &mut exit_code);
// 5. HTTP proxy config
@@ -723,30 +723,30 @@ mod tests {
// ── network tests (ignored by default) ───────────────────────────────────
- #[test]
+ #[tokio::test]
#[ignore]
- fn test_check_https_packagist_connectivity() {
- let result = check_http_connectivity("https://repo.packagist.org/packages.json");
+ async fn test_check_https_packagist_connectivity() {
+ let result = check_http_connectivity("https://repo.packagist.org/packages.json").await;
assert!(
matches!(result, CheckResult::Ok(_)),
"expected Ok for HTTPS Packagist connectivity"
);
}
- #[test]
+ #[tokio::test]
#[ignore]
- fn test_check_http_packagist_connectivity() {
- let result = check_http_connectivity("http://repo.packagist.org/packages.json");
+ async fn test_check_http_packagist_connectivity() {
+ let result = check_http_connectivity("http://repo.packagist.org/packages.json").await;
assert!(
matches!(result, CheckResult::Ok(_) | CheckResult::Warning(_)),
"expected Ok or Warning for HTTP Packagist connectivity"
);
}
- #[test]
+ #[tokio::test]
#[ignore]
- fn test_check_github_api_connectivity() {
- let result = check_github_api();
+ async fn test_check_github_api_connectivity() {
+ let result = check_github_api().await;
assert!(
matches!(result, CheckResult::Ok(_)),
"expected Ok for GitHub API connectivity"
diff --git a/crates/mozart/src/commands/dump_autoload.rs b/crates/mozart/src/commands/dump_autoload.rs
index a920f5a..43108ab 100644
--- a/crates/mozart/src/commands/dump_autoload.rs
+++ b/crates/mozart/src/commands/dump_autoload.rs
@@ -48,7 +48,7 @@ pub struct DumpAutoloadArgs {
pub strict_ambiguous: bool,
}
-pub fn execute(
+pub async fn execute(
args: &DumpAutoloadArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/exec.rs b/crates/mozart/src/commands/exec.rs
index 1e785cb..66bc93c 100644
--- a/crates/mozart/src/commands/exec.rs
+++ b/crates/mozart/src/commands/exec.rs
@@ -17,7 +17,7 @@ pub struct ExecArgs {
// ─── Main entry point ────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &ExecArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/fund.rs b/crates/mozart/src/commands/fund.rs
index ad91d6b..181e6e0 100644
--- a/crates/mozart/src/commands/fund.rs
+++ b/crates/mozart/src/commands/fund.rs
@@ -23,7 +23,7 @@ struct FundingEntry {
// ─── Main entry point ───────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &FundArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/global.rs b/crates/mozart/src/commands/global.rs
index 1cde2c1..a646f7a 100644
--- a/crates/mozart/src/commands/global.rs
+++ b/crates/mozart/src/commands/global.rs
@@ -13,7 +13,7 @@ pub struct GlobalArgs {
// ─── Main entry point ────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &GlobalArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
@@ -40,7 +40,7 @@ pub fn execute(
argv.extend(args.args.iter().cloned());
let new_cli = super::Cli::try_parse_from(&argv)?;
- crate::commands::execute(&new_cli)
+ Box::pin(crate::commands::execute(&new_cli)).await
}
// ─── Helpers ─────────────────────────────────────────────────────────────────
diff --git a/crates/mozart/src/commands/init.rs b/crates/mozart/src/commands/init.rs
index 25cc70e..1e8688f 100644
--- a/crates/mozart/src/commands/init.rs
+++ b/crates/mozart/src/commands/init.rs
@@ -55,7 +55,7 @@ pub struct InitArgs {
pub autoload: Option<String>,
}
-pub fn execute(
+pub async fn execute(
args: &InitArgs,
cli: &super::Cli,
console: &console::Console,
diff --git a/crates/mozart/src/commands/install.rs b/crates/mozart/src/commands/install.rs
index 1094d99..d55ba72 100644
--- a/crates/mozart/src/commands/install.rs
+++ b/crates/mozart/src/commands/install.rs
@@ -310,7 +310,7 @@ fn make_progress(show: bool, pkg_name: &str, version: &str) -> downloader::Downl
/// 7. Writes vendor/composer/installed.json
/// 8. Cleans up empty vendor directories
/// 9. Generates the autoloader (unless no_autoloader)
-pub fn install_from_lock(
+pub async fn install_from_lock(
lock: &lockfile::LockFile,
working_dir: &Path,
vendor_dir: &Path,
@@ -418,7 +418,8 @@ pub fn install_from_lock(
&pkg.name,
Some(&mut progress),
None,
- )?;
+ )
+ .await?;
progress.finish();
}
@@ -496,7 +497,7 @@ pub fn install_from_lock(
Ok(())
}
-pub fn execute(
+pub async fn execute(
args: &InstallArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
@@ -590,6 +591,7 @@ pub fn execute(
apcu_autoloader_prefix: args.apcu_autoloader_prefix.clone(),
},
)
+ .await
}
#[cfg(test)]
diff --git a/crates/mozart/src/commands/licenses.rs b/crates/mozart/src/commands/licenses.rs
index 4ffd928..e8e298a 100644
--- a/crates/mozart/src/commands/licenses.rs
+++ b/crates/mozart/src/commands/licenses.rs
@@ -27,7 +27,7 @@ struct LicenseEntry {
// ─── Main entry point ───────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &LicensesArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/outdated.rs b/crates/mozart/src/commands/outdated.rs
index 49c541f..eba0d52 100644
--- a/crates/mozart/src/commands/outdated.rs
+++ b/crates/mozart/src/commands/outdated.rs
@@ -96,7 +96,7 @@ struct OutdatedEntry {
// ─── Main entry point ───────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &OutdatedArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
@@ -179,7 +179,7 @@ pub fn execute(
}
// Fetch latest version from Packagist
- let latest = match fetch_latest_version(&pkg.name) {
+ let latest = match fetch_latest_version(&pkg.name).await {
Ok(v) => v,
Err(_) => {
// Skip packages we can't fetch (platform packages, private, etc.)
@@ -333,11 +333,11 @@ fn load_locked_packages(working_dir: &Path, no_dev: bool) -> anyhow::Result<Vec<
// ─── Version fetching ────────────────────────────────────────────────────────
-fn fetch_latest_version(name: &str) -> anyhow::Result<PackageInfo> {
+async fn fetch_latest_version(name: &str) -> anyhow::Result<PackageInfo> {
use mozart_core::package::Stability;
use mozart_registry::version::find_best_candidate;
- let versions = mozart_registry::packagist::fetch_package_versions(name, None)?;
+ let versions = mozart_registry::packagist::fetch_package_versions(name, None).await?;
let best = find_best_candidate(&versions, Stability::Stable)
.ok_or_else(|| anyhow::anyhow!("No stable version found for {name}"))?;
diff --git a/crates/mozart/src/commands/prohibits.rs b/crates/mozart/src/commands/prohibits.rs
index 3ec01a7..1f45b27 100644
--- a/crates/mozart/src/commands/prohibits.rs
+++ b/crates/mozart/src/commands/prohibits.rs
@@ -22,7 +22,7 @@ pub struct ProhibitsArgs {
pub locked: bool,
}
-pub fn execute(
+pub async fn execute(
args: &ProhibitsArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/reinstall.rs b/crates/mozart/src/commands/reinstall.rs
index d064136..91c2aaf 100644
--- a/crates/mozart/src/commands/reinstall.rs
+++ b/crates/mozart/src/commands/reinstall.rs
@@ -65,7 +65,7 @@ pub struct ReinstallArgs {
// ─── Main entry point ─────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &ReinstallArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
@@ -215,7 +215,8 @@ pub fn execute(
&locked.name,
Some(&mut progress),
Some(&files_cache),
- )?;
+ )
+ .await?;
progress.finish();
reinstalled_count += 1;
diff --git a/crates/mozart/src/commands/remove.rs b/crates/mozart/src/commands/remove.rs
index de4b77b..f869d12 100644
--- a/crates/mozart/src/commands/remove.rs
+++ b/crates/mozart/src/commands/remove.rs
@@ -96,7 +96,7 @@ pub struct RemoveArgs {
pub apcu_autoloader_prefix: Option<String>,
}
-pub fn execute(
+pub async fn execute(
args: &RemoveArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
@@ -285,7 +285,7 @@ pub fn execute(
console.info("Resolving dependencies...");
// Run resolver
- let mut resolved = resolver::resolve(&request).map_err(|e| {
+ let mut resolved = resolver::resolve(&request).await.map_err(|e| {
mozart_core::exit_code::bail(
mozart_core::exit_code::DEPENDENCY_RESOLUTION_FAILED,
e.to_string(),
@@ -370,7 +370,8 @@ pub fn execute(
composer_json: raw.clone(),
include_dev: dev_mode,
repo_cache: None,
- })?;
+ })
+ .await?;
// Compute and print change report
let changes = super::update::compute_update_changes(old_lock.as_ref(), &new_lock, dev_mode);
@@ -468,7 +469,8 @@ pub fn execute(
apcu_autoloader: false,
apcu_autoloader_prefix: None,
},
- )?;
+ )
+ .await?;
}
Ok(())
@@ -681,9 +683,9 @@ mod tests {
// ──────────── Integration tests (network, #[ignore]) ────────────
- #[test]
+ #[tokio::test]
#[ignore]
- fn test_remove_full_e2e() {
+ async fn test_remove_full_e2e() {
use mozart_registry::lockfile::{LockFileGenerationRequest, generate_lock_file};
use mozart_registry::resolver::{ResolveRequest, resolve};
use std::collections::HashMap;
@@ -714,7 +716,9 @@ mod tests {
ignore_platform_req_list: vec![],
repo_cache: None,
};
- let resolved = resolve(&request).expect("initial resolution should succeed");
+ let resolved = resolve(&request)
+ .await
+ .expect("initial resolution should succeed");
let initial_lock = generate_lock_file(&LockFileGenerationRequest {
resolved_packages: resolved,
composer_json_content: content.to_string(),
@@ -722,6 +726,7 @@ mod tests {
include_dev: false,
repo_cache: None,
})
+ .await
.expect("initial lock file generation should succeed");
initial_lock
.write_to_file(&lock_path)
@@ -745,7 +750,9 @@ mod tests {
ignore_platform_req_list: vec![],
repo_cache: None,
};
- let resolved2 = resolve(&request2).expect("post-remove resolution should succeed");
+ let resolved2 = resolve(&request2)
+ .await
+ .expect("post-remove resolution should succeed");
let composer_json_content2 = std::fs::read_to_string(&composer_path).unwrap();
let new_lock = generate_lock_file(&LockFileGenerationRequest {
@@ -755,6 +762,7 @@ mod tests {
include_dev: false,
repo_cache: None,
})
+ .await
.expect("post-remove lock file generation should succeed");
// psr/log should no longer be in the new lock
diff --git a/crates/mozart/src/commands/repository.rs b/crates/mozart/src/commands/repository.rs
index 0974e29..e5d43ec 100644
--- a/crates/mozart/src/commands/repository.rs
+++ b/crates/mozart/src/commands/repository.rs
@@ -35,7 +35,7 @@ pub struct RepositoryArgs {
pub after: Option<String>,
}
-pub fn execute(
+pub async fn execute(
_args: &RepositoryArgs,
_cli: &super::Cli,
_console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/require.rs b/crates/mozart/src/commands/require.rs
index 960182f..0182bb6 100644
--- a/crates/mozart/src/commands/require.rs
+++ b/crates/mozart/src/commands/require.rs
@@ -131,7 +131,7 @@ pub struct RequireArgs {
///
/// Returns a list of `"vendor/package:constraint"` strings that the user confirmed,
/// or an empty vec if the user typed nothing / pressed Ctrl-D immediately.
-fn interactive_search_packages(
+async fn interactive_search_packages(
already_required: &std::collections::HashSet<String>,
preferred_stability: Stability,
fixed: bool,
@@ -165,7 +165,7 @@ fn interactive_search_packages(
}
// Search Packagist
- let (results, total) = match packagist::search_packages(&query, None) {
+ let (results, total) = match packagist::search_packages(&query, None).await {
Ok(r) => r,
Err(e) => {
eprintln!(
@@ -276,7 +276,7 @@ fn interactive_search_packages(
))
);
- match packagist::fetch_package_versions(&package_name, None) {
+ match packagist::fetch_package_versions(&package_name, None).await {
Ok(versions) => {
match version::find_best_candidate(&versions, preferred_stability) {
Some(best) => {
@@ -343,7 +343,7 @@ fn interactive_search_packages(
Ok(selected)
}
-pub fn execute(
+pub async fn execute(
args: &RequireArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
@@ -389,7 +389,7 @@ pub fn execute(
.unwrap_or(Stability::Stable);
let found =
- interactive_search_packages(&already_required, preferred_stability, args.fixed)?;
+ interactive_search_packages(&already_required, preferred_stability, args.fixed).await?;
if found.is_empty() {
// Nothing selected — exit cleanly
@@ -466,7 +466,7 @@ pub fn execute(
))
);
- let versions = packagist::fetch_package_versions(&name, None)?;
+ let versions = packagist::fetch_package_versions(&name, None).await?;
let best = version::find_best_candidate(&versions, preferred_stability)
.ok_or_else(|| {
anyhow::anyhow!(
@@ -606,7 +606,7 @@ pub fn execute(
console.info("Resolving dependencies...");
// Run resolver
- let mut resolved = match resolver::resolve(&request) {
+ let mut resolved = match resolver::resolve(&request).await {
Ok(packages) => packages,
Err(e) => {
return Err(mozart_core::exit_code::bail(
@@ -671,7 +671,8 @@ pub fn execute(
composer_json: raw.clone(),
include_dev: dev_mode,
repo_cache: None,
- })?;
+ })
+ .await?;
// Compute and print change report
let changes = super::update::compute_update_changes(old_lock.as_ref(), &new_lock, dev_mode);
@@ -779,7 +780,8 @@ pub fn execute(
apcu_autoloader: false,
apcu_autoloader_prefix: None,
},
- )?;
+ )
+ .await?;
}
Ok(())
@@ -912,9 +914,9 @@ mod tests {
// Integration tests (network, #[ignore])
// ─────────────────────────────────────────────────────────────────────────
- #[test]
+ #[tokio::test]
#[ignore]
- fn test_require_full_e2e() {
+ async fn test_require_full_e2e() {
use mozart_core::package::RawPackageData;
use mozart_registry::lockfile::{LockFileGenerationRequest, generate_lock_file};
@@ -935,7 +937,9 @@ mod tests {
repo_cache: None,
};
- let resolved = resolver::resolve(&request).expect("Resolution should succeed");
+ let resolved = resolver::resolve(&request)
+ .await
+ .expect("Resolution should succeed");
assert!(!resolved.is_empty());
assert!(resolved.iter().any(|p| p.name == "psr/log"));
@@ -946,6 +950,7 @@ mod tests {
include_dev: false,
repo_cache: None,
})
+ .await
.expect("Lock file generation should succeed");
assert!(!lock.content_hash.is_empty());
@@ -953,9 +958,9 @@ mod tests {
assert!(lock.packages.iter().any(|p| p.name == "psr/log"));
}
- #[test]
+ #[tokio::test]
#[ignore]
- fn test_require_no_install_writes_lock_only() {
+ async fn test_require_no_install_writes_lock_only() {
use mozart_core::package::RawPackageData;
use tempfile::tempdir;
@@ -983,7 +988,9 @@ mod tests {
repo_cache: None,
};
- let resolved = resolver::resolve(&request).expect("Resolution should succeed");
+ let resolved = resolver::resolve(&request)
+ .await
+ .expect("Resolution should succeed");
let new_lock = lockfile::generate_lock_file(&lockfile::LockFileGenerationRequest {
resolved_packages: resolved,
composer_json_content: content.to_string(),
@@ -991,6 +998,7 @@ mod tests {
include_dev: false,
repo_cache: None,
})
+ .await
.expect("Lock file generation should succeed");
// Simulate --no-install: write lock but don't install
diff --git a/crates/mozart/src/commands/run_script.rs b/crates/mozart/src/commands/run_script.rs
index acef421..78dfd69 100644
--- a/crates/mozart/src/commands/run_script.rs
+++ b/crates/mozart/src/commands/run_script.rs
@@ -46,7 +46,7 @@ const INTERNAL_ONLY_EVENTS: &[&str] = &[
// ─── Main entry point ────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &RunScriptArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/search.rs b/crates/mozart/src/commands/search.rs
index 98189ff..a8edc86 100644
--- a/crates/mozart/src/commands/search.rs
+++ b/crates/mozart/src/commands/search.rs
@@ -59,7 +59,7 @@ fn passes_only_vendor(result: &SearchResult, query: &str) -> bool {
vendor.eq_ignore_ascii_case(query)
}
-pub fn execute(
+pub async fn execute(
args: &SearchArgs,
_cli: &super::Cli,
_console: &mozart_core::console::Console,
@@ -67,7 +67,7 @@ pub fn execute(
let query = args.tokens.join(" ");
let (all_results, total) =
- mozart_registry::packagist::search_packages(&query, args.r#type.as_deref())?;
+ mozart_registry::packagist::search_packages(&query, args.r#type.as_deref()).await?;
// Apply client-side filters
let mut results: Vec<&SearchResult> = all_results.iter().collect();
diff --git a/crates/mozart/src/commands/self_update.rs b/crates/mozart/src/commands/self_update.rs
index 03d2643..9f6a7fe 100644
--- a/crates/mozart/src/commands/self_update.rs
+++ b/crates/mozart/src/commands/self_update.rs
@@ -1,5 +1,5 @@
use clap::Args;
-use std::io::{Read, Write};
+use std::io::Write;
use std::path::{Path, PathBuf};
// ─── CLI args ─────────────────────────────────────────────────────────────────
@@ -50,7 +50,7 @@ const BACKUP_EXTENSION: &str = ".old";
// ─── Public entry point ───────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &SelfUpdateArgs,
_cli: &super::Cli,
_console: &mozart_core::console::Console,
@@ -69,7 +69,7 @@ pub fn execute(
if args.rollback {
rollback(&current_exe, &data_dir)
} else {
- update(args, &current_exe, &data_dir)
+ update(args, &current_exe, &data_dir).await
}
}
@@ -128,10 +128,10 @@ fn platform_asset_name() -> anyhow::Result<String> {
// ─── GitHub fetching ──────────────────────────────────────────────────────────
-fn fetch_releases(include_prerelease: bool) -> anyhow::Result<Vec<GitHubRelease>> {
+async fn fetch_releases(include_prerelease: bool) -> anyhow::Result<Vec<GitHubRelease>> {
let url = format!("{GITHUB_API_BASE}/{GITHUB_REPO}/releases");
- let client = reqwest::blocking::Client::builder()
+ let client = reqwest::Client::builder()
.timeout(std::time::Duration::from_secs(30))
.user_agent(concat!("mozart/", env!("CARGO_PKG_VERSION")))
.build()
@@ -140,6 +140,7 @@ fn fetch_releases(include_prerelease: bool) -> anyhow::Result<Vec<GitHubRelease>
let response = client
.get(&url)
.send()
+ .await
.map_err(|e| anyhow::anyhow!("Could not fetch releases from GitHub: {e}"))?;
if !response.status().is_success() {
@@ -151,6 +152,7 @@ fn fetch_releases(include_prerelease: bool) -> anyhow::Result<Vec<GitHubRelease>
let mut releases: Vec<GitHubRelease> = response
.json()
+ .await
.map_err(|e| anyhow::anyhow!("Could not parse GitHub releases response: {e}"))?;
if !include_prerelease {
@@ -203,16 +205,21 @@ fn find_asset<'a>(release: &'a GitHubRelease, asset_name: &str) -> anyhow::Resul
// ─── Download ─────────────────────────────────────────────────────────────────
-fn download_asset(asset: &GitHubAsset, dest: &Path, show_progress: bool) -> anyhow::Result<()> {
- let client = reqwest::blocking::Client::builder()
+async fn download_asset(
+ asset: &GitHubAsset,
+ dest: &Path,
+ show_progress: bool,
+) -> anyhow::Result<()> {
+ let client = reqwest::Client::builder()
.timeout(std::time::Duration::from_secs(300))
.user_agent(concat!("mozart/", env!("CARGO_PKG_VERSION")))
.build()
.map_err(|e| anyhow::anyhow!("Could not build HTTP client: {e}"))?;
- let mut response = client
+ let response = client
.get(&asset.browser_download_url)
.send()
+ .await
.map_err(|e| anyhow::anyhow!("Could not download asset: {e}"))?;
if !response.status().is_success() {
@@ -228,18 +235,16 @@ fn download_asset(asset: &GitHubAsset, dest: &Path, show_progress: bool) -> anyh
let total_bytes = asset.size;
let mut downloaded: u64 = 0;
- let mut buf = [0u8; 8192];
+ let mut stream = response;
- loop {
- let n = response
- .read(&mut buf)
- .map_err(|e| anyhow::anyhow!("Error reading download stream: {e}"))?;
- if n == 0 {
- break;
- }
- file.write_all(&buf[..n])
+ while let Some(chunk) = stream
+ .chunk()
+ .await
+ .map_err(|e| anyhow::anyhow!("Error reading download stream: {e}"))?
+ {
+ file.write_all(&chunk)
.map_err(|e| anyhow::anyhow!("Error writing to destination file: {e}"))?;
- downloaded += n as u64;
+ downloaded += chunk.len() as u64;
if show_progress && total_bytes > 0 {
let pct = (downloaded * 100) / total_bytes;
@@ -257,13 +262,13 @@ fn download_asset(asset: &GitHubAsset, dest: &Path, show_progress: bool) -> anyh
// ─── Core update flow ─────────────────────────────────────────────────────────
-fn update(args: &SelfUpdateArgs, current_exe: &Path, data_dir: &Path) -> anyhow::Result<()> {
+async fn update(args: &SelfUpdateArgs, current_exe: &Path, data_dir: &Path) -> anyhow::Result<()> {
let current_version = get_current_version();
println!("Updating Mozart...");
// Fetch releases
- let releases = fetch_releases(args.preview)?;
+ let releases = fetch_releases(args.preview).await?;
// Find target release
let target_release = find_target_release(&releases, args.version.as_deref())?;
@@ -298,7 +303,7 @@ fn update(args: &SelfUpdateArgs, current_exe: &Path, data_dir: &Path) -> anyhow:
.map_err(|e| anyhow::anyhow!("Could not create temporary file: {e}"))?;
let tmp_path = tmp.path().to_path_buf();
- download_asset(asset, &tmp_path, !args.no_progress)?;
+ download_asset(asset, &tmp_path, !args.no_progress).await?;
// Set executable permission on Unix
#[cfg(unix)]
diff --git a/crates/mozart/src/commands/show.rs b/crates/mozart/src/commands/show.rs
index c6a446d..d329984 100644
--- a/crates/mozart/src/commands/show.rs
+++ b/crates/mozart/src/commands/show.rs
@@ -99,7 +99,7 @@ pub struct ShowArgs {
pub ignore_platform_reqs: bool,
}
-pub fn execute(
+pub async fn execute(
args: &ShowArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
@@ -126,21 +126,21 @@ pub fn execute(
// --available: show available versions for installed packages
if args.available {
- return show_available(args, &working_dir);
+ return show_available(args, &working_dir).await;
}
// --locked: show from lock file
if args.locked {
- return execute_locked(args, &working_dir);
+ return execute_locked(args, &working_dir).await;
}
// Default: installed mode
- execute_installed(args, &working_dir)
+ execute_installed(args, &working_dir).await
}
// ─── Installed mode ────────────────────────────────────────────────────────
-fn execute_installed(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> {
+async fn execute_installed(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> {
let vendor_dir = working_dir.join("vendor");
let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?;
@@ -193,7 +193,7 @@ fn execute_installed(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()>
if let Some(ref package_filter) = args.package {
if package_filter.contains('*') {
packages.retain(|p| matches_wildcard(&p.name, package_filter));
- show_installed_package_list(&packages, args, &vendor_dir)?;
+ show_installed_package_list(&packages, args, &vendor_dir).await?;
return Ok(());
} else {
// Single package detail view
@@ -212,7 +212,7 @@ fn execute_installed(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()>
}
// List view
- show_installed_package_list(&packages, args, &vendor_dir)
+ show_installed_package_list(&packages, args, &vendor_dir).await
}
fn filter_installed_packages<'a>(
@@ -253,7 +253,7 @@ fn filter_installed_packages<'a>(
Ok(packages)
}
-fn show_installed_package_list(
+async fn show_installed_package_list(
packages: &[&mozart_registry::installed::InstalledPackageEntry],
args: &ShowArgs,
_vendor_dir: &Path,
@@ -289,7 +289,7 @@ fn show_installed_package_list(
let description = get_installed_description(pkg);
let latest_info = if show_latest {
- fetch_latest_for_package(&pkg.name).ok()
+ fetch_latest_for_package(&pkg.name).await.ok()
} else {
None
};
@@ -472,11 +472,11 @@ fn extract_major(version_normalized: &str) -> u64 {
.unwrap_or(0)
}
-fn fetch_latest_for_package(name: &str) -> anyhow::Result<LatestInfo> {
+async fn fetch_latest_for_package(name: &str) -> anyhow::Result<LatestInfo> {
use mozart_core::package::Stability;
use mozart_registry::version::find_best_candidate;
- let versions = mozart_registry::packagist::fetch_package_versions(name, None)?;
+ let versions = mozart_registry::packagist::fetch_package_versions(name, None).await?;
let best = find_best_candidate(&versions, Stability::Stable)
.ok_or_else(|| anyhow::anyhow!("No stable version found for {name}"))?;
@@ -644,7 +644,7 @@ fn show_installed_package_detail(
// ─── Locked mode ───────────────────────────────────────────────────────────
-fn execute_locked(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> {
+async fn execute_locked(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> {
let lock_path = working_dir.join("composer.lock");
if !lock_path.exists() {
anyhow::bail!(
@@ -684,18 +684,18 @@ fn execute_locked(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> {
if let Some(ref package_filter) = args.package {
if package_filter.contains('*') {
packages.retain(|p| matches_wildcard(&p.name, package_filter));
- show_locked_package_list(&packages, args)?;
+ show_locked_package_list(&packages, args).await?;
} else {
show_locked_package_detail(&lock, package_filter)?;
}
} else {
- show_locked_package_list(&packages, args)?;
+ show_locked_package_list(&packages, args).await?;
}
Ok(())
}
-fn show_locked_package_list(
+async fn show_locked_package_list(
packages: &[&mozart_registry::lockfile::LockedPackage],
args: &ShowArgs,
) -> anyhow::Result<()> {
@@ -729,7 +729,7 @@ fn show_locked_package_list(
let description = pkg.description.as_deref().unwrap_or("").to_string();
let latest_info = if show_latest {
- fetch_latest_for_package(&pkg.name).ok()
+ fetch_latest_for_package(&pkg.name).await.ok()
} else {
None
};
@@ -1346,10 +1346,10 @@ fn show_platform(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> {
// ─── Available mode ─────────────────────────────────────────────────────────
-fn show_available(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> {
+async fn show_available(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> {
// If a specific package name is given, show available versions for it
if let Some(ref pkg_name) = args.package {
- return show_available_versions(pkg_name, args);
+ return show_available_versions(pkg_name, args).await;
}
// Otherwise, show all installed packages with their available (latest) versions
@@ -1384,7 +1384,7 @@ fn show_available(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> {
if is_platform_package(&pkg.name) {
continue;
}
- show_available_versions_inline(&pkg.name);
+ show_available_versions_inline(&pkg.name).await;
}
return Ok(());
}
@@ -1413,7 +1413,7 @@ fn show_available(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> {
if is_platform_package(&pkg.name) {
continue;
}
- match mozart_registry::packagist::fetch_package_versions(&pkg.name, None) {
+ match mozart_registry::packagist::fetch_package_versions(&pkg.name, None).await {
Ok(versions) => {
let version_strings: Vec<String> =
versions.iter().map(|v| v.version.clone()).collect();
@@ -1441,14 +1441,14 @@ fn show_available(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> {
if is_platform_package(&pkg.name) {
continue;
}
- show_available_versions_inline(&pkg.name);
+ show_available_versions_inline(&pkg.name).await;
}
Ok(())
}
-fn show_available_versions(pkg_name: &str, args: &ShowArgs) -> anyhow::Result<()> {
- let versions = mozart_registry::packagist::fetch_package_versions(pkg_name, None)?;
+async fn show_available_versions(pkg_name: &str, args: &ShowArgs) -> anyhow::Result<()> {
+ let versions = mozart_registry::packagist::fetch_package_versions(pkg_name, None).await?;
if versions.is_empty() {
println!("No versions found for {pkg_name}");
return Ok(());
@@ -1475,8 +1475,8 @@ fn show_available_versions(pkg_name: &str, args: &ShowArgs) -> anyhow::Result<()
Ok(())
}
-fn show_available_versions_inline(pkg_name: &str) {
- match mozart_registry::packagist::fetch_package_versions(pkg_name, None) {
+async fn show_available_versions_inline(pkg_name: &str) {
+ match mozart_registry::packagist::fetch_package_versions(pkg_name, None).await {
Ok(versions) => {
if versions.is_empty() {
println!(
diff --git a/crates/mozart/src/commands/status.rs b/crates/mozart/src/commands/status.rs
index ad6dac1..e29eda3 100644
--- a/crates/mozart/src/commands/status.rs
+++ b/crates/mozart/src/commands/status.rs
@@ -44,7 +44,7 @@ struct PackageStatus {
// ─── Main entry point ────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &StatusArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
@@ -104,7 +104,8 @@ pub fn execute(
dist.shasum.as_deref(),
None,
Some(&files_cache),
- );
+ )
+ .await;
let bytes = match downloaded {
Ok(b) => b,
diff --git a/crates/mozart/src/commands/suggests.rs b/crates/mozart/src/commands/suggests.rs
index d528171..0268fe8 100644
--- a/crates/mozart/src/commands/suggests.rs
+++ b/crates/mozart/src/commands/suggests.rs
@@ -38,7 +38,7 @@ struct Suggestion {
// ─── Main entry point ────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &SuggestsArgs,
cli: &super::Cli,
_console: &mozart_core::console::Console,
diff --git a/crates/mozart/src/commands/update.rs b/crates/mozart/src/commands/update.rs
index 3a7c423..53ee9d7 100644
--- a/crates/mozart/src/commands/update.rs
+++ b/crates/mozart/src/commands/update.rs
@@ -630,7 +630,7 @@ pub fn apply_minimal_changes(
// Main execute function
// ─────────────────────────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &UpdateArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,
@@ -743,7 +743,7 @@ pub fn execute(
}
console.info("Resolving dependencies...");
- let mut resolved = match resolver::resolve(&request) {
+ let mut resolved = match resolver::resolve(&request).await {
Ok(packages) => packages,
Err(e) => {
return Err(mozart_core::exit_code::bail(
@@ -859,7 +859,8 @@ pub fn execute(
composer_json: composer_json.clone(),
include_dev: dev_mode,
repo_cache: None,
- })?;
+ })
+ .await?;
// Step 10: Compute and print change report
let changes = compute_update_changes(old_lock.as_ref(), &new_lock, dev_mode);
@@ -968,7 +969,8 @@ pub fn execute(
apcu_autoloader: false,
apcu_autoloader_prefix: None,
},
- )?;
+ )
+ .await?;
}
Ok(())
@@ -1657,9 +1659,9 @@ mod tests {
// ──────────── Integration test (network, #[ignore]) ────────────
- #[test]
+ #[tokio::test]
#[ignore]
- fn test_update_full_e2e() {
+ async fn test_update_full_e2e() {
use mozart_core::package::RawPackageData;
use mozart_registry::lockfile::{LockFileGenerationRequest, generate_lock_file};
use mozart_registry::resolver::{ResolveRequest, resolve};
@@ -1682,7 +1684,7 @@ mod tests {
repo_cache: None,
};
- let resolved = resolve(&request).expect("Resolution should succeed");
+ let resolved = resolve(&request).await.expect("Resolution should succeed");
assert!(!resolved.is_empty());
assert!(resolved.iter().any(|p| p.name == "monolog/monolog"));
@@ -1693,6 +1695,7 @@ mod tests {
include_dev: false,
repo_cache: None,
})
+ .await
.expect("Lock file generation should succeed");
assert!(!lock.content_hash.is_empty());
diff --git a/crates/mozart/src/commands/validate.rs b/crates/mozart/src/commands/validate.rs
index 50e3cce..6ed4cee 100644
--- a/crates/mozart/src/commands/validate.rs
+++ b/crates/mozart/src/commands/validate.rs
@@ -67,7 +67,7 @@ impl ValidationResult {
// ─── Entry point ─────────────────────────────────────────────────────────────
-pub fn execute(
+pub async fn execute(
args: &ValidateArgs,
cli: &super::Cli,
console: &mozart_core::console::Console,