diff options
Diffstat (limited to 'crates/mozart/src/commands')
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(¤t_exe, &data_dir) } else { - update(args, ¤t_exe, &data_dir) + update(args, ¤t_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, |
