diff options
Diffstat (limited to 'crates/mozart/src/commands')
34 files changed, 592 insertions, 530 deletions
diff --git a/crates/mozart/src/commands/about.rs b/crates/mozart/src/commands/about.rs index d60aecf..d436526 100644 --- a/crates/mozart/src/commands/about.rs +++ b/crates/mozart/src/commands/about.rs @@ -1,5 +1,5 @@ -use crate::console; use clap::Args; +use mozart_core::console; #[derive(Args)] pub struct AboutArgs {} diff --git a/crates/mozart/src/commands/archive.rs b/crates/mozart/src/commands/archive.rs index 9be45e9..687e116 100644 --- a/crates/mozart/src/commands/archive.rs +++ b/crates/mozart/src/commands/archive.rs @@ -85,9 +85,9 @@ impl Drop for PackageMeta { pub fn execute( args: &ArchiveArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { - use crate::archiver::{ + use mozart_archiver::{ ArchiveFormat, collect_archivable_files, create_archive, generate_archive_filename, parse_composer_excludes, parse_gitattributes, parse_gitignore_pattern, self_exclusion_patterns, @@ -154,7 +154,7 @@ pub fn execute( if !composer_json_path.exists() { anyhow::bail!("No composer.json found in {}", working_dir.display()); } - let root = crate::package::read_from_file(&composer_json_path)?; + let root = mozart_core::package::read_from_file(&composer_json_path)?; let (archive_name, archive_excludes) = read_archive_config(&composer_json_path)?; let version = root .extra_fields @@ -243,11 +243,11 @@ fn resolve_remote_package( package_name: &str, version_constraint: Option<&str>, ) -> anyhow::Result<PackageMeta> { - use crate::package::Stability; - use crate::version::find_best_candidate; + use mozart_core::package::Stability; + use mozart_registry::version::find_best_candidate; // Fetch versions from Packagist - let versions = crate::packagist::fetch_package_versions(package_name, None)?; + let versions = mozart_registry::packagist::fetch_package_versions(package_name, None)?; if versions.is_empty() { anyhow::bail!("No versions found for package \"{}\"", package_name); } @@ -292,11 +292,12 @@ fn resolve_remote_package( let temp_dir = temp_base.join(&unique); std::fs::create_dir_all(&temp_dir)?; - let bytes = crate::downloader::download_dist(&dist.url, dist.shasum.as_deref(), None, None)?; + let bytes = + mozart_registry::downloader::download_dist(&dist.url, dist.shasum.as_deref(), None, None)?; match dist.dist_type.as_str() { - "zip" => crate::downloader::extract_zip(&bytes, &temp_dir)?, - "tar" | "tar.gz" | "tgz" => crate::downloader::extract_tar_gz(&bytes, &temp_dir)?, + "zip" => mozart_registry::downloader::extract_zip(&bytes, &temp_dir)?, + "tar" | "tar.gz" | "tgz" => mozart_registry::downloader::extract_tar_gz(&bytes, &temp_dir)?, other => { let _ = std::fs::remove_dir_all(&temp_dir); anyhow::bail!("Unsupported dist type: {}", other); diff --git a/crates/mozart/src/commands/audit.rs b/crates/mozart/src/commands/audit.rs index 3e69bb3..7fd271f 100644 --- a/crates/mozart/src/commands/audit.rs +++ b/crates/mozart/src/commands/audit.rs @@ -2,7 +2,7 @@ use clap::Args; use std::collections::BTreeMap; use std::path::{Path, PathBuf}; -use crate::packagist::SecurityAdvisory; +use mozart_registry::packagist::SecurityAdvisory; #[derive(Args)] pub struct AuditArgs { @@ -73,7 +73,7 @@ struct AuditResult { pub fn execute( args: &AuditArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { // Validate format let format = args.format.as_str(); @@ -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 crate::packagist::fetch_security_advisories(&names) { + let all_advisories = match mozart_registry::packagist::fetch_security_advisories(&names) { Ok(a) => a, Err(e) => { if args.ignore_unreachable { @@ -186,7 +186,7 @@ fn load_packages( fn load_installed_packages(working_dir: &Path, no_dev: bool) -> anyhow::Result<Vec<PackageEntry>> { let vendor_dir = working_dir.join("vendor"); - let installed = crate::installed::InstalledPackages::read(&vendor_dir)?; + let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?; let dev_names: std::collections::HashSet<String> = installed .dev_package_names @@ -225,9 +225,10 @@ fn load_locked_packages(working_dir: &Path, no_dev: bool) -> anyhow::Result<Vec< ); } - let lock = crate::lockfile::LockFile::read_from_file(&lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; - let mut all_packages: Vec<&crate::lockfile::LockedPackage> = lock.packages.iter().collect(); + let mut all_packages: Vec<&mozart_registry::lockfile::LockedPackage> = + lock.packages.iter().collect(); if !no_dev && let Some(ref pkgs_dev) = lock.packages_dev { all_packages.extend(pkgs_dev.iter()); @@ -272,7 +273,7 @@ fn filter_advisories( .as_deref() .unwrap_or(pkg.version.as_str()); - let installed_ver = match crate::constraint::Version::parse(version_str) { + let installed_ver = match mozart_constraint::Version::parse(version_str) { Ok(v) => v, Err(_) => { eprintln!( @@ -297,7 +298,7 @@ fn filter_advisories( // Normalize single-pipe OR separators (`|`) to double-pipe (`||`) // since the Packagist API may use either form. let normalized_constraint = normalize_or_separator(&advisory.affected_versions); - let constraint = match crate::constraint::VersionConstraint::parse( + let constraint = match mozart_constraint::VersionConstraint::parse( &normalized_constraint, ) { Ok(c) => c, @@ -391,7 +392,7 @@ fn render_table(result: &AuditResult) { if result.total_advisory_count == 0 && result.abandoned.is_empty() { println!( "{}", - crate::console::info("No security vulnerability advisories found.") + mozart_core::console::info("No security vulnerability advisories found.") ); return; } @@ -406,7 +407,7 @@ fn render_table(result: &AuditResult) { "Found {} security vulnerability {} affecting {} package(s):", result.total_advisory_count, advisory_word, result.affected_package_count ); - println!("{}", crate::console::highlight(&header)); + println!("{}", mozart_core::console::highlight(&header)); println!(); for advisories in result.advisories.values() { @@ -456,7 +457,7 @@ fn render_table(result: &AuditResult) { if !result.abandoned.is_empty() { let header = format!("Found {} abandoned package(s):", result.abandoned.len()); - println!("{}", crate::console::highlight(&header)); + println!("{}", mozart_core::console::highlight(&header)); println!(); let label_width = 20usize; @@ -605,7 +606,7 @@ fn render_summary(result: &AuditResult) { #[cfg(test)] mod tests { use super::*; - use crate::packagist::{AdvisorySource, SecurityAdvisory}; + use mozart_registry::packagist::{AdvisorySource, SecurityAdvisory}; use std::collections::BTreeMap; fn make_advisory( @@ -782,8 +783,8 @@ mod tests { let working_dir = dir.path(); let vendor_dir = working_dir.join("vendor"); - let mut installed = crate::installed::InstalledPackages::new(); - installed.upsert(crate::installed::InstalledPackageEntry { + let mut installed = mozart_registry::installed::InstalledPackages::new(); + installed.upsert(mozart_registry::installed::InstalledPackageEntry { name: "monolog/monolog".to_string(), version: "1.5.0".to_string(), version_normalized: Some("1.5.0.0".to_string()), @@ -811,8 +812,8 @@ mod tests { let working_dir = dir.path(); let vendor_dir = working_dir.join("vendor"); - let mut installed = crate::installed::InstalledPackages::new(); - installed.upsert(crate::installed::InstalledPackageEntry { + let mut installed = mozart_registry::installed::InstalledPackages::new(); + installed.upsert(mozart_registry::installed::InstalledPackageEntry { name: "monolog/monolog".to_string(), version: "1.5.0".to_string(), version_normalized: None, @@ -824,7 +825,7 @@ mod tests { aliases: vec![], extra_fields: BTreeMap::new(), }); - installed.upsert(crate::installed::InstalledPackageEntry { + installed.upsert(mozart_registry::installed::InstalledPackageEntry { name: "phpunit/phpunit".to_string(), version: "10.0.0".to_string(), version_normalized: None, @@ -848,7 +849,7 @@ mod tests { #[test] fn test_load_locked_packages() { - use crate::lockfile::{LockFile, LockedPackage}; + use mozart_registry::lockfile::{LockFile, LockedPackage}; use tempfile::tempdir; let dir = tempdir().unwrap(); @@ -902,7 +903,7 @@ mod tests { #[test] fn test_load_locked_packages_no_dev() { - use crate::lockfile::{LockFile, LockedPackage}; + use mozart_registry::lockfile::{LockFile, LockedPackage}; use tempfile::tempdir; let dir = tempdir().unwrap(); diff --git a/crates/mozart/src/commands/browse.rs b/crates/mozart/src/commands/browse.rs index 0a89ae7..d662ec0 100644 --- a/crates/mozart/src/commands/browse.rs +++ b/crates/mozart/src/commands/browse.rs @@ -21,7 +21,7 @@ pub struct BrowseArgs { pub fn execute( args: &BrowseArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -36,7 +36,7 @@ pub fn execute( "No composer.json found in the current directory and no package specified." ); } - let root = crate::package::read_from_file(&composer_json)?; + let root = mozart_core::package::read_from_file(&composer_json)?; vec![root.name.clone()] } else { args.packages.clone() @@ -57,7 +57,7 @@ pub fn execute( None => { console.info(&format!( "{}", - crate::console::warning(&format!( + mozart_core::console::warning(&format!( "No URL found for package \"{}\".", package_name )) @@ -84,7 +84,7 @@ fn resolve_url( // 1. Check root package (composer.json) let composer_json = working_dir.join("composer.json"); if composer_json.exists() - && let Ok(root) = crate::package::read_from_file(&composer_json) + && let Ok(root) = mozart_core::package::read_from_file(&composer_json) && root.name.eq_ignore_ascii_case(package_name) && let Some(url) = extract_url_from_root(&root, prefer_homepage) { @@ -94,7 +94,7 @@ fn resolve_url( // 2. Check lock file (composer.lock) let lock_path = working_dir.join("composer.lock"); if lock_path.exists() - && let Ok(lock) = crate::lockfile::LockFile::read_from_file(&lock_path) + && let Ok(lock) = mozart_registry::lockfile::LockFile::read_from_file(&lock_path) { let all_packages = lock .packages @@ -109,7 +109,7 @@ fn resolve_url( } // 3. Fall back to Packagist API - match crate::packagist::fetch_package_versions(package_name, None) { + match mozart_registry::packagist::fetch_package_versions(package_name, None) { Ok(versions) => { // Find the latest stable version (first non-dev, or fallback to first) let best = versions @@ -129,7 +129,7 @@ fn resolve_url( // ─── URL extraction ─────────────────────────────────────────────────────────── fn extract_url_from_locked( - pkg: &crate::lockfile::LockedPackage, + pkg: &mozart_registry::lockfile::LockedPackage, prefer_homepage: bool, ) -> Option<String> { if prefer_homepage { @@ -161,7 +161,7 @@ fn extract_url_from_locked( } fn extract_url_from_root( - root: &crate::package::RawPackageData, + root: &mozart_core::package::RawPackageData, prefer_homepage: bool, ) -> Option<String> { if prefer_homepage { @@ -187,7 +187,7 @@ fn extract_url_from_root( } fn extract_url_from_packagist( - pkg: &crate::packagist::PackagistVersion, + pkg: &mozart_registry::packagist::PackagistVersion, prefer_homepage: bool, ) -> Option<String> { if prefer_homepage { @@ -278,14 +278,14 @@ mod tests { source_url: Option<&str>, homepage: Option<&str>, support_source: Option<&str>, - ) -> crate::lockfile::LockedPackage { + ) -> mozart_registry::lockfile::LockedPackage { let support = support_source.map(|s| serde_json::json!({"source": s})); - let source = source_url.map(|url| crate::lockfile::LockedSource { + let source = source_url.map(|url| mozart_registry::lockfile::LockedSource { source_type: "git".to_string(), url: url.to_string(), reference: None, }); - crate::lockfile::LockedPackage { + mozart_registry::lockfile::LockedPackage { name: "vendor/package".to_string(), version: "1.0.0".to_string(), version_normalized: None, diff --git a/crates/mozart/src/commands/bump.rs b/crates/mozart/src/commands/bump.rs index 4c37dd6..af2809d 100644 --- a/crates/mozart/src/commands/bump.rs +++ b/crates/mozart/src/commands/bump.rs @@ -25,7 +25,7 @@ pub struct BumpArgs { pub fn execute( args: &BumpArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -44,7 +44,8 @@ pub fn execute( let composer_json_content = std::fs::read_to_string(&composer_json_path)?; // Parse composer.json - let mut root: crate::package::RawPackageData = serde_json::from_str(&composer_json_content)?; + let mut root: mozart_core::package::RawPackageData = + serde_json::from_str(&composer_json_content)?; // Warn if package is not a project (libraries shouldn't bump) if let Some(ref pkg_type) = root.package_type @@ -52,7 +53,7 @@ pub fn execute( { console.info(&format!( "{}", - crate::console::warning(&format!( + mozart_core::console::warning(&format!( "Warning: Bumping constraints for a non-project package (type=\"{pkg_type}\"). \ Libraries should not pin their dependencies." )) @@ -65,12 +66,12 @@ pub fn execute( } // Read and parse lock file - let lock = crate::lockfile::LockFile::read_from_file(&lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; // Check lock file freshness if !lock.is_fresh(&composer_json_content) { - return Err(crate::exit_code::bail( - crate::exit_code::LOCK_FILE_INVALID, + return Err(mozart_core::exit_code::bail( + mozart_core::exit_code::LOCK_FILE_INVALID, "composer.lock is not up to date with composer.json. \ Run `mozart install` or `mozart update` to refresh it.", )); @@ -107,7 +108,7 @@ pub fn execute( } if let Some((pretty_version, version_normalized)) = locked_versions.get(&pkg_name.to_lowercase()) - && let Some(new_constraint) = crate::version_bumper::bump_requirement( + && let Some(new_constraint) = mozart_core::version_bumper::bump_requirement( constraint, pretty_version, version_normalized.as_deref(), @@ -131,7 +132,7 @@ pub fn execute( } if let Some((pretty_version, version_normalized)) = locked_versions.get(&pkg_name.to_lowercase()) - && let Some(new_constraint) = crate::version_bumper::bump_requirement( + && let Some(new_constraint) = mozart_core::version_bumper::bump_requirement( constraint, pretty_version, version_normalized.as_deref(), @@ -154,16 +155,16 @@ pub fn execute( if args.dry_run { println!( "{}: {} → {}", - crate::console::info(name), + mozart_core::console::info(name), old, - crate::console::comment(new) + mozart_core::console::comment(new) ); } else { println!( "Bumping {} from {} to {}", - crate::console::info(name), + mozart_core::console::info(name), old, - crate::console::comment(new) + mozart_core::console::comment(new) ); } } @@ -182,18 +183,19 @@ pub fn execute( } // Write updated composer.json - crate::package::write_to_file(&root, &composer_json_path)?; + mozart_core::package::write_to_file(&root, &composer_json_path)?; // Update the lock file content-hash to match the new composer.json let new_composer_json_content = std::fs::read_to_string(&composer_json_path)?; - let new_hash = crate::lockfile::LockFile::compute_content_hash(&new_composer_json_content)?; + let new_hash = + mozart_registry::lockfile::LockFile::compute_content_hash(&new_composer_json_content)?; let mut updated_lock = lock; updated_lock.content_hash = new_hash; updated_lock.write_to_file(&lock_path)?; println!( "\n{}", - crate::console::info(&format!( + mozart_core::console::info(&format!( "{} constraint(s) bumped successfully.", total_changes )) @@ -206,7 +208,7 @@ pub fn execute( /// Build a map of lowercase package names to (pretty_version, version_normalized) from composer.lock. fn build_locked_versions_map( - lock: &crate::lockfile::LockFile, + lock: &mozart_registry::lockfile::LockFile, ) -> HashMap<String, (String, Option<String>)> { let mut map: HashMap<String, (String, Option<String>)> = HashMap::new(); @@ -242,7 +244,7 @@ fn is_platform_package(name: &str) -> bool { #[cfg(test)] mod tests { use super::*; - use crate::lockfile::{LockFile, LockedPackage}; + use mozart_registry::lockfile::{LockFile, LockedPackage}; use std::collections::BTreeMap; use tempfile::tempdir; @@ -344,9 +346,9 @@ mod tests { dry_run: false, }; let cli = make_cli(dir.path()); - let console = crate::console::Console { + let console = mozart_core::console::Console { interactive: false, - verbosity: crate::console::Verbosity::Normal, + verbosity: mozart_core::console::Verbosity::Normal, decorated: false, }; execute(&args, &cli, &console).unwrap(); @@ -380,9 +382,9 @@ mod tests { dry_run: true, }; let cli = make_cli(dir.path()); - let console = crate::console::Console { + let console = mozart_core::console::Console { interactive: false, - verbosity: crate::console::Verbosity::Normal, + verbosity: mozart_core::console::Verbosity::Normal, decorated: false, }; execute(&args, &cli, &console).unwrap(); @@ -417,9 +419,9 @@ mod tests { dry_run: false, }; let cli = make_cli(dir.path()); - let console = crate::console::Console { + let console = mozart_core::console::Console { interactive: false, - verbosity: crate::console::Verbosity::Normal, + verbosity: mozart_core::console::Verbosity::Normal, decorated: false, }; execute(&args, &cli, &console).unwrap(); @@ -460,9 +462,9 @@ mod tests { dry_run: false, }; let cli = make_cli(dir.path()); - let console = crate::console::Console { + let console = mozart_core::console::Console { interactive: false, - verbosity: crate::console::Verbosity::Normal, + verbosity: mozart_core::console::Verbosity::Normal, decorated: false, }; execute(&args, &cli, &console).unwrap(); @@ -505,9 +507,9 @@ mod tests { dry_run: false, }; let cli = make_cli(dir.path()); - let console = crate::console::Console { + let console = mozart_core::console::Console { interactive: false, - verbosity: crate::console::Verbosity::Normal, + verbosity: mozart_core::console::Verbosity::Normal, decorated: false, }; execute(&args, &cli, &console).unwrap(); @@ -589,9 +591,9 @@ mod tests { dry_run: false, }; let cli = make_cli(dir.path()); - let console = crate::console::Console { + let console = mozart_core::console::Console { interactive: false, - verbosity: crate::console::Verbosity::Normal, + verbosity: mozart_core::console::Verbosity::Normal, decorated: false, }; execute(&args, &cli, &console).unwrap(); @@ -636,9 +638,9 @@ mod tests { dry_run: false, }; let cli = make_cli(dir.path()); - let console = crate::console::Console { + let console = mozart_core::console::Console { interactive: false, - verbosity: crate::console::Verbosity::Normal, + verbosity: mozart_core::console::Verbosity::Normal, decorated: false, }; execute(&args, &cli, &console).unwrap(); diff --git a/crates/mozart/src/commands/check_platform_reqs.rs b/crates/mozart/src/commands/check_platform_reqs.rs index ad7b860..71728d3 100644 --- a/crates/mozart/src/commands/check_platform_reqs.rs +++ b/crates/mozart/src/commands/check_platform_reqs.rs @@ -55,7 +55,7 @@ struct CheckResult { pub fn execute( args: &CheckPlatformReqsArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -89,7 +89,7 @@ pub fn execute( } // Detect real platform - let platform = crate::platform::detect_platform(); + let platform = mozart_core::platform::detect_platform(); // Check requirements against detected platform let results = check_requirements(&requirements, &platform); @@ -146,7 +146,7 @@ fn collect_requirements( // Always include root composer.json requirements let composer_json_path = working_dir.join("composer.json"); - let root = crate::package::read_from_file(&composer_json_path)?; + let root = mozart_core::package::read_from_file(&composer_json_path)?; add_platform_requirements_from_map(&root.require, "root", &mut requirements); if !args.no_dev { @@ -161,7 +161,7 @@ fn collect_from_lock( no_dev: bool, requirements: &mut BTreeMap<String, Vec<PlatformRequirement>>, ) -> anyhow::Result<()> { - let lock = crate::lockfile::LockFile::read_from_file(lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(lock_path)?; for pkg in &lock.packages { add_platform_requirements_from_map(&pkg.require, &pkg.name, requirements); @@ -181,7 +181,7 @@ fn collect_from_installed( no_dev: bool, requirements: &mut BTreeMap<String, Vec<PlatformRequirement>>, ) -> anyhow::Result<()> { - let installed = crate::installed::InstalledPackages::read(vendor_dir)?; + let installed = mozart_registry::installed::InstalledPackages::read(vendor_dir)?; let dev_names: std::collections::HashSet<String> = installed .dev_package_names @@ -200,7 +200,7 @@ fn collect_from_installed( { for (dep_name, dep_constraint_val) in require_obj { let dep_lower = dep_name.to_lowercase(); - if crate::platform::is_platform_package(&dep_lower) { + if mozart_core::platform::is_platform_package(&dep_lower) { let constraint = dep_constraint_val.as_str().unwrap_or("*").to_string(); requirements .entry(dep_lower) @@ -224,7 +224,7 @@ fn add_platform_requirements_from_map( ) { for (name, constraint) in require { let name_lower = name.to_lowercase(); - if crate::platform::is_platform_package(&name_lower) { + if mozart_core::platform::is_platform_package(&name_lower) { requirements .entry(name_lower) .or_default() @@ -240,7 +240,7 @@ fn add_platform_requirements_from_map( fn check_requirements( requirements: &BTreeMap<String, Vec<PlatformRequirement>>, - platform: &[crate::platform::PlatformPackage], + platform: &[mozart_core::platform::PlatformPackage], ) -> Vec<CheckResult> { let mut results: Vec<CheckResult> = Vec::new(); @@ -279,18 +279,18 @@ fn check_requirements( } Some(detected) => { // Check all constraints - let detected_version = match crate::constraint::Version::parse(&detected.version) { + let detected_version = match mozart_constraint::Version::parse(&detected.version) { Ok(v) => v, Err(_) => { // Unparseable version → treat as 0.0.0 - crate::constraint::Version::parse("0.0.0").unwrap() + mozart_constraint::Version::parse("0.0.0").unwrap() } }; let mut failed_req: Option<(String, String)> = None; for req in reqs { let constraint = - match crate::constraint::VersionConstraint::parse(&req.constraint) { + match mozart_constraint::VersionConstraint::parse(&req.constraint) { Ok(c) => c, Err(_) => continue, // skip unparseable constraints }; @@ -352,9 +352,9 @@ fn render_text(results: &[CheckResult]) { CheckStatus::Success => { println!( "{} {} {}", - crate::console::info(&padded_name), - crate::console::comment(&padded_version), - crate::console::info("success"), + mozart_core::console::info(&padded_name), + mozart_core::console::comment(&padded_version), + mozart_core::console::info("success"), ); } CheckStatus::Failed => { @@ -365,9 +365,9 @@ fn render_text(results: &[CheckResult]) { .unwrap_or(("", "")); println!( "{} {} {} requires {} ({})", - crate::console::comment(&padded_name), - crate::console::comment(&padded_version), - crate::console::error("failed"), + mozart_core::console::comment(&padded_name), + mozart_core::console::comment(&padded_version), + mozart_core::console::error("failed"), provider, constraint, ); @@ -380,9 +380,9 @@ fn render_text(results: &[CheckResult]) { .unwrap_or(("*", "")); println!( "{} {} {} requires {} ({})", - crate::console::comment(&padded_name), - crate::console::comment(&padded_version), - crate::console::error("missing"), + mozart_core::console::comment(&padded_name), + mozart_core::console::comment(&padded_version), + mozart_core::console::error("missing"), provider, constraint, ); @@ -426,7 +426,7 @@ fn render_json(results: &[CheckResult]) -> anyhow::Result<()> { #[cfg(test)] mod tests { use super::*; - use crate::platform::PlatformPackage; + use mozart_core::platform::PlatformPackage; use std::collections::BTreeMap; use tempfile::tempdir; @@ -501,17 +501,25 @@ mod tests { #[test] fn test_is_platform_package() { - assert!(crate::platform::is_platform_package("php")); - assert!(crate::platform::is_platform_package("ext-json")); - assert!(crate::platform::is_platform_package("ext-mbstring")); - assert!(crate::platform::is_platform_package("lib-pcre")); - assert!(crate::platform::is_platform_package("php-64bit")); - assert!(crate::platform::is_platform_package("composer-plugin-api")); - assert!(crate::platform::is_platform_package("composer-runtime-api")); + assert!(mozart_core::platform::is_platform_package("php")); + assert!(mozart_core::platform::is_platform_package("ext-json")); + assert!(mozart_core::platform::is_platform_package("ext-mbstring")); + assert!(mozart_core::platform::is_platform_package("lib-pcre")); + assert!(mozart_core::platform::is_platform_package("php-64bit")); + assert!(mozart_core::platform::is_platform_package( + "composer-plugin-api" + )); + assert!(mozart_core::platform::is_platform_package( + "composer-runtime-api" + )); - assert!(!crate::platform::is_platform_package("monolog/monolog")); - assert!(!crate::platform::is_platform_package("psr/log")); - assert!(!crate::platform::is_platform_package("symfony/console")); + assert!(!mozart_core::platform::is_platform_package( + "monolog/monolog" + )); + assert!(!mozart_core::platform::is_platform_package("psr/log")); + assert!(!mozart_core::platform::is_platform_package( + "symfony/console" + )); } // ── test_collect_requirements_from_lock ────────────────────────────────── diff --git a/crates/mozart/src/commands/clear_cache.rs b/crates/mozart/src/commands/clear_cache.rs index 59baff3..afab64d 100644 --- a/crates/mozart/src/commands/clear_cache.rs +++ b/crates/mozart/src/commands/clear_cache.rs @@ -1,5 +1,5 @@ -use crate::cache::{Cache, build_cache_config}; use clap::Args; +use mozart_registry::cache::{Cache, build_cache_config}; #[derive(Args)] pub struct ClearCacheArgs { @@ -11,9 +11,9 @@ pub struct ClearCacheArgs { pub fn execute( args: &ClearCacheArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { - let config = build_cache_config(cli); + let config = build_cache_config(cli.no_cache); if args.gc { // Run GC only (probabilistic under normal circumstances, but forced here) diff --git a/crates/mozart/src/commands/completion.rs b/crates/mozart/src/commands/completion.rs index 406749c..4c2f4a8 100644 --- a/crates/mozart/src/commands/completion.rs +++ b/crates/mozart/src/commands/completion.rs @@ -12,7 +12,7 @@ pub struct CompletionArgs { pub fn execute( args: &CompletionArgs, _cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let mut cmd = super::Cli::command(); clap_complete::aot::generate(args.shell, &mut cmd, "mozart", &mut std::io::stdout()); diff --git a/crates/mozart/src/commands/config.rs b/crates/mozart/src/commands/config.rs index e875a92..2a3ab85 100644 --- a/crates/mozart/src/commands/config.rs +++ b/crates/mozart/src/commands/config.rs @@ -514,7 +514,7 @@ fn write_json_file(path: &Path, value: &serde_json::Value) -> anyhow::Result<()> { std::fs::create_dir_all(parent)?; } - crate::package::write_to_file(value, path)?; + mozart_core::package::write_to_file(value, path)?; Ok(()) } @@ -606,7 +606,7 @@ fn render_value(v: &serde_json::Value) -> String { pub fn execute( args: &ConfigArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { // 1. Handle --editor mode if args.editor { @@ -1025,7 +1025,7 @@ fn execute_read( None => { eprintln!( "{}", - crate::console::error( + mozart_core::console::error( "No command specified. Use --list to show all config values, \ or provide a setting key." ) diff --git a/crates/mozart/src/commands/create_project.rs b/crates/mozart/src/commands/create_project.rs index 654eb0e..e9a1911 100644 --- a/crates/mozart/src/commands/create_project.rs +++ b/crates/mozart/src/commands/create_project.rs @@ -1,12 +1,12 @@ -use crate::console; -use crate::downloader; -use crate::lockfile; -use crate::package::{self, Stability}; -use crate::packagist; -use crate::resolver::{self, PlatformConfig, ResolveRequest}; -use crate::validation; -use crate::version; use clap::Args; +use mozart_core::console; +use mozart_core::package::{self, Stability}; +use mozart_core::validation; +use mozart_registry::downloader; +use mozart_registry::lockfile; +use mozart_registry::packagist; +use mozart_registry::resolver::{self, PlatformConfig, ResolveRequest}; +use mozart_registry::version; use std::collections::HashMap; use std::path::{Path, PathBuf}; @@ -173,7 +173,7 @@ fn is_dir_non_empty(path: &Path) -> bool { pub fn execute( args: &CreateProjectArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { // --- Handle deprecated / no-op flags --- if args.prefer_source { @@ -423,8 +423,8 @@ pub fn execute( console.info("Resolving dependencies..."); let resolved = resolver::resolve(&request).map_err(|e| { - crate::exit_code::bail( - crate::exit_code::DEPENDENCY_RESOLUTION_FAILED, + mozart_core::exit_code::bail( + mozart_core::exit_code::DEPENDENCY_RESOLUTION_FAILED, e.to_string(), ) })?; diff --git a/crates/mozart/src/commands/dependency.rs b/crates/mozart/src/commands/dependency.rs index 0ae8bb4..4714de2 100644 --- a/crates/mozart/src/commands/dependency.rs +++ b/crates/mozart/src/commands/dependency.rs @@ -67,7 +67,7 @@ pub fn load_packages(working_dir: &Path, locked: bool) -> Result<Vec<PackageInfo // Add the root package (composer.json) as a synthetic entry if composer_json_path.exists() - && let Ok(root) = crate::package::read_from_file(&composer_json_path) + && let Ok(root) = mozart_core::package::read_from_file(&composer_json_path) { // Extract conflict from extra_fields if present let conflict: BTreeMap<String, String> = root @@ -98,7 +98,7 @@ fn load_from_lockfile(lock_path: &Path) -> Result<Vec<PackageInfo>> { if !lock_path.exists() { anyhow::bail!("composer.lock not found — run `mozart install` first or omit --locked"); } - let lock = crate::lockfile::LockFile::read_from_file(lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(lock_path)?; let mut packages: Vec<PackageInfo> = Vec::new(); @@ -131,7 +131,7 @@ fn load_from_lockfile(lock_path: &Path) -> Result<Vec<PackageInfo>> { fn load_from_installed(working_dir: &Path) -> Result<Vec<PackageInfo>> { let vendor_dir = working_dir.join("vendor"); - let installed = crate::installed::InstalledPackages::read(&vendor_dir)?; + let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?; let packages = installed .packages @@ -192,7 +192,7 @@ fn load_from_installed(working_dir: &Path) -> Result<Vec<PackageInfo>> { pub fn get_dependents( packages: &[PackageInfo], needles: &[String], - constraint: Option<&crate::constraint::VersionConstraint>, + constraint: Option<&mozart_constraint::VersionConstraint>, inverted: bool, recursive: bool, ) -> Result<Vec<DependencyResult>> { @@ -317,7 +317,7 @@ fn recurse_dependents( fn get_prohibitors( packages: &[PackageInfo], needles: &[String], - constraint: Option<&crate::constraint::VersionConstraint>, + constraint: Option<&mozart_constraint::VersionConstraint>, _recursive: bool, ) -> Result<Vec<DependencyResult>> { let mut results: Vec<DependencyResult> = Vec::new(); @@ -333,7 +333,7 @@ fn get_prohibitors( .find(|(k, _)| k.to_lowercase() == needle_lower) && let Some(requested_version) = constraint && let Ok(pkg_constraint) = - crate::constraint::VersionConstraint::parse(req_constraint_str) + mozart_constraint::VersionConstraint::parse(req_constraint_str) { // The package requires `needle` but with a different // (incompatible) constraint — it blocks the requested version. @@ -359,7 +359,7 @@ fn get_prohibitors( .find(|(k, _)| k.to_lowercase() == needle_lower) && let Some(requested_version) = constraint && let Ok(pkg_constraint) = - crate::constraint::VersionConstraint::parse(req_constraint_str) + mozart_constraint::VersionConstraint::parse(req_constraint_str) && constraint_prohibits(requested_version, &pkg_constraint) { results.push(DependencyResult { @@ -380,7 +380,7 @@ fn get_prohibitors( .find(|(k, _)| k.to_lowercase() == needle_lower) && let Some(requested_version) = constraint && let Ok(conflict_constraint) = - crate::constraint::VersionConstraint::parse(conflict_constraint_str) + mozart_constraint::VersionConstraint::parse(conflict_constraint_str) { // If the conflict constraint overlaps with (matches) the // requested version range, this package conflicts with it. @@ -408,8 +408,8 @@ fn get_prohibitors( /// We sample a set of "representative versions" from the requested constraint /// and check whether none of them satisfy the package's constraint. fn constraint_prohibits( - requested: &crate::constraint::VersionConstraint, - pkg_constraint: &crate::constraint::VersionConstraint, + requested: &mozart_constraint::VersionConstraint, + pkg_constraint: &mozart_constraint::VersionConstraint, ) -> bool { // We try to determine if there is any version satisfying *requested* that // does NOT satisfy *pkg_constraint*. @@ -430,8 +430,8 @@ fn constraint_prohibits( /// That is, if the conflict constraint matches at least one version that the /// requested constraint also matches. fn constraint_overlaps( - requested: &crate::constraint::VersionConstraint, - conflict_constraint: &crate::constraint::VersionConstraint, + requested: &mozart_constraint::VersionConstraint, + conflict_constraint: &mozart_constraint::VersionConstraint, ) -> bool { let probes = sample_versions_from_constraint(requested); if probes.is_empty() { @@ -446,9 +446,9 @@ fn constraint_overlaps( /// constraint. These are used for the "does this constraint overlap/prohibit /// that constraint?" heuristic. fn sample_versions_from_constraint( - constraint: &crate::constraint::VersionConstraint, -) -> Vec<crate::constraint::Version> { - use crate::constraint::Version; + constraint: &mozart_constraint::VersionConstraint, +) -> Vec<mozart_constraint::Version> { + use mozart_constraint::Version; // Broad grid of versions to probe let candidates: &[&str] = &[ @@ -498,7 +498,7 @@ fn sample_versions_from_constraint( /// Columns: package name | version | link description | link constraint pub fn print_table(results: &[DependencyResult]) { if results.is_empty() { - println!("{}", crate::console::info("No relationships found.")); + println!("{}", mozart_core::console::info("No relationships found.")); return; } @@ -522,10 +522,10 @@ pub fn print_table(results: &[DependencyResult]) { for r in results { println!( "{:<name_w$} {:<ver_w$} {:<desc_w$} {}", - crate::console::info(&r.package_name), - crate::console::comment(&r.package_version), + mozart_core::console::info(&r.package_name), + mozart_core::console::comment(&r.package_version), r.link_description, - crate::console::comment(&r.link_constraint), + mozart_core::console::comment(&r.link_constraint), name_w = name_w, ver_w = ver_w, desc_w = desc_w, @@ -544,7 +544,7 @@ pub fn print_table(results: &[DependencyResult]) { /// ``` pub fn print_tree(results: &[DependencyResult], depth: usize) { if results.is_empty() && depth == 0 { - println!("{}", crate::console::info("No relationships found.")); + println!("{}", mozart_core::console::info("No relationships found.")); return; } @@ -556,10 +556,10 @@ pub fn print_tree(results: &[DependencyResult], depth: usize) { println!( "{}{:<} {} {} {}", prefix, - crate::console::info(&r.package_name), - crate::console::comment(&r.package_version), + mozart_core::console::info(&r.package_name), + mozart_core::console::comment(&r.package_version), r.link_description, - crate::console::comment(&r.link_constraint), + mozart_core::console::comment(&r.link_constraint), ); if !r.children.is_empty() { @@ -685,7 +685,7 @@ mod tests { make_pkg("root/project", "ROOT", &[("vendor/a", "^1.0")], &[], true), make_pkg("vendor/a", "1.0.0", &[], &[], false), ]; - let constraint = crate::constraint::VersionConstraint::parse("2.0.0").unwrap(); + let constraint = mozart_constraint::VersionConstraint::parse("2.0.0").unwrap(); let needles = vec!["vendor/a".to_string()]; let results = get_dependents(&packages, &needles, Some(&constraint), true, false).unwrap(); assert!(!results.is_empty(), "root should prohibit vendor/a 2.0"); @@ -713,7 +713,7 @@ mod tests { false, ), ]; - let constraint = crate::constraint::VersionConstraint::parse("2.0.0").unwrap(); + let constraint = mozart_constraint::VersionConstraint::parse("2.0.0").unwrap(); let needles = vec!["vendor/a".to_string()]; let results = get_dependents(&packages, &needles, Some(&constraint), true, false).unwrap(); // vendor/b conflicts with vendor/a ^2.0 which covers 2.0.0 @@ -733,7 +733,7 @@ mod tests { make_pkg("root/project", "ROOT", &[("vendor/a", "^2.0")], &[], true), make_pkg("vendor/a", "2.0.0", &[], &[], false), ]; - let constraint = crate::constraint::VersionConstraint::parse("2.5.0").unwrap(); + let constraint = mozart_constraint::VersionConstraint::parse("2.5.0").unwrap(); let needles = vec!["vendor/a".to_string()]; let results = get_dependents(&packages, &needles, Some(&constraint), true, false).unwrap(); assert!( diff --git a/crates/mozart/src/commands/depends.rs b/crates/mozart/src/commands/depends.rs index 80e70f1..91b3829 100644 --- a/crates/mozart/src/commands/depends.rs +++ b/crates/mozart/src/commands/depends.rs @@ -22,7 +22,7 @@ pub struct DependsArgs { pub fn execute( args: &DependsArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -34,7 +34,7 @@ pub fn execute( if packages.is_empty() { println!( "{}", - crate::console::info("No packages found. Run `mozart install` first.") + mozart_core::console::info("No packages found. Run `mozart install` first.") ); return Ok(()); } diff --git a/crates/mozart/src/commands/diagnose.rs b/crates/mozart/src/commands/diagnose.rs index 199ed60..606d00e 100644 --- a/crates/mozart/src/commands/diagnose.rs +++ b/crates/mozart/src/commands/diagnose.rs @@ -220,7 +220,7 @@ fn check_composer_lock(working_dir: &Path) -> CheckResult { } }; - let lock = match crate::lockfile::LockFile::read_from_file(&lock_path) { + let lock = match mozart_registry::lockfile::LockFile::read_from_file(&lock_path) { Ok(l) => l, Err(e) => return CheckResult::Fail(format!("composer.lock is invalid: {e}")), }; @@ -374,7 +374,7 @@ fn check_cache_dir(cache_dir: &Path) -> CheckResult { pub fn execute( _args: &DiagnoseArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -551,7 +551,7 @@ mod tests { #[test] fn test_check_composer_lock_fresh() { - use crate::lockfile::LockFile; + use mozart_registry::lockfile::LockFile; let dir = tempdir().unwrap(); @@ -587,7 +587,7 @@ mod tests { #[test] fn test_check_composer_lock_stale() { - use crate::lockfile::LockFile; + use mozart_registry::lockfile::LockFile; let dir = tempdir().unwrap(); diff --git a/crates/mozart/src/commands/dump_autoload.rs b/crates/mozart/src/commands/dump_autoload.rs index 6f38ab9..a920f5a 100644 --- a/crates/mozart/src/commands/dump_autoload.rs +++ b/crates/mozart/src/commands/dump_autoload.rs @@ -51,7 +51,7 @@ pub struct DumpAutoloadArgs { pub fn execute( args: &DumpAutoloadArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -62,14 +62,14 @@ pub fn execute( let dev_mode = !args.no_dev; // Determine suffix: read from existing autoload.php, or from lock file, or generate - let suffix = crate::autoload::determine_suffix(&working_dir, &vendor_dir)?; + let suffix = mozart_autoload::autoload::determine_suffix(&working_dir, &vendor_dir)?; if args.dry_run { console.info("Dry run: would generate autoload files"); return Ok(()); } - crate::autoload::generate(&crate::autoload::AutoloadConfig { + mozart_autoload::autoload::generate(&mozart_autoload::autoload::AutoloadConfig { project_dir: working_dir, vendor_dir, dev_mode, @@ -79,7 +79,7 @@ pub fn execute( apcu: args.apcu, apcu_prefix: args.apcu_prefix.clone(), strict_psr: args.strict_psr, - platform_check: crate::autoload::PlatformCheckMode::Full, + platform_check: mozart_autoload::autoload::PlatformCheckMode::Full, ignore_platform_reqs: args.ignore_platform_reqs, })?; diff --git a/crates/mozart/src/commands/exec.rs b/crates/mozart/src/commands/exec.rs index 32781a5..1e785cb 100644 --- a/crates/mozart/src/commands/exec.rs +++ b/crates/mozart/src/commands/exec.rs @@ -20,7 +20,7 @@ pub struct ExecArgs { pub fn execute( args: &ExecArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -58,7 +58,7 @@ pub fn execute( } else { // Check root composer.json bin entries let composer_json_path = working_dir.join("composer.json"); - if let Ok(root) = crate::package::read_from_file(&composer_json_path) { + if let Ok(root) = mozart_core::package::read_from_file(&composer_json_path) { root.bin.into_iter().find_map(|entry| { let p = working_dir.join(&entry); let stem = Path::new(&entry) @@ -159,7 +159,7 @@ fn get_binaries(working_dir: &Path, bin_dir: &Path) -> Vec<(String, bool)> { // Collect from root composer.json bin entries let composer_json_path = working_dir.join("composer.json"); - if let Ok(root) = crate::package::read_from_file(&composer_json_path) { + if let Ok(root) = mozart_core::package::read_from_file(&composer_json_path) { let existing: std::collections::HashSet<&str> = binaries.iter().map(|(n, _)| n.as_str()).collect(); let mut local: Vec<String> = root @@ -363,7 +363,7 @@ mod tests { assert!(!candidate.exists()); // Confirm root bin entries are also empty - let root = crate::package::read_from_file(&dir.path().join("composer.json")).unwrap(); + let root = mozart_core::package::read_from_file(&dir.path().join("composer.json")).unwrap(); assert!(root.bin.is_empty()); } } diff --git a/crates/mozart/src/commands/fund.rs b/crates/mozart/src/commands/fund.rs index e8a42f5..ad91d6b 100644 --- a/crates/mozart/src/commands/fund.rs +++ b/crates/mozart/src/commands/fund.rs @@ -26,7 +26,7 @@ struct FundingEntry { pub fn execute( args: &FundArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -64,9 +64,10 @@ pub fn execute( fn collect_funding_from_locked(working_dir: &Path) -> anyhow::Result<Vec<FundingEntry>> { let lock_path = working_dir.join("composer.lock"); - let lock = crate::lockfile::LockFile::read_from_file(&lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; - let mut all_packages: Vec<&crate::lockfile::LockedPackage> = lock.packages.iter().collect(); + let mut all_packages: Vec<&mozart_registry::lockfile::LockedPackage> = + lock.packages.iter().collect(); if let Some(ref pkgs_dev) = lock.packages_dev { all_packages.extend(pkgs_dev.iter()); } @@ -94,7 +95,7 @@ fn collect_funding_from_locked(working_dir: &Path) -> anyhow::Result<Vec<Funding fn collect_funding_from_installed(working_dir: &Path) -> anyhow::Result<Vec<FundingEntry>> { let vendor_dir = working_dir.join("vendor"); - let installed = crate::installed::InstalledPackages::read(&vendor_dir)?; + let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?; let entries = installed .packages @@ -361,7 +362,7 @@ mod tests { #[test] fn test_fund_from_lockfile() { - use crate::lockfile::{LockFile, LockedPackage}; + use mozart_registry::lockfile::{LockFile, LockedPackage}; use tempfile::tempdir; let dir = tempdir().unwrap(); @@ -451,7 +452,7 @@ mod tests { let working_dir = dir.path(); let vendor_dir = working_dir.join("vendor"); - let mut installed = crate::installed::InstalledPackages::new(); + let mut installed = mozart_registry::installed::InstalledPackages::new(); let mut extra = BTreeMap::new(); extra.insert( @@ -461,7 +462,7 @@ mod tests { "url": "https://github.com/Seldaek" }]), ); - installed.upsert(crate::installed::InstalledPackageEntry { + installed.upsert(mozart_registry::installed::InstalledPackageEntry { name: "monolog/monolog".to_string(), version: "3.0.0".to_string(), version_normalized: None, @@ -475,7 +476,7 @@ mod tests { }); // Package without funding - installed.upsert(crate::installed::InstalledPackageEntry { + installed.upsert(mozart_registry::installed::InstalledPackageEntry { name: "psr/log".to_string(), version: "3.0.0".to_string(), version_normalized: None, @@ -498,7 +499,7 @@ mod tests { #[test] fn test_fund_no_funding_data() { - use crate::lockfile::{LockFile, LockedPackage}; + use mozart_registry::lockfile::{LockFile, LockedPackage}; use tempfile::tempdir; let dir = tempdir().unwrap(); diff --git a/crates/mozart/src/commands/global.rs b/crates/mozart/src/commands/global.rs index e6e7bc8..1cde2c1 100644 --- a/crates/mozart/src/commands/global.rs +++ b/crates/mozart/src/commands/global.rs @@ -16,7 +16,7 @@ pub struct GlobalArgs { pub fn execute( args: &GlobalArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { use clap::Parser as _; use std::fs; diff --git a/crates/mozart/src/commands/init.rs b/crates/mozart/src/commands/init.rs index be104c6..25cc70e 100644 --- a/crates/mozart/src/commands/init.rs +++ b/crates/mozart/src/commands/init.rs @@ -1,9 +1,9 @@ -use crate::console; -use crate::package::{self, RawAuthor, RawAutoload, RawPackageData, RawRepository}; -use crate::validation; use anyhow::{Context, bail}; use clap::Args; use colored::Colorize; +use mozart_core::console; +use mozart_core::package::{self, RawAuthor, RawAutoload, RawPackageData, RawRepository}; +use mozart_core::validation; use std::collections::BTreeMap; use std::path::{Path, PathBuf}; use std::process::Command; @@ -211,7 +211,7 @@ fn build_interactive( let name = console.ask_validated( &format!( "Package name (<vendor>/<name>) [{}]", - crate::console::comment(&default_name), + mozart_core::console::comment(&default_name), ), &default_name, |val| { @@ -229,7 +229,10 @@ fn build_interactive( // Description let default_desc = args.description.clone().unwrap_or_default(); let description = console.ask( - &format!("Description [{}]", crate::console::comment(&default_desc)), + &format!( + "Description [{}]", + mozart_core::console::comment(&default_desc) + ), &default_desc, ); let description = if description.is_empty() { @@ -248,7 +251,7 @@ fn build_interactive( &format!( "Author [{}n to skip]", if !default_author.is_empty() { - format!("{}, ", crate::console::comment(&default_author)) + format!("{}, ", mozart_core::console::comment(&default_author)) } else { String::new() } @@ -272,7 +275,7 @@ fn build_interactive( let stability_input = console.ask( &format!( "Minimum Stability [{}]", - crate::console::comment(&default_stability), + mozart_core::console::comment(&default_stability), ), &default_stability, ); @@ -292,7 +295,7 @@ fn build_interactive( let type_input = console.ask( &format!( "Package Type (e.g. library, project, metapackage, composer-plugin) [{}]", - crate::console::comment(&default_type), + mozart_core::console::comment(&default_type), ), &default_type, ); @@ -305,7 +308,10 @@ fn build_interactive( // License let default_license = args.license.clone().unwrap_or_default(); let license_input = console.ask( - &format!("License [{}]", crate::console::comment(&default_license),), + &format!( + "License [{}]", + mozart_core::console::comment(&default_license), + ), &default_license, ); let license = if license_input.is_empty() { @@ -319,7 +325,7 @@ fn build_interactive( console.info(""); console.info(&format!( "{}", - crate::console::info("Define your dependencies.") + mozart_core::console::info("Define your dependencies.") )); console.info(""); let require = parse_requirements(&args.require)?; @@ -335,7 +341,7 @@ fn build_interactive( &format!( "Add PSR-4 autoload mapping? Maps namespace \"{}\" to the entered relative path. [{}, n to skip]", namespace, - crate::console::comment(&default_autoload), + mozart_core::console::comment(&default_autoload), ), &default_autoload, ); diff --git a/crates/mozart/src/commands/install.rs b/crates/mozart/src/commands/install.rs index fb7335b..1094d99 100644 --- a/crates/mozart/src/commands/install.rs +++ b/crates/mozart/src/commands/install.rs @@ -1,8 +1,8 @@ -use crate::console; -use crate::downloader; -use crate::installed; -use crate::lockfile; use clap::Args; +use mozart_core::console; +use mozart_registry::downloader; +use mozart_registry::installed; +use mozart_registry::lockfile; use std::collections::{BTreeMap, HashSet}; use std::path::{Path, PathBuf}; @@ -475,7 +475,7 @@ pub fn install_from_lock( let suffix = lock.content_hash.clone(); - crate::autoload::generate(&crate::autoload::AutoloadConfig { + mozart_autoload::autoload::generate(&mozart_autoload::autoload::AutoloadConfig { project_dir: working_dir.to_path_buf(), vendor_dir: vendor_dir.to_path_buf(), dev_mode, @@ -485,7 +485,7 @@ pub fn install_from_lock( apcu: config.apcu_autoloader, apcu_prefix: config.apcu_autoloader_prefix.clone(), strict_psr: false, - platform_check: crate::autoload::PlatformCheckMode::Full, + platform_check: mozart_autoload::autoload::PlatformCheckMode::Full, ignore_platform_reqs: config.ignore_platform_reqs, })?; @@ -499,7 +499,7 @@ pub fn install_from_lock( pub fn execute( args: &InstallArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { // Step 1: Resolve the working directory let working_dir = resolve_working_dir(cli); @@ -507,8 +507,8 @@ pub fn execute( // Step 2: Validate arguments if !args.packages.is_empty() { let pkgs = args.packages.join(" "); - return Err(crate::exit_code::bail( - crate::exit_code::GENERAL_ERROR, + return Err(mozart_core::exit_code::bail( + mozart_core::exit_code::GENERAL_ERROR, format!( "Invalid argument {pkgs}. Use \"mozart require {pkgs}\" instead to add packages to your composer.json." ), @@ -516,8 +516,8 @@ pub fn execute( } if args.no_install { - return Err(crate::exit_code::bail( - crate::exit_code::GENERAL_ERROR, + return Err(mozart_core::exit_code::bail( + mozart_core::exit_code::GENERAL_ERROR, "Invalid option \"--no-install\". Use \"mozart update --no-install\" instead if you are trying to update the composer.lock file.", )); } @@ -537,8 +537,8 @@ pub fn execute( // Step 3: Read composer.lock let lock_path = working_dir.join("composer.lock"); if !lock_path.exists() { - return Err(crate::exit_code::bail( - crate::exit_code::LOCK_FILE_INVALID, + return Err(mozart_core::exit_code::bail( + mozart_core::exit_code::LOCK_FILE_INVALID, "No composer.lock file present. Run \"mozart update\" to generate one.", )); } diff --git a/crates/mozart/src/commands/licenses.rs b/crates/mozart/src/commands/licenses.rs index 0703976..4ffd928 100644 --- a/crates/mozart/src/commands/licenses.rs +++ b/crates/mozart/src/commands/licenses.rs @@ -30,7 +30,7 @@ struct LicenseEntry { pub fn execute( args: &LicensesArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -51,7 +51,7 @@ pub fn execute( if !composer_json_path.exists() { anyhow::bail!("No composer.json found in {}", working_dir.display()); } - let root = crate::package::read_from_file(&composer_json_path)?; + let root = mozart_core::package::read_from_file(&composer_json_path)?; let root_name = root.name.clone(); let root_version = root @@ -98,7 +98,7 @@ pub fn execute( fn load_installed_licenses(working_dir: &Path, no_dev: bool) -> anyhow::Result<Vec<LicenseEntry>> { let vendor_dir = working_dir.join("vendor"); - let installed = crate::installed::InstalledPackages::read(&vendor_dir)?; + let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?; let dev_names: HashSet<String> = installed .dev_package_names @@ -134,9 +134,10 @@ fn load_locked_licenses(working_dir: &Path, no_dev: bool) -> anyhow::Result<Vec< ); } - let lock = crate::lockfile::LockFile::read_from_file(&lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; - let mut all_packages: Vec<&crate::lockfile::LockedPackage> = lock.packages.iter().collect(); + let mut all_packages: Vec<&mozart_registry::lockfile::LockedPackage> = + lock.packages.iter().collect(); if !no_dev && let Some(ref pkgs_dev) = lock.packages_dev { all_packages.extend(pkgs_dev.iter()); @@ -157,7 +158,9 @@ fn load_locked_licenses(working_dir: &Path, no_dev: bool) -> anyhow::Result<Vec< // ─── License extraction ─────────────────────────────────────────────────────── -fn extract_installed_licenses(pkg: &crate::installed::InstalledPackageEntry) -> Vec<String> { +fn extract_installed_licenses( + pkg: &mozart_registry::installed::InstalledPackageEntry, +) -> Vec<String> { pkg.extra_fields .get("license") .and_then(|v| v.as_array()) @@ -205,9 +208,12 @@ fn render_text( root_licenses.join(", ") }; // Print root package header - println!("Name: {}", crate::console::comment(root_name)); - println!("Version: {}", crate::console::comment(root_version)); - println!("Licenses: {}", crate::console::comment(&license_display)); + println!("Name: {}", mozart_core::console::comment(root_name)); + println!("Version: {}", mozart_core::console::comment(root_version)); + println!( + "Licenses: {}", + mozart_core::console::comment(&license_display) + ); println!("Dependencies:"); println!(); @@ -312,8 +318,8 @@ mod tests { name: &str, version: &str, extra: BTreeMap<String, serde_json::Value>, - ) -> crate::installed::InstalledPackageEntry { - crate::installed::InstalledPackageEntry { + ) -> mozart_registry::installed::InstalledPackageEntry { + mozart_registry::installed::InstalledPackageEntry { name: name.to_string(), version: version.to_string(), version_normalized: None, @@ -429,10 +435,10 @@ mod tests { .unwrap(); // Build installed packages - let mut installed = crate::installed::InstalledPackages::new(); + let mut installed = mozart_registry::installed::InstalledPackages::new(); let mut extra = BTreeMap::new(); extra.insert("license".to_string(), serde_json::json!(["MIT"])); - installed.upsert(crate::installed::InstalledPackageEntry { + installed.upsert(mozart_registry::installed::InstalledPackageEntry { name: "monolog/monolog".to_string(), version: "3.0.0".to_string(), version_normalized: None, @@ -468,12 +474,12 @@ mod tests { ) .unwrap(); - let mut installed = crate::installed::InstalledPackages::new(); + let mut installed = mozart_registry::installed::InstalledPackages::new(); // Production package let mut extra_prod = BTreeMap::new(); extra_prod.insert("license".to_string(), serde_json::json!(["MIT"])); - installed.upsert(crate::installed::InstalledPackageEntry { + installed.upsert(mozart_registry::installed::InstalledPackageEntry { name: "monolog/monolog".to_string(), version: "3.0.0".to_string(), version_normalized: None, @@ -489,7 +495,7 @@ mod tests { // Dev package let mut extra_dev = BTreeMap::new(); extra_dev.insert("license".to_string(), serde_json::json!(["BSD-3-Clause"])); - installed.upsert(crate::installed::InstalledPackageEntry { + installed.upsert(mozart_registry::installed::InstalledPackageEntry { name: "phpunit/phpunit".to_string(), version: "10.0.0".to_string(), version_normalized: None, @@ -519,7 +525,7 @@ mod tests { #[test] fn test_load_locked_licenses_basic() { - use crate::lockfile::{LockFile, LockedPackage}; + use mozart_registry::lockfile::{LockFile, LockedPackage}; use tempfile::tempdir; let dir = tempdir().unwrap(); diff --git a/crates/mozart/src/commands/outdated.rs b/crates/mozart/src/commands/outdated.rs index b6672c4..49c541f 100644 --- a/crates/mozart/src/commands/outdated.rs +++ b/crates/mozart/src/commands/outdated.rs @@ -99,7 +99,7 @@ struct OutdatedEntry { pub fn execute( args: &OutdatedArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -120,7 +120,7 @@ pub fn execute( // Load root composer.json for --direct filtering and constraint lookup let composer_json_path = working_dir.join("composer.json"); let root_package = if composer_json_path.exists() { - crate::package::read_from_file(&composer_json_path).ok() + mozart_core::package::read_from_file(&composer_json_path).ok() } else { None }; @@ -247,7 +247,7 @@ pub fn execute( fn load_installed_packages(working_dir: &Path, no_dev: bool) -> anyhow::Result<Vec<PackageInfo>> { let vendor_dir = working_dir.join("vendor"); - let installed = crate::installed::InstalledPackages::read(&vendor_dir)?; + let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?; let dev_names: HashSet<String> = installed .dev_package_names @@ -301,9 +301,10 @@ fn load_locked_packages(working_dir: &Path, no_dev: bool) -> anyhow::Result<Vec< ); } - let lock = crate::lockfile::LockFile::read_from_file(&lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; - let mut all_packages: Vec<&crate::lockfile::LockedPackage> = lock.packages.iter().collect(); + let mut all_packages: Vec<&mozart_registry::lockfile::LockedPackage> = + lock.packages.iter().collect(); if !no_dev && let Some(ref pkgs_dev) = lock.packages_dev { all_packages.extend(pkgs_dev.iter()); @@ -333,10 +334,10 @@ fn load_locked_packages(working_dir: &Path, no_dev: bool) -> anyhow::Result<Vec< // ─── Version fetching ──────────────────────────────────────────────────────── fn fetch_latest_version(name: &str) -> anyhow::Result<PackageInfo> { - use crate::package::Stability; - use crate::version::find_best_candidate; + use mozart_core::package::Stability; + use mozart_registry::version::find_best_candidate; - let versions = crate::packagist::fetch_package_versions(name, None)?; + let versions = mozart_registry::packagist::fetch_package_versions(name, None)?; let best = find_best_candidate(&versions, Stability::Stable) .ok_or_else(|| anyhow::anyhow!("No stable version found for {name}"))?; @@ -361,7 +362,7 @@ fn classify_update( latest_normalized: &str, root_constraint: Option<&str>, ) -> UpdateCategory { - use crate::version::compare_normalized_versions; + use mozart_registry::version::compare_normalized_versions; // If latest is not newer than current, it's up-to-date if compare_normalized_versions(latest_normalized, current_normalized) != Ordering::Greater { @@ -370,8 +371,8 @@ fn classify_update( // We have an update available — classify it if let Some(constraint_str) = root_constraint - && let Ok(constraint) = crate::constraint::VersionConstraint::parse(constraint_str) - && let Ok(latest_ver) = crate::constraint::Version::parse(latest_normalized) + && let Ok(constraint) = mozart_constraint::VersionConstraint::parse(constraint_str) + && let Ok(latest_ver) = mozart_constraint::Version::parse(latest_normalized) { if constraint.matches(&latest_ver) { return UpdateCategory::SemverCompatible; @@ -460,7 +461,10 @@ fn passes_level_filter(args: &OutdatedArgs, current: &str, latest: &str) -> bool fn render_text(entries: &[OutdatedEntry]) { if entries.is_empty() { - println!("{}", crate::console::info("All packages are up to date.")); + println!( + "{}", + mozart_core::console::info("All packages are up to date.") + ); return; } @@ -484,23 +488,23 @@ fn render_text(entries: &[OutdatedEntry]) { let (name_str, lat_str) = match entry.category { UpdateCategory::UpToDate => ( - crate::console::info(&name_col).to_string(), - crate::console::info(&lat_col).to_string(), + mozart_core::console::info(&name_col).to_string(), + mozart_core::console::info(&lat_col).to_string(), ), UpdateCategory::SemverCompatible => ( - crate::console::highlight(&name_col).to_string(), - crate::console::highlight(&lat_col).to_string(), + mozart_core::console::highlight(&name_col).to_string(), + mozart_core::console::highlight(&lat_col).to_string(), ), UpdateCategory::SemverIncompatible => ( - crate::console::comment(&name_col).to_string(), - crate::console::comment(&lat_col).to_string(), + mozart_core::console::comment(&name_col).to_string(), + mozart_core::console::comment(&lat_col).to_string(), ), }; println!( "{} {} {} {}", name_str, - crate::console::comment(&cur_col), + mozart_core::console::comment(&cur_col), lat_str, entry.description ); diff --git a/crates/mozart/src/commands/prohibits.rs b/crates/mozart/src/commands/prohibits.rs index f545bb2..3ec01a7 100644 --- a/crates/mozart/src/commands/prohibits.rs +++ b/crates/mozart/src/commands/prohibits.rs @@ -25,7 +25,7 @@ pub struct ProhibitsArgs { pub fn execute( args: &ProhibitsArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -37,13 +37,13 @@ pub fn execute( if packages.is_empty() { println!( "{}", - crate::console::info("No packages found. Run `mozart install` first.") + mozart_core::console::info("No packages found. Run `mozart install` first.") ); return Ok(()); } // Parse the version constraint the user is asking about - let version_constraint = crate::constraint::VersionConstraint::parse(&args.version) + let version_constraint = mozart_constraint::VersionConstraint::parse(&args.version) .map_err(|e| anyhow::anyhow!("Invalid version constraint '{}': {}", args.version, e))?; let recursive = args.tree || args.recursive; @@ -61,7 +61,7 @@ pub fn execute( if results.is_empty() { println!( "{}", - crate::console::info(&format!( + mozart_core::console::info(&format!( "{} {} can be installed.", args.package, args.version )) diff --git a/crates/mozart/src/commands/reinstall.rs b/crates/mozart/src/commands/reinstall.rs index 78611b4..d064136 100644 --- a/crates/mozart/src/commands/reinstall.rs +++ b/crates/mozart/src/commands/reinstall.rs @@ -68,7 +68,7 @@ pub struct ReinstallArgs { pub fn execute( args: &ReinstallArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { // Step 1: Resolve working directory let working_dir = match &cli.working_dir { @@ -79,7 +79,7 @@ pub fn execute( let vendor_dir = working_dir.join("vendor"); // Step 2: Read installed.json - let installed = crate::installed::InstalledPackages::read(&vendor_dir)?; + let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?; // Step 3: Read composer.lock let lock_path = working_dir.join("composer.lock"); @@ -89,7 +89,7 @@ pub fn execute( working_dir.display() ); } - let lock = crate::lockfile::LockFile::read_from_file(&lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; // Step 4: Validate — error if both --type and package names are provided; // error if neither is provided. @@ -116,7 +116,7 @@ pub fn execute( .map(|n| n.to_lowercase()) .collect(); - let candidates: Vec<&crate::installed::InstalledPackageEntry> = installed + let candidates: Vec<&mozart_registry::installed::InstalledPackageEntry> = installed .packages .iter() .filter(|pkg| { @@ -128,7 +128,7 @@ pub fn execute( }) .collect(); - let selected: Vec<&crate::installed::InstalledPackageEntry> = if has_type { + let selected: Vec<&mozart_registry::installed::InstalledPackageEntry> = if has_type { filter_by_type(&candidates, &args.r#type) } else { filter_by_names(&candidates, &args.packages) @@ -141,7 +141,7 @@ pub fn execute( // Step 6: For each selected package, find its locked metadata. // Build a lookup map: lowercase name -> LockedPackage - let all_locked: Vec<&crate::lockfile::LockedPackage> = lock + let all_locked: Vec<&mozart_registry::lockfile::LockedPackage> = lock .packages .iter() .chain(lock.packages_dev.as_deref().unwrap_or(&[])) @@ -161,8 +161,8 @@ pub fn execute( } // Step 8: For each package, remove vendor dir and re-download. - let cache_config = crate::cache::build_cache_config(cli); - let files_cache = crate::cache::Cache::files(&cache_config); + let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache); + let files_cache = mozart_registry::cache::Cache::files(&cache_config); let mut reinstalled_count = 0usize; @@ -202,12 +202,12 @@ pub fn execute( } // Re-download and install - let mut progress = crate::downloader::DownloadProgress::new( + let mut progress = mozart_registry::downloader::DownloadProgress::new( !args.no_progress, format!("{} ({})", locked.name, locked.version), ); - crate::downloader::install_package( + mozart_registry::downloader::install_package( &dist.url, &dist.dist_type, dist.shasum.as_deref(), @@ -233,7 +233,7 @@ pub fn execute( let dev_mode = !args.no_dev && installed.dev; let suffix = lock.content_hash.clone(); - crate::autoload::generate(&crate::autoload::AutoloadConfig { + mozart_autoload::autoload::generate(&mozart_autoload::autoload::AutoloadConfig { project_dir: working_dir.to_path_buf(), vendor_dir: vendor_dir.to_path_buf(), dev_mode, @@ -243,7 +243,7 @@ pub fn execute( apcu: args.apcu_autoloader, apcu_prefix: args.apcu_autoloader_prefix.clone(), strict_psr: false, - platform_check: crate::autoload::PlatformCheckMode::Full, + platform_check: mozart_autoload::autoload::PlatformCheckMode::Full, ignore_platform_reqs: args.ignore_platform_reqs, })?; @@ -257,9 +257,9 @@ pub fn execute( /// Filter candidates by package type (case-insensitive). fn filter_by_type<'a>( - candidates: &[&'a crate::installed::InstalledPackageEntry], + candidates: &[&'a mozart_registry::installed::InstalledPackageEntry], types: &[String], -) -> Vec<&'a crate::installed::InstalledPackageEntry> { +) -> Vec<&'a mozart_registry::installed::InstalledPackageEntry> { let lower_types: Vec<String> = types.iter().map(|t| t.to_lowercase()).collect(); candidates .iter() @@ -280,9 +280,9 @@ fn filter_by_type<'a>( /// Patterns support `*` as a wildcard matching any sequence of characters /// (including `/`). fn filter_by_names<'a>( - candidates: &[&'a crate::installed::InstalledPackageEntry], + candidates: &[&'a mozart_registry::installed::InstalledPackageEntry], patterns: &[String], -) -> Vec<&'a crate::installed::InstalledPackageEntry> { +) -> Vec<&'a mozart_registry::installed::InstalledPackageEntry> { candidates .iter() .filter(|pkg| { @@ -339,9 +339,9 @@ fn glob_matches(pattern: &str, value: &str) -> bool { /// Find a locked package by name (case-insensitive). fn find_locked_package<'a>( - locked: &[&'a crate::lockfile::LockedPackage], + locked: &[&'a mozart_registry::lockfile::LockedPackage], name: &str, -) -> Option<&'a crate::lockfile::LockedPackage> { +) -> Option<&'a mozart_registry::lockfile::LockedPackage> { let name_lower = name.to_lowercase(); locked .iter() @@ -361,8 +361,8 @@ mod tests { fn make_installed_entry( name: &str, pkg_type: Option<&str>, - ) -> crate::installed::InstalledPackageEntry { - crate::installed::InstalledPackageEntry { + ) -> mozart_registry::installed::InstalledPackageEntry { + mozart_registry::installed::InstalledPackageEntry { name: name.to_string(), version: "1.0.0".to_string(), version_normalized: None, @@ -376,8 +376,8 @@ mod tests { } } - fn make_locked_package(name: &str, version: &str) -> crate::lockfile::LockedPackage { - crate::lockfile::LockedPackage { + fn make_locked_package(name: &str, version: &str) -> mozart_registry::lockfile::LockedPackage { + mozart_registry::lockfile::LockedPackage { name: name.to_string(), version: version.to_string(), version_normalized: None, @@ -453,7 +453,7 @@ mod tests { make_locked_package("psr/log", "3.0.0"), make_locked_package("monolog/monolog", "3.8.0"), ]; - let refs: Vec<&crate::lockfile::LockedPackage> = pkgs.iter().collect(); + let refs: Vec<&mozart_registry::lockfile::LockedPackage> = pkgs.iter().collect(); let result = find_locked_package(&refs, "psr/log"); assert!(result.is_some()); @@ -463,7 +463,7 @@ mod tests { #[test] fn test_find_locked_package_case_insensitive() { let pkgs = vec![make_locked_package("Monolog/Monolog", "3.8.0")]; - let refs: Vec<&crate::lockfile::LockedPackage> = pkgs.iter().collect(); + let refs: Vec<&mozart_registry::lockfile::LockedPackage> = pkgs.iter().collect(); let result = find_locked_package(&refs, "monolog/monolog"); assert!(result.is_some()); @@ -472,7 +472,7 @@ mod tests { #[test] fn test_find_locked_package_not_found() { let pkgs = vec![make_locked_package("psr/log", "3.0.0")]; - let refs: Vec<&crate::lockfile::LockedPackage> = pkgs.iter().collect(); + let refs: Vec<&mozart_registry::lockfile::LockedPackage> = pkgs.iter().collect(); let result = find_locked_package(&refs, "monolog/monolog"); assert!(result.is_none()); @@ -601,7 +601,7 @@ mod tests { let e1 = make_installed_entry("psr/log", Some("library")); let e2 = make_installed_entry("phpunit/phpunit", Some("library")); - let mut installed = crate::installed::InstalledPackages::new(); + let mut installed = mozart_registry::installed::InstalledPackages::new(); installed.packages.push(e1.clone()); installed.packages.push(e2.clone()); installed.dev_package_names = vec!["phpunit/phpunit".to_string()]; @@ -613,7 +613,7 @@ mod tests { .collect(); // Simulate --no-dev filtering - let candidates: Vec<&crate::installed::InstalledPackageEntry> = installed + let candidates: Vec<&mozart_registry::installed::InstalledPackageEntry> = installed .packages .iter() .filter(|pkg| !dev_package_names.contains(&pkg.name.to_lowercase())) @@ -628,13 +628,13 @@ mod tests { let e1 = make_installed_entry("psr/log", Some("library")); let e2 = make_installed_entry("phpunit/phpunit", Some("library")); - let mut installed = crate::installed::InstalledPackages::new(); + let mut installed = mozart_registry::installed::InstalledPackages::new(); installed.packages.push(e1.clone()); installed.packages.push(e2.clone()); installed.dev_package_names = vec!["phpunit/phpunit".to_string()]; // no_dev = false: include all - let candidates: Vec<&crate::installed::InstalledPackageEntry> = + let candidates: Vec<&mozart_registry::installed::InstalledPackageEntry> = installed.packages.iter().collect(); assert_eq!(candidates.len(), 2); diff --git a/crates/mozart/src/commands/remove.rs b/crates/mozart/src/commands/remove.rs index 6969745..de4b77b 100644 --- a/crates/mozart/src/commands/remove.rs +++ b/crates/mozart/src/commands/remove.rs @@ -1,9 +1,9 @@ -use crate::console; -use crate::lockfile; -use crate::package; -use crate::resolver::{self, PlatformConfig, ResolveRequest}; -use crate::validation; use clap::Args; +use mozart_core::console; +use mozart_core::package; +use mozart_core::validation; +use mozart_registry::lockfile; +use mozart_registry::resolver::{self, PlatformConfig, ResolveRequest}; use std::collections::HashMap; #[derive(Args)] @@ -99,7 +99,7 @@ pub struct RemoveArgs { pub fn execute( args: &RemoveArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { // Step 1: Validate inputs if args.packages.is_empty() && !args.unused { @@ -286,8 +286,8 @@ pub fn execute( // Run resolver let mut resolved = resolver::resolve(&request).map_err(|e| { - crate::exit_code::bail( - crate::exit_code::DEPENDENCY_RESOLUTION_FAILED, + mozart_core::exit_code::bail( + mozart_core::exit_code::DEPENDENCY_RESOLUTION_FAILED, e.to_string(), ) })?; @@ -477,8 +477,8 @@ pub fn execute( #[cfg(test)] mod tests { use super::*; - use crate::lockfile; - use crate::package::RawPackageData; + use mozart_core::package::RawPackageData; + use mozart_registry::lockfile; use std::collections::BTreeMap; // ──────────── Helper constructors ──────────── @@ -684,8 +684,8 @@ mod tests { #[test] #[ignore] fn test_remove_full_e2e() { - use crate::lockfile::{LockFileGenerationRequest, generate_lock_file}; - use crate::resolver::{ResolveRequest, resolve}; + use mozart_registry::lockfile::{LockFileGenerationRequest, generate_lock_file}; + use mozart_registry::resolver::{ResolveRequest, resolve}; use std::collections::HashMap; use tempfile::tempdir; @@ -705,11 +705,11 @@ mod tests { require: vec![("psr/log".to_string(), "^3.0".to_string())], require_dev: vec![], include_dev: false, - minimum_stability: crate::package::Stability::Stable, + minimum_stability: mozart_core::package::Stability::Stable, stability_flags: HashMap::new(), prefer_stable: true, prefer_lowest: false, - platform: crate::resolver::PlatformConfig::new(), + platform: mozart_registry::resolver::PlatformConfig::new(), ignore_platform_reqs: false, ignore_platform_req_list: vec![], repo_cache: None, @@ -736,11 +736,11 @@ mod tests { require: vec![], require_dev: vec![], include_dev: false, - minimum_stability: crate::package::Stability::Stable, + minimum_stability: mozart_core::package::Stability::Stable, stability_flags: HashMap::new(), prefer_stable: true, prefer_lowest: false, - platform: crate::resolver::PlatformConfig::new(), + platform: mozart_registry::resolver::PlatformConfig::new(), ignore_platform_reqs: false, ignore_platform_req_list: vec![], repo_cache: None, diff --git a/crates/mozart/src/commands/repository.rs b/crates/mozart/src/commands/repository.rs index c54601b..0974e29 100644 --- a/crates/mozart/src/commands/repository.rs +++ b/crates/mozart/src/commands/repository.rs @@ -38,7 +38,7 @@ pub struct RepositoryArgs { pub fn execute( _args: &RepositoryArgs, _cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { todo!() } diff --git a/crates/mozart/src/commands/require.rs b/crates/mozart/src/commands/require.rs index 6e76b6e..960182f 100644 --- a/crates/mozart/src/commands/require.rs +++ b/crates/mozart/src/commands/require.rs @@ -1,11 +1,11 @@ -use crate::console; -use crate::lockfile; -use crate::package::{self, Stability}; -use crate::packagist; -use crate::resolver::{self, PlatformConfig, ResolveRequest}; -use crate::validation; -use crate::version; use clap::Args; +use mozart_core::console; +use mozart_core::package::{self, Stability}; +use mozart_core::validation; +use mozart_registry::lockfile; +use mozart_registry::packagist; +use mozart_registry::resolver::{self, PlatformConfig, ResolveRequest}; +use mozart_registry::version; use std::collections::HashMap; use std::io::{BufRead, IsTerminal, Write}; @@ -346,7 +346,7 @@ fn interactive_search_packages( pub fn execute( args: &RequireArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { // Collect the effective list of packages to add. // If none were provided on the CLI, try interactive search (unless --no-interaction). @@ -609,8 +609,8 @@ pub fn execute( let mut resolved = match resolver::resolve(&request) { Ok(packages) => packages, Err(e) => { - return Err(crate::exit_code::bail( - crate::exit_code::DEPENDENCY_RESOLUTION_FAILED, + return Err(mozart_core::exit_code::bail( + mozart_core::exit_code::DEPENDENCY_RESOLUTION_FAILED, e.to_string(), )); } @@ -758,7 +758,7 @@ pub fn execute( .map(|s| s.eq_ignore_ascii_case("source")) .unwrap_or(false); if prefer_source { - console.info(&crate::console::warning( + console.info(&mozart_core::console::warning( "Warning: Source installs are not yet supported. Falling back to dist.", )); } @@ -836,7 +836,7 @@ mod tests { /// Verify that --sort-packages sorts both require and require-dev maps. #[test] fn test_sort_packages_sorts_both_sections() { - use crate::package::RawPackageData; + use mozart_core::package::RawPackageData; let mut raw = RawPackageData::new("test/project".to_string()); raw.require @@ -915,8 +915,8 @@ mod tests { #[test] #[ignore] fn test_require_full_e2e() { - use crate::lockfile::{LockFileGenerationRequest, generate_lock_file}; - use crate::package::RawPackageData; + use mozart_core::package::RawPackageData; + use mozart_registry::lockfile::{LockFileGenerationRequest, generate_lock_file}; let composer_json_content = r#"{"name": "test/project", "require": {"psr/log": "^3.0"}}"#; let composer_json: RawPackageData = serde_json::from_str(composer_json_content).unwrap(); @@ -956,7 +956,7 @@ mod tests { #[test] #[ignore] fn test_require_no_install_writes_lock_only() { - use crate::package::RawPackageData; + use mozart_core::package::RawPackageData; use tempfile::tempdir; let dir = tempdir().unwrap(); diff --git a/crates/mozart/src/commands/run_script.rs b/crates/mozart/src/commands/run_script.rs index 8f2b5cd..acef421 100644 --- a/crates/mozart/src/commands/run_script.rs +++ b/crates/mozart/src/commands/run_script.rs @@ -49,7 +49,7 @@ const INTERNAL_ONLY_EVENTS: &[&str] = &[ pub fn execute( args: &RunScriptArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), diff --git a/crates/mozart/src/commands/search.rs b/crates/mozart/src/commands/search.rs index d172976..98189ff 100644 --- a/crates/mozart/src/commands/search.rs +++ b/crates/mozart/src/commands/search.rs @@ -1,5 +1,5 @@ -use crate::packagist::SearchResult; use clap::Args; +use mozart_registry::packagist::SearchResult; #[derive(Args)] pub struct SearchArgs { @@ -62,11 +62,12 @@ fn passes_only_vendor(result: &SearchResult, query: &str) -> bool { pub fn execute( args: &SearchArgs, _cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let query = args.tokens.join(" "); - let (all_results, total) = crate::packagist::search_packages(&query, args.r#type.as_deref())?; + let (all_results, total) = + mozart_registry::packagist::search_packages(&query, args.r#type.as_deref())?; // Apply client-side filters let mut results: Vec<&SearchResult> = all_results.iter().collect(); @@ -92,7 +93,7 @@ pub fn execute( if results.is_empty() { eprintln!( "{}", - crate::console::warning(&format!("No packages found for \"{query}\"")) + mozart_core::console::warning(&format!("No packages found for \"{query}\"")) ); return Ok(()); } @@ -115,9 +116,13 @@ pub fn execute( println!( "{} {} {}", - crate::console::info(&format!("{:<width$}", result.name, width = name_width)), - crate::console::comment(&dl_str), - crate::console::comment(&fav_str), + mozart_core::console::info(&format!( + "{:<width$}", + result.name, + width = name_width + )), + mozart_core::console::comment(&dl_str), + mozart_core::console::comment(&fav_str), ); if !result.description.is_empty() { println!(" {}", result.description); @@ -163,7 +168,7 @@ mod tests { #[test] fn test_parse_search_response() { - use crate::packagist::SearchResponse; + use mozart_registry::packagist::SearchResponse; let json = r#"{ "results": [ @@ -209,7 +214,7 @@ mod tests { #[test] fn test_parse_search_response_with_next() { - use crate::packagist::SearchResponse; + use mozart_registry::packagist::SearchResponse; let json = r#"{ "results": [], diff --git a/crates/mozart/src/commands/self_update.rs b/crates/mozart/src/commands/self_update.rs index 29c67ef..03d2643 100644 --- a/crates/mozart/src/commands/self_update.rs +++ b/crates/mozart/src/commands/self_update.rs @@ -53,7 +53,7 @@ const BACKUP_EXTENSION: &str = ".old"; pub fn execute( args: &SelfUpdateArgs, _cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let current_exe = std::env::current_exe() .map_err(|e| anyhow::anyhow!("Could not determine current executable path: {e}"))?; @@ -278,7 +278,7 @@ fn update(args: &SelfUpdateArgs, current_exe: &Path, data_dir: &Path) -> anyhow: if args.version.is_none() && target_version == current_version { println!( "{}", - crate::console::info(&format!( + mozart_core::console::info(&format!( "Mozart is already at the latest version ({current_version})" )) ); @@ -329,14 +329,14 @@ fn update(args: &SelfUpdateArgs, current_exe: &Path, data_dir: &Path) -> anyhow: println!( "{}", - crate::console::info(&format!( + mozart_core::console::info(&format!( "Mozart updated successfully from {current_version} to {target_version}" )) ); if args.clean_backups { clean_backups(data_dir)?; - println!("{}", crate::console::comment("Old backups removed.")); + println!("{}", mozart_core::console::comment("Old backups removed.")); } Ok(()) @@ -367,7 +367,7 @@ fn rollback(current_exe: &Path, data_dir: &Path) -> anyhow::Result<()> { println!( "{}", - crate::console::info(&format!( + mozart_core::console::info(&format!( "Rollback successful. Restored from {}", backup.file_name().unwrap_or_default().to_string_lossy() )) diff --git a/crates/mozart/src/commands/show.rs b/crates/mozart/src/commands/show.rs index a8ae995..c6a446d 100644 --- a/crates/mozart/src/commands/show.rs +++ b/crates/mozart/src/commands/show.rs @@ -102,7 +102,7 @@ pub struct ShowArgs { pub fn execute( args: &ShowArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -142,17 +142,17 @@ pub fn execute( fn execute_installed(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { let vendor_dir = working_dir.join("vendor"); - let installed = crate::installed::InstalledPackages::read(&vendor_dir)?; + let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?; if installed.packages.is_empty() { // Warn if composer.json has requirements but nothing is installed let composer_json_path = working_dir.join("composer.json"); if composer_json_path.exists() { - let root = crate::package::read_from_file(&composer_json_path)?; + let root = mozart_core::package::read_from_file(&composer_json_path)?; if !root.require.is_empty() || !root.require_dev.is_empty() { eprintln!( "{}", - crate::console::warning( + mozart_core::console::warning( "No dependencies installed. Try running mozart install or update." ) ); @@ -216,11 +216,11 @@ fn execute_installed(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> } fn filter_installed_packages<'a>( - installed: &'a crate::installed::InstalledPackages, + installed: &'a mozart_registry::installed::InstalledPackages, args: &ShowArgs, working_dir: &Path, -) -> anyhow::Result<Vec<&'a crate::installed::InstalledPackageEntry>> { - let mut packages: Vec<&crate::installed::InstalledPackageEntry> = +) -> anyhow::Result<Vec<&'a mozart_registry::installed::InstalledPackageEntry>> { + let mut packages: Vec<&mozart_registry::installed::InstalledPackageEntry> = installed.packages.iter().collect(); // --no-dev: exclude dev packages @@ -237,7 +237,7 @@ fn filter_installed_packages<'a>( if args.direct { let composer_json_path = working_dir.join("composer.json"); if composer_json_path.exists() { - let root = crate::package::read_from_file(&composer_json_path)?; + let root = mozart_core::package::read_from_file(&composer_json_path)?; let mut direct_names: HashSet<String> = root.require.keys().map(|k| k.to_lowercase()).collect(); if !args.no_dev { @@ -254,7 +254,7 @@ fn filter_installed_packages<'a>( } fn show_installed_package_list( - packages: &[&crate::installed::InstalledPackageEntry], + packages: &[&mozart_registry::installed::InstalledPackageEntry], args: &ShowArgs, _vendor_dir: &Path, ) -> anyhow::Result<()> { @@ -297,7 +297,7 @@ fn show_installed_package_list( // --outdated: skip packages that are up-to-date if args.outdated { if let Some(ref li) = latest_info { - use crate::version::compare_normalized_versions; + use mozart_registry::version::compare_normalized_versions; use std::cmp::Ordering; if compare_normalized_versions(&li.version_normalized, &version_normalized) != Ordering::Greater @@ -362,20 +362,24 @@ fn show_installed_package_list( .map(|li| classify_update_category(&entry.version_normalized, &li.version_normalized)); let name_str = match category { - Some(ListUpdateKind::Compatible) => { - crate::console::highlight(&format!("{:<width$}", entry.name, width = name_width)) - .to_string() - } - Some(ListUpdateKind::Incompatible) => { - crate::console::comment(&format!("{:<width$}", entry.name, width = name_width)) - .to_string() - } - _ => crate::console::info(&format!("{:<width$}", entry.name, width = name_width)) + Some(ListUpdateKind::Compatible) => mozart_core::console::highlight(&format!( + "{:<width$}", + entry.name, + width = name_width + )) + .to_string(), + Some(ListUpdateKind::Incompatible) => mozart_core::console::comment(&format!( + "{:<width$}", + entry.name, + width = name_width + )) + .to_string(), + _ => mozart_core::console::info(&format!("{:<width$}", entry.name, width = name_width)) .to_string(), }; let version_str = - crate::console::comment(&format!("{:<width$}", version, width = version_width)) + mozart_core::console::comment(&format!("{:<width$}", version, width = version_width)) .to_string(); if show_latest { @@ -383,20 +387,20 @@ fn show_installed_package_list( Some(li) => { let lv = format_version(&li.version); match category { - Some(ListUpdateKind::Compatible) => crate::console::highlight(&format!( - "{:<width$}", - lv, - width = latest_width - )) + Some(ListUpdateKind::Compatible) => mozart_core::console::highlight( + &format!("{:<width$}", lv, width = latest_width), + ) .to_string(), - Some(ListUpdateKind::Incompatible) => crate::console::comment(&format!( + Some(ListUpdateKind::Incompatible) => mozart_core::console::comment( + &format!("{:<width$}", lv, width = latest_width), + ) + .to_string(), + _ => mozart_core::console::info(&format!( "{:<width$}", lv, width = latest_width )) .to_string(), - _ => crate::console::info(&format!("{:<width$}", lv, width = latest_width)) - .to_string(), } } None => format!("{:<width$}", "", width = latest_width), @@ -439,7 +443,7 @@ enum ListUpdateKind { } fn classify_update_category(current_normalized: &str, latest_normalized: &str) -> ListUpdateKind { - use crate::version::compare_normalized_versions; + use mozart_registry::version::compare_normalized_versions; use std::cmp::Ordering; if compare_normalized_versions(latest_normalized, current_normalized) != Ordering::Greater { @@ -469,10 +473,10 @@ fn extract_major(version_normalized: &str) -> u64 { } fn fetch_latest_for_package(name: &str) -> anyhow::Result<LatestInfo> { - use crate::package::Stability; - use crate::version::find_best_candidate; + use mozart_core::package::Stability; + use mozart_registry::version::find_best_candidate; - let versions = crate::packagist::fetch_package_versions(name, None)?; + let versions = mozart_registry::packagist::fetch_package_versions(name, None)?; let best = find_best_candidate(&versions, Stability::Stable) .ok_or_else(|| anyhow::anyhow!("No stable version found for {name}"))?; @@ -513,7 +517,7 @@ fn render_installed_json(entries: &[InstalledListEntry]) -> anyhow::Result<()> { } fn show_installed_package_detail( - installed: &crate::installed::InstalledPackages, + installed: &mozart_registry::installed::InstalledPackages, package_name: &str, working_dir: &Path, ) -> anyhow::Result<()> { @@ -535,36 +539,36 @@ fn show_installed_package_detail( let vendor_dir = working_dir.join("vendor"); - println!("{} : {}", crate::console::info("name"), pkg.name); + println!("{} : {}", mozart_core::console::info("name"), pkg.name); println!( "{} : {}", - crate::console::info("descrip."), + mozart_core::console::info("descrip."), get_installed_description(pkg) ); println!( "{} : {}", - crate::console::info("keywords"), + mozart_core::console::info("keywords"), get_installed_keywords(pkg) ); println!( "{} : {}", - crate::console::info("versions"), + mozart_core::console::info("versions"), format_version_highlight(&pkg.version) ); println!( "{} : {}", - crate::console::info("type"), + mozart_core::console::info("type"), pkg.package_type.as_deref().unwrap_or("library") ); // License if let Some(licenses) = get_installed_license(pkg) { - println!("{} : {}", crate::console::info("license"), licenses); + println!("{} : {}", mozart_core::console::info("license"), licenses); } // Homepage if let Some(homepage) = get_installed_homepage(pkg) { - println!("{} : {}", crate::console::info("homepage"), homepage); + println!("{} : {}", mozart_core::console::info("homepage"), homepage); } // Source @@ -577,9 +581,9 @@ fn show_installed_package_detail( .unwrap_or(""); println!( "{} : [{}] {} {}", - crate::console::info("source"), + mozart_core::console::info("source"), source_type, - crate::console::comment(source_url), + mozart_core::console::comment(source_url), source_ref ); } @@ -591,9 +595,9 @@ fn show_installed_package_detail( let dist_ref = dist.get("reference").and_then(|v| v.as_str()).unwrap_or(""); println!( "{} : [{}] {} {}", - crate::console::info("dist"), + mozart_core::console::info("dist"), dist_type, - crate::console::comment(dist_url), + mozart_core::console::comment(dist_url), dist_ref ); } @@ -603,7 +607,7 @@ fn show_installed_package_detail( if install_path.exists() { println!( "{} : {}", - crate::console::info("path"), + mozart_core::console::info("path"), install_path.display() ); } @@ -613,10 +617,10 @@ fn show_installed_package_detail( && !requires.is_empty() { println!(); - println!("{}", crate::console::info("requires")); + println!("{}", mozart_core::console::info("requires")); for (name, constraint) in requires { let c = constraint.as_str().unwrap_or(""); - println!("{} {}", name, crate::console::comment(c)); + println!("{} {}", name, mozart_core::console::comment(c)); } } @@ -628,10 +632,10 @@ fn show_installed_package_detail( && !requires_dev.is_empty() { println!(); - println!("{}", crate::console::info("requires (dev)")); + println!("{}", mozart_core::console::info("requires (dev)")); for (name, constraint) in requires_dev { let c = constraint.as_str().unwrap_or(""); - println!("{} {}", name, crate::console::comment(c)); + println!("{} {}", name, mozart_core::console::comment(c)); } } @@ -648,10 +652,11 @@ fn execute_locked(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { ); } - let lock = crate::lockfile::LockFile::read_from_file(&lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; // Combine packages and packages-dev - let mut packages: Vec<&crate::lockfile::LockedPackage> = lock.packages.iter().collect(); + let mut packages: Vec<&mozart_registry::lockfile::LockedPackage> = + lock.packages.iter().collect(); if let Some(ref pkgs_dev) = lock.packages_dev && !args.no_dev @@ -663,7 +668,7 @@ fn execute_locked(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { if args.direct { let composer_json_path = working_dir.join("composer.json"); if composer_json_path.exists() { - let root = crate::package::read_from_file(&composer_json_path)?; + let root = mozart_core::package::read_from_file(&composer_json_path)?; let mut direct_names: HashSet<String> = root.require.keys().map(|k| k.to_lowercase()).collect(); if !args.no_dev { @@ -691,7 +696,7 @@ fn execute_locked(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { } fn show_locked_package_list( - packages: &[&crate::lockfile::LockedPackage], + packages: &[&mozart_registry::lockfile::LockedPackage], args: &ShowArgs, ) -> anyhow::Result<()> { let show_latest = args.latest || args.outdated; @@ -732,7 +737,7 @@ fn show_locked_package_list( // --outdated: skip packages that are up-to-date if args.outdated { if let Some(ref li) = latest_info { - use crate::version::compare_normalized_versions; + use mozart_registry::version::compare_normalized_versions; use std::cmp::Ordering; if compare_normalized_versions(&li.version_normalized, &version_normalized) != Ordering::Greater @@ -795,20 +800,24 @@ fn show_locked_package_list( .map(|li| classify_update_category(&entry.version_normalized, &li.version_normalized)); let name_str = match category { - Some(ListUpdateKind::Compatible) => { - crate::console::highlight(&format!("{:<width$}", entry.name, width = name_width)) - .to_string() - } - Some(ListUpdateKind::Incompatible) => { - crate::console::comment(&format!("{:<width$}", entry.name, width = name_width)) - .to_string() - } - _ => crate::console::info(&format!("{:<width$}", entry.name, width = name_width)) + Some(ListUpdateKind::Compatible) => mozart_core::console::highlight(&format!( + "{:<width$}", + entry.name, + width = name_width + )) + .to_string(), + Some(ListUpdateKind::Incompatible) => mozart_core::console::comment(&format!( + "{:<width$}", + entry.name, + width = name_width + )) + .to_string(), + _ => mozart_core::console::info(&format!("{:<width$}", entry.name, width = name_width)) .to_string(), }; let version_str = - crate::console::comment(&format!("{:<width$}", version, width = version_width)) + mozart_core::console::comment(&format!("{:<width$}", version, width = version_width)) .to_string(); if show_latest { @@ -816,20 +825,20 @@ fn show_locked_package_list( Some(li) => { let lv = format_version(&li.version); match category { - Some(ListUpdateKind::Compatible) => crate::console::highlight(&format!( - "{:<width$}", - lv, - width = latest_width - )) + Some(ListUpdateKind::Compatible) => mozart_core::console::highlight( + &format!("{:<width$}", lv, width = latest_width), + ) + .to_string(), + Some(ListUpdateKind::Incompatible) => mozart_core::console::comment( + &format!("{:<width$}", lv, width = latest_width), + ) .to_string(), - Some(ListUpdateKind::Incompatible) => crate::console::comment(&format!( + _ => mozart_core::console::info(&format!( "{:<width$}", lv, width = latest_width )) .to_string(), - _ => crate::console::info(&format!("{:<width$}", lv, width = latest_width)) - .to_string(), } } None => format!("{:<width$}", "", width = latest_width), @@ -889,7 +898,7 @@ fn render_locked_json(entries: &[LockedListEntry]) -> anyhow::Result<()> { } fn show_locked_package_detail( - lock: &crate::lockfile::LockFile, + lock: &mozart_registry::lockfile::LockFile, package_name: &str, ) -> anyhow::Result<()> { // Search in both packages and packages-dev @@ -906,10 +915,10 @@ fn show_locked_package_detail( } }; - println!("{} : {}", crate::console::info("name"), pkg.name); + println!("{} : {}", mozart_core::console::info("name"), pkg.name); println!( "{} : {}", - crate::console::info("descrip."), + mozart_core::console::info("descrip."), pkg.description.as_deref().unwrap_or("") ); @@ -919,16 +928,16 @@ fn show_locked_package_detail( .as_ref() .map(|kw| kw.join(", ")) .unwrap_or_default(); - println!("{} : {}", crate::console::info("keywords"), keywords); + println!("{} : {}", mozart_core::console::info("keywords"), keywords); println!( "{} : * {}", - crate::console::info("versions"), + mozart_core::console::info("versions"), format_version(&pkg.version) ); println!( "{} : {}", - crate::console::info("type"), + mozart_core::console::info("type"), pkg.package_type.as_deref().unwrap_or("library") ); @@ -936,23 +945,23 @@ fn show_locked_package_detail( if let Some(ref licenses) = pkg.license { println!( "{} : {}", - crate::console::info("license"), + mozart_core::console::info("license"), licenses.join(", ") ); } // Homepage if let Some(ref homepage) = pkg.homepage { - println!("{} : {}", crate::console::info("homepage"), homepage); + println!("{} : {}", mozart_core::console::info("homepage"), homepage); } // Source if let Some(ref source) = pkg.source { println!( "{} : [{}] {} {}", - crate::console::info("source"), + mozart_core::console::info("source"), source.source_type, - crate::console::comment(&source.url), + mozart_core::console::comment(&source.url), source.reference.as_deref().unwrap_or("") ); } @@ -961,9 +970,9 @@ fn show_locked_package_detail( if let Some(ref dist) = pkg.dist { println!( "{} : [{}] {} {}", - crate::console::info("dist"), + mozart_core::console::info("dist"), dist.dist_type, - crate::console::comment(&dist.url), + mozart_core::console::comment(&dist.url), dist.reference.as_deref().unwrap_or("") ); } @@ -971,18 +980,18 @@ fn show_locked_package_detail( // Requires if !pkg.require.is_empty() { println!(); - println!("{}", crate::console::info("requires")); + println!("{}", mozart_core::console::info("requires")); for (name, constraint) in &pkg.require { - println!("{} {}", name, crate::console::comment(constraint)); + println!("{} {}", name, mozart_core::console::comment(constraint)); } } // Requires (dev) if !pkg.require_dev.is_empty() { println!(); - println!("{}", crate::console::info("requires (dev)")); + println!("{}", mozart_core::console::info("requires (dev)")); for (name, constraint) in &pkg.require_dev { - println!("{} {}", name, crate::console::comment(constraint)); + println!("{} {}", name, mozart_core::console::comment(constraint)); } } @@ -991,9 +1000,9 @@ fn show_locked_package_detail( && !suggests.is_empty() { println!(); - println!("{}", crate::console::info("suggests")); + println!("{}", mozart_core::console::info("suggests")); for (name, reason) in suggests { - println!("{} {}", name, crate::console::comment(reason)); + println!("{} {}", name, mozart_core::console::comment(reason)); } } @@ -1007,46 +1016,46 @@ fn show_self(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { if !composer_json_path.exists() { anyhow::bail!("No composer.json found in {}", working_dir.display()); } - let root = crate::package::read_from_file(&composer_json_path)?; + let root = mozart_core::package::read_from_file(&composer_json_path)?; if args.name_only { println!("{}", root.name); return Ok(()); } - println!("{} : {}", crate::console::info("name"), root.name); + println!("{} : {}", mozart_core::console::info("name"), root.name); println!( "{} : {}", - crate::console::info("descrip."), + mozart_core::console::info("descrip."), root.description.as_deref().unwrap_or("") ); println!( "{} : {}", - crate::console::info("type"), + mozart_core::console::info("type"), root.package_type.as_deref().unwrap_or("project") ); if let Some(ref license) = root.license { - println!("{} : {}", crate::console::info("license"), license); + println!("{} : {}", mozart_core::console::info("license"), license); } if let Some(ref homepage) = root.homepage { - println!("{} : {}", crate::console::info("homepage"), homepage); + println!("{} : {}", mozart_core::console::info("homepage"), homepage); } // Requires if !root.require.is_empty() { println!(); - println!("{}", crate::console::info("requires")); + println!("{}", mozart_core::console::info("requires")); for (name, constraint) in &root.require { - println!("{} {}", name, crate::console::comment(constraint)); + println!("{} {}", name, mozart_core::console::comment(constraint)); } } // Requires (dev) if !root.require_dev.is_empty() { println!(); - println!("{}", crate::console::info("requires (dev)")); + println!("{}", mozart_core::console::info("requires (dev)")); for (name, constraint) in &root.require_dev { - println!("{} {}", name, crate::console::comment(constraint)); + println!("{} {}", name, mozart_core::console::comment(constraint)); } } @@ -1063,13 +1072,13 @@ fn show_tree(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { anyhow::bail!("No composer.json found in {}", working_dir.display()); } - let root = crate::package::read_from_file(&composer_json_path)?; + let root = mozart_core::package::read_from_file(&composer_json_path)?; // Load all locked packages into a map for quick lookup - let pkg_map: HashMap<String, &crate::lockfile::LockedPackage>; + let pkg_map: HashMap<String, &mozart_registry::lockfile::LockedPackage>; let lock_storage; if lock_path.exists() { - lock_storage = crate::lockfile::LockFile::read_from_file(&lock_path)?; + lock_storage = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; pkg_map = lock_storage .packages .iter() @@ -1101,8 +1110,8 @@ fn show_tree(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { // Print root println!( "{} {}", - crate::console::info(&root.name), - crate::console::comment(root.description.as_deref().unwrap_or("")) + mozart_core::console::info(&root.name), + mozart_core::console::comment(root.description.as_deref().unwrap_or("")) ); // Render each root dependency as a tree @@ -1130,7 +1139,7 @@ fn show_tree(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { fn print_tree_node( pkg_name: &str, constraint: &str, - pkg_map: &HashMap<String, &crate::lockfile::LockedPackage>, + pkg_map: &HashMap<String, &mozart_registry::lockfile::LockedPackage>, prefix: &str, child_prefix: &str, visited: &mut HashSet<String>, @@ -1148,8 +1157,8 @@ fn print_tree_node( println!( "{} {} {} {}", prefix, - crate::console::info(pkg_name), - crate::console::comment(&version), + mozart_core::console::info(pkg_name), + mozart_core::console::comment(&version), description ); @@ -1206,7 +1215,7 @@ fn print_tree_node( println!( "{} {} {} (not installed)", prefix, - crate::console::comment(pkg_name), + mozart_core::console::comment(pkg_name), constraint ); } @@ -1233,12 +1242,12 @@ fn show_platform(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { let mut platform_packages: Vec<(String, String, String)> = Vec::new(); // (name, version, source) // Try to detect PHP from the system - let php_version = crate::platform::detect_php_version(); + let php_version = mozart_core::platform::detect_php_version(); // Load platform requirements from lock file if available let lock_path = working_dir.join("composer.lock"); if lock_path.exists() { - let lock = crate::lockfile::LockFile::read_from_file(&lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; // Collect platform entries from lock's platform field if let Some(obj) = lock.platform.as_object() { @@ -1268,7 +1277,7 @@ fn show_platform(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { } // Detect PHP extensions if PHP is available - let extensions = crate::platform::detect_php_extensions(); + let extensions = mozart_core::platform::detect_php_extensions(); for ext in &extensions { let ext_name = format!("ext-{ext}"); if !platform_packages.iter().any(|(n, _, _)| *n == ext_name) { @@ -1327,8 +1336,8 @@ fn show_platform(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { for (name, version, _source) in &platform_packages { println!( "{} {}", - crate::console::info(&format!("{:<width$}", name, width = name_width)), - crate::console::comment(&format!("{:<width$}", version, width = version_width)), + mozart_core::console::info(&format!("{:<width$}", name, width = name_width)), + mozart_core::console::comment(&format!("{:<width$}", version, width = version_width)), ); } @@ -1346,7 +1355,7 @@ fn show_available(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { // Otherwise, show all installed packages with their available (latest) versions // by querying Packagist for each installed package let vendor_dir = working_dir.join("vendor"); - let installed = crate::installed::InstalledPackages::read(&vendor_dir); + let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir); let installed = match installed { Ok(i) if !i.packages.is_empty() => i, @@ -1354,16 +1363,16 @@ fn show_available(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { // Try lock file let lock_path = working_dir.join("composer.lock"); if lock_path.exists() { - let lock = crate::lockfile::LockFile::read_from_file(&lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; println!( "{}", - crate::console::info( + mozart_core::console::info( "Available versions for locked packages (from Packagist):" ) ); println!(); - let mut all_packages: Vec<&crate::lockfile::LockedPackage> = + let mut all_packages: Vec<&mozart_registry::lockfile::LockedPackage> = lock.packages.iter().collect(); if !args.no_dev && let Some(ref dev_pkgs) = lock.packages_dev @@ -1382,7 +1391,7 @@ fn show_available(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { eprintln!( "{}", - crate::console::warning( + mozart_core::console::warning( "No dependencies installed. Try running mozart install or update." ) ); @@ -1392,7 +1401,7 @@ fn show_available(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { println!( "{}", - crate::console::info("Available versions for installed packages (from Packagist):") + mozart_core::console::info("Available versions for installed packages (from Packagist):") ); println!(); @@ -1404,7 +1413,7 @@ fn show_available(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { if is_platform_package(&pkg.name) { continue; } - match crate::packagist::fetch_package_versions(&pkg.name, None) { + match mozart_registry::packagist::fetch_package_versions(&pkg.name, None) { Ok(versions) => { let version_strings: Vec<String> = versions.iter().map(|v| v.version.clone()).collect(); @@ -1439,7 +1448,7 @@ fn show_available(args: &ShowArgs, working_dir: &Path) -> anyhow::Result<()> { } fn show_available_versions(pkg_name: &str, args: &ShowArgs) -> anyhow::Result<()> { - let versions = crate::packagist::fetch_package_versions(pkg_name, None)?; + let versions = mozart_registry::packagist::fetch_package_versions(pkg_name, None)?; if versions.is_empty() { println!("No versions found for {pkg_name}"); return Ok(()); @@ -1458,19 +1467,22 @@ fn show_available_versions(pkg_name: &str, args: &ShowArgs) -> anyhow::Result<() println!( "{}", - crate::console::info(&format!("Available versions for {pkg_name}:")) + mozart_core::console::info(&format!("Available versions for {pkg_name}:")) ); for v in &versions { - println!(" {}", crate::console::comment(&v.version)); + println!(" {}", mozart_core::console::comment(&v.version)); } Ok(()) } fn show_available_versions_inline(pkg_name: &str) { - match crate::packagist::fetch_package_versions(pkg_name, None) { + match mozart_registry::packagist::fetch_package_versions(pkg_name, None) { Ok(versions) => { if versions.is_empty() { - println!("{}: no versions found", crate::console::info(pkg_name)); + println!( + "{}: no versions found", + mozart_core::console::info(pkg_name) + ); return; } // Show up to 5 most recent versions @@ -1486,15 +1498,15 @@ fn show_available_versions_inline(pkg_name: &str) { }; println!( "{}: {}{}", - crate::console::info(pkg_name), - crate::console::comment(&shown.join(", ")), + mozart_core::console::info(pkg_name), + mozart_core::console::comment(&shown.join(", ")), rest ); } Err(_) => { println!( "{}: (could not fetch from Packagist)", - crate::console::comment(pkg_name) + mozart_core::console::comment(pkg_name) ); } } @@ -1513,7 +1525,7 @@ fn format_version_highlight(version: &str) -> String { } /// Extract description from an InstalledPackageEntry's extra_fields. -fn get_installed_description(pkg: &crate::installed::InstalledPackageEntry) -> String { +fn get_installed_description(pkg: &mozart_registry::installed::InstalledPackageEntry) -> String { pkg.extra_fields .get("description") .and_then(|v| v.as_str()) @@ -1522,7 +1534,7 @@ fn get_installed_description(pkg: &crate::installed::InstalledPackageEntry) -> S } /// Extract keywords from an InstalledPackageEntry's extra_fields. -fn get_installed_keywords(pkg: &crate::installed::InstalledPackageEntry) -> String { +fn get_installed_keywords(pkg: &mozart_registry::installed::InstalledPackageEntry) -> String { pkg.extra_fields .get("keywords") .and_then(|v| v.as_array()) @@ -1536,7 +1548,9 @@ fn get_installed_keywords(pkg: &crate::installed::InstalledPackageEntry) -> Stri } /// Extract license from an InstalledPackageEntry's extra_fields. -fn get_installed_license(pkg: &crate::installed::InstalledPackageEntry) -> Option<String> { +fn get_installed_license( + pkg: &mozart_registry::installed::InstalledPackageEntry, +) -> Option<String> { pkg.extra_fields.get("license").and_then(|v| { v.as_array().map(|arr| { arr.iter() @@ -1548,7 +1562,9 @@ fn get_installed_license(pkg: &crate::installed::InstalledPackageEntry) -> Optio } /// Extract homepage from an InstalledPackageEntry's extra_fields. -fn get_installed_homepage(pkg: &crate::installed::InstalledPackageEntry) -> Option<String> { +fn get_installed_homepage( + pkg: &mozart_registry::installed::InstalledPackageEntry, +) -> Option<String> { pkg.extra_fields .get("homepage") .and_then(|v| v.as_str()) @@ -1711,7 +1727,7 @@ mod tests { "description".to_string(), serde_json::Value::String("A logging library".to_string()), ); - let pkg = crate::installed::InstalledPackageEntry { + let pkg = mozart_registry::installed::InstalledPackageEntry { name: "monolog/monolog".to_string(), version: "3.0.0".to_string(), version_normalized: None, @@ -1729,7 +1745,7 @@ mod tests { #[test] fn test_get_installed_description_absent() { use std::collections::BTreeMap; - let pkg = crate::installed::InstalledPackageEntry { + let pkg = mozart_registry::installed::InstalledPackageEntry { name: "psr/log".to_string(), version: "3.0.0".to_string(), version_normalized: None, @@ -1754,7 +1770,7 @@ mod tests { "keywords".to_string(), serde_json::json!(["log", "psr3", "logging"]), ); - let pkg = crate::installed::InstalledPackageEntry { + let pkg = mozart_registry::installed::InstalledPackageEntry { name: "psr/log".to_string(), version: "3.0.0".to_string(), version_normalized: None, diff --git a/crates/mozart/src/commands/status.rs b/crates/mozart/src/commands/status.rs index dc26a5f..ad6dac1 100644 --- a/crates/mozart/src/commands/status.rs +++ b/crates/mozart/src/commands/status.rs @@ -47,7 +47,7 @@ struct PackageStatus { pub fn execute( args: &StatusArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -55,15 +55,15 @@ pub fn execute( }; let vendor_dir = working_dir.join("vendor"); - let installed = crate::installed::InstalledPackages::read(&vendor_dir)?; + let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?; if installed.packages.is_empty() { println!("No packages installed."); return Ok(()); } - let cache_config = crate::cache::build_cache_config(cli); - let files_cache = crate::cache::Cache::files(&cache_config); + let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache); + let files_cache = mozart_registry::cache::Cache::files(&cache_config); let show_files = args.verbose || cli.verbose > 0; @@ -99,7 +99,7 @@ pub fn execute( // Download original archive to a temp dir let tmp_dir = make_temp_dir(&pkg.name)?; - let downloaded = crate::downloader::download_dist( + let downloaded = mozart_registry::downloader::download_dist( &dist.url, dist.shasum.as_deref(), None, @@ -117,8 +117,10 @@ pub fn execute( // Extract archive to temp dir let extract_result = match dist.dist_type.as_str() { - "zip" => crate::downloader::extract_zip(&bytes, &tmp_dir), - "tar" | "tar.gz" | "tgz" => crate::downloader::extract_tar_gz(&bytes, &tmp_dir), + "zip" => mozart_registry::downloader::extract_zip(&bytes, &tmp_dir), + "tar" | "tar.gz" | "tgz" => { + mozart_registry::downloader::extract_tar_gz(&bytes, &tmp_dir) + } other => { eprintln!( " Warning: unsupported dist type '{}' for {}", @@ -184,7 +186,7 @@ pub fn execute( // ─── Helpers ────────────────────────────────────────────────────────────────── /// Extract dist info from an installed package entry. -fn extract_dist_info(pkg: &crate::installed::InstalledPackageEntry) -> Option<DistInfo> { +fn extract_dist_info(pkg: &mozart_registry::installed::InstalledPackageEntry) -> Option<DistInfo> { // Try the strongly-typed `dist` field first let dist_val = pkg.dist.as_ref().or_else(|| pkg.extra_fields.get("dist"))?; @@ -213,7 +215,7 @@ fn extract_dist_info(pkg: &crate::installed::InstalledPackageEntry) -> Option<Di /// since it is a path relative to `vendor/composer/`. Falls back to /// `vendor/<package-name>`. fn resolve_install_path( - pkg: &crate::installed::InstalledPackageEntry, + pkg: &mozart_registry::installed::InstalledPackageEntry, vendor_dir: &Path, ) -> PathBuf { if let Some(ref rel) = pkg.install_path { @@ -484,7 +486,7 @@ mod tests { fn test_extract_dist_info_from_dist_field() { use std::collections::BTreeMap; - let pkg = crate::installed::InstalledPackageEntry { + let pkg = mozart_registry::installed::InstalledPackageEntry { name: "vendor/pkg".to_string(), version: "1.0.0".to_string(), version_normalized: None, @@ -512,7 +514,7 @@ mod tests { fn test_extract_dist_info_no_url() { use std::collections::BTreeMap; - let pkg = crate::installed::InstalledPackageEntry { + let pkg = mozart_registry::installed::InstalledPackageEntry { name: "vendor/pkg".to_string(), version: "1.0.0".to_string(), version_normalized: None, @@ -536,7 +538,7 @@ mod tests { fn test_extract_dist_info_absent() { use std::collections::BTreeMap; - let pkg = crate::installed::InstalledPackageEntry { + let pkg = mozart_registry::installed::InstalledPackageEntry { name: "vendor/pkg".to_string(), version: "1.0.0".to_string(), version_normalized: None, @@ -558,7 +560,7 @@ mod tests { fn test_resolve_install_path_default() { use std::collections::BTreeMap; - let pkg = crate::installed::InstalledPackageEntry { + let pkg = mozart_registry::installed::InstalledPackageEntry { name: "monolog/monolog".to_string(), version: "3.0.0".to_string(), version_normalized: None, @@ -580,7 +582,7 @@ mod tests { fn test_resolve_install_path_with_install_path() { use std::collections::BTreeMap; - let pkg = crate::installed::InstalledPackageEntry { + let pkg = mozart_registry::installed::InstalledPackageEntry { name: "monolog/monolog".to_string(), version: "3.0.0".to_string(), version_normalized: None, diff --git a/crates/mozart/src/commands/suggests.rs b/crates/mozart/src/commands/suggests.rs index df58e47..d528171 100644 --- a/crates/mozart/src/commands/suggests.rs +++ b/crates/mozart/src/commands/suggests.rs @@ -41,7 +41,7 @@ struct Suggestion { pub fn execute( args: &SuggestsArgs, cli: &super::Cli, - _console: &crate::console::Console, + _console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -160,9 +160,10 @@ fn collect_suggestions_from_locked( no_dev: bool, ) -> anyhow::Result<Vec<Suggestion>> { let lock_path = working_dir.join("composer.lock"); - let lock = crate::lockfile::LockFile::read_from_file(&lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; - let mut all_packages: Vec<&crate::lockfile::LockedPackage> = lock.packages.iter().collect(); + let mut all_packages: Vec<&mozart_registry::lockfile::LockedPackage> = + lock.packages.iter().collect(); if !no_dev && let Some(ref pkgs_dev) = lock.packages_dev { all_packages.extend(pkgs_dev.iter()); } @@ -187,7 +188,7 @@ fn collect_suggestions_from_installed( no_dev: bool, ) -> anyhow::Result<Vec<Suggestion>> { let vendor_dir = working_dir.join("vendor"); - let installed = crate::installed::InstalledPackages::read(&vendor_dir)?; + let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?; if installed.packages.is_empty() { let installed_json = vendor_dir.join("composer/installed.json"); @@ -233,7 +234,7 @@ fn collect_suggestions_from_root(working_dir: &Path) -> anyhow::Result<Vec<Sugge return Ok(vec![]); } - let root = crate::package::read_from_file(&composer_json_path)?; + let root = mozart_core::package::read_from_file(&composer_json_path)?; // suggest is in extra_fields since RawPackageData doesn't model it explicitly let suggest_val = root.extra_fields.get("suggest"); @@ -264,11 +265,12 @@ fn collect_installed_names_from_lock( no_dev: bool, ) -> anyhow::Result<HashSet<String>> { let lock_path = working_dir.join("composer.lock"); - let lock = crate::lockfile::LockFile::read_from_file(&lock_path)?; + let lock = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)?; let mut names: HashSet<String> = HashSet::new(); - let mut all_packages: Vec<&crate::lockfile::LockedPackage> = lock.packages.iter().collect(); + let mut all_packages: Vec<&mozart_registry::lockfile::LockedPackage> = + lock.packages.iter().collect(); if !no_dev && let Some(ref pkgs_dev) = lock.packages_dev { all_packages.extend(pkgs_dev.iter()); } @@ -299,7 +301,7 @@ fn collect_installed_names_from_installed( no_dev: bool, ) -> anyhow::Result<HashSet<String>> { let vendor_dir = working_dir.join("vendor"); - let installed = crate::installed::InstalledPackages::read(&vendor_dir)?; + let installed = mozart_registry::installed::InstalledPackages::read(&vendor_dir)?; let dev_names: HashSet<String> = installed .dev_package_names @@ -330,7 +332,7 @@ fn collect_installed_names_from_installed( // Add platform packages from require/require-dev in composer.json let composer_json_path = working_dir.join("composer.json"); if composer_json_path.exists() - && let Ok(root) = crate::package::read_from_file(&composer_json_path) + && let Ok(root) = mozart_core::package::read_from_file(&composer_json_path) { for name in root.require.keys().chain(root.require_dev.keys()) { if is_platform_package(name) { @@ -342,7 +344,10 @@ fn collect_installed_names_from_installed( Ok(names) } -fn add_platform_names_from_lock(lock: &crate::lockfile::LockFile, names: &mut HashSet<String>) { +fn add_platform_names_from_lock( + lock: &mozart_registry::lockfile::LockFile, + names: &mut HashSet<String>, +) { // Collect platform keys from the lock's platform and platform_dev objects if let Some(obj) = lock.platform.as_object() { for key in obj.keys() { @@ -372,7 +377,7 @@ fn compute_direct_deps(working_dir: &Path) -> anyhow::Result<HashSet<String>> { if !composer_json_path.exists() { return Ok(HashSet::new()); } - let root = crate::package::read_from_file(&composer_json_path)?; + let root = mozart_core::package::read_from_file(&composer_json_path)?; let mut deps: HashSet<String> = HashSet::new(); for name in root.require.keys().chain(root.require_dev.keys()) { deps.insert(name.to_lowercase()); @@ -447,8 +452,8 @@ mod tests { fn make_locked_package( name: &str, suggest: Option<BTreeMap<String, String>>, - ) -> crate::lockfile::LockedPackage { - crate::lockfile::LockedPackage { + ) -> mozart_registry::lockfile::LockedPackage { + mozart_registry::lockfile::LockedPackage { name: name.to_string(), version: "1.0.0".to_string(), version_normalized: None, @@ -476,7 +481,7 @@ mod tests { fn make_installed_entry( name: &str, suggest: Option<BTreeMap<String, String>>, - ) -> crate::installed::InstalledPackageEntry { + ) -> mozart_registry::installed::InstalledPackageEntry { let mut extra_fields: BTreeMap<String, serde_json::Value> = BTreeMap::new(); if let Some(s) = suggest { let map: serde_json::Map<String, serde_json::Value> = s @@ -485,7 +490,7 @@ mod tests { .collect(); extra_fields.insert("suggest".to_string(), serde_json::Value::Object(map)); } - crate::installed::InstalledPackageEntry { + mozart_registry::installed::InstalledPackageEntry { name: name.to_string(), version: "1.0.0".to_string(), version_normalized: None, @@ -500,11 +505,11 @@ mod tests { } fn minimal_lock( - packages: Vec<crate::lockfile::LockedPackage>, - packages_dev: Option<Vec<crate::lockfile::LockedPackage>>, - ) -> crate::lockfile::LockFile { - crate::lockfile::LockFile { - readme: crate::lockfile::LockFile::default_readme(), + packages: Vec<mozart_registry::lockfile::LockedPackage>, + packages_dev: Option<Vec<mozart_registry::lockfile::LockedPackage>>, + ) -> mozart_registry::lockfile::LockFile { + mozart_registry::lockfile::LockFile { + readme: mozart_registry::lockfile::LockFile::default_readme(), content_hash: "abc123".to_string(), packages, packages_dev, @@ -687,7 +692,7 @@ mod tests { let mut suggest = BTreeMap::new(); suggest.insert("ext-redis".to_string(), "For Redis caching".to_string()); - let mut installed = crate::installed::InstalledPackages::new(); + let mut installed = mozart_registry::installed::InstalledPackages::new(); installed.upsert(make_installed_entry("vendor/cache", Some(suggest))); installed.upsert(make_installed_entry("vendor/other", None)); installed.write(&vendor_dir).unwrap(); diff --git a/crates/mozart/src/commands/update.rs b/crates/mozart/src/commands/update.rs index d4056e4..3a7c423 100644 --- a/crates/mozart/src/commands/update.rs +++ b/crates/mozart/src/commands/update.rs @@ -1,8 +1,8 @@ -use crate::console; -use crate::lockfile; -use crate::package::{self, Stability}; -use crate::resolver::{self, PlatformConfig, ResolveRequest, ResolvedPackage}; use clap::Args; +use mozart_core::console; +use mozart_core::package::{self, Stability}; +use mozart_registry::lockfile; +use mozart_registry::resolver::{self, PlatformConfig, ResolveRequest, ResolvedPackage}; use std::collections::{HashMap, HashSet}; #[derive(Args)] @@ -633,7 +633,7 @@ pub fn apply_minimal_changes( pub fn execute( args: &UpdateArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { // Step 1: Resolve the working directory let working_dir = super::install::resolve_working_dir(cli); @@ -670,8 +670,8 @@ pub fn execute( // Step 3: Read composer.json let composer_json_path = working_dir.join("composer.json"); if !composer_json_path.exists() { - return Err(crate::exit_code::bail( - crate::exit_code::GENERAL_ERROR, + return Err(mozart_core::exit_code::bail( + mozart_core::exit_code::GENERAL_ERROR, format!( "Composer could not find a composer.json file in {}", working_dir.display() @@ -746,8 +746,8 @@ pub fn execute( let mut resolved = match resolver::resolve(&request) { Ok(packages) => packages, Err(e) => { - return Err(crate::exit_code::bail( - crate::exit_code::DEPENDENCY_RESOLUTION_FAILED, + return Err(mozart_core::exit_code::bail( + mozart_core::exit_code::DEPENDENCY_RESOLUTION_FAILED, e.to_string(), )); } @@ -777,8 +777,8 @@ pub fn execute( let update_packages: Vec<String> = if !args.packages.is_empty() { match &old_lock { None => { - return Err(crate::exit_code::bail( - crate::exit_code::NO_LOCK_FILE_FOR_PARTIAL_UPDATE, + return Err(mozart_core::exit_code::bail( + mozart_core::exit_code::NO_LOCK_FILE_FOR_PARTIAL_UPDATE, "No lock file found. Cannot perform partial update. Run `mozart update` first.", )); } @@ -834,8 +834,8 @@ pub fn execute( if !update_packages.is_empty() { match &old_lock { None => { - return Err(crate::exit_code::bail( - crate::exit_code::NO_LOCK_FILE_FOR_PARTIAL_UPDATE, + return Err(mozart_core::exit_code::bail( + mozart_core::exit_code::NO_LOCK_FILE_FOR_PARTIAL_UPDATE, "No lock file found. Cannot perform partial update. Run `mozart update` first.", )); } @@ -947,7 +947,7 @@ pub fn execute( .map(|s| s.eq_ignore_ascii_case("source")) .unwrap_or(false); if prefer_source { - console.info(&crate::console::warning( + console.info(&mozart_core::console::warning( "Warning: Source installs are not yet supported. Falling back to dist.", )); } @@ -986,11 +986,11 @@ fn handle_lock_mode( lock_path: &std::path::Path, composer_json_content: &str, dry_run: bool, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { if !lock_path.exists() { - return Err(crate::exit_code::bail( - crate::exit_code::LOCK_FILE_INVALID, + return Err(mozart_core::exit_code::bail( + mozart_core::exit_code::LOCK_FILE_INVALID, "No lock file found. Run `mozart update` to generate one.", )); } @@ -1360,9 +1360,9 @@ mod tests { // Composer.json content that will produce a different hash let composer_json_content = r#"{"name": "test/project", "require": {"psr/log": "^3.0"}}"#; - let console = crate::console::Console { + let console = mozart_core::console::Console { interactive: false, - verbosity: crate::console::Verbosity::Normal, + verbosity: mozart_core::console::Verbosity::Normal, decorated: false, }; let result = handle_lock_mode(&lock_path, composer_json_content, false, &console); @@ -1388,9 +1388,9 @@ mod tests { lock.content_hash = correct_hash.clone(); lock.write_to_file(&lock_path).unwrap(); - let console = crate::console::Console { + let console = mozart_core::console::Console { interactive: false, - verbosity: crate::console::Verbosity::Normal, + verbosity: mozart_core::console::Verbosity::Normal, decorated: false, }; let result = handle_lock_mode(&lock_path, composer_json_content, false, &console); @@ -1412,9 +1412,9 @@ mod tests { let composer_json_content = r#"{"name": "test/project", "require": {"psr/log": "^3.0"}}"#; - let console = crate::console::Console { + let console = mozart_core::console::Console { interactive: false, - verbosity: crate::console::Verbosity::Normal, + verbosity: mozart_core::console::Verbosity::Normal, decorated: false, }; let result = handle_lock_mode(&lock_path, composer_json_content, true, &console); @@ -1660,9 +1660,9 @@ mod tests { #[test] #[ignore] fn test_update_full_e2e() { - use crate::lockfile::{LockFileGenerationRequest, generate_lock_file}; - use crate::package::RawPackageData; - use crate::resolver::{ResolveRequest, resolve}; + use mozart_core::package::RawPackageData; + use mozart_registry::lockfile::{LockFileGenerationRequest, generate_lock_file}; + use mozart_registry::resolver::{ResolveRequest, resolve}; let composer_json_content = r#"{"name": "test/project", "require": {"monolog/monolog": "^3.0"}}"#; @@ -1717,9 +1717,9 @@ mod tests { let expected_hash = lockfile::LockFile::compute_content_hash(composer_json_content).unwrap(); - let console = crate::console::Console { + let console = mozart_core::console::Console { interactive: false, - verbosity: crate::console::Verbosity::Normal, + verbosity: mozart_core::console::Verbosity::Normal, decorated: false, }; handle_lock_mode(&lock_path, composer_json_content, false, &console).unwrap(); diff --git a/crates/mozart/src/commands/validate.rs b/crates/mozart/src/commands/validate.rs index 1dec3fe..50e3cce 100644 --- a/crates/mozart/src/commands/validate.rs +++ b/crates/mozart/src/commands/validate.rs @@ -70,7 +70,7 @@ impl ValidationResult { pub fn execute( args: &ValidateArgs, cli: &super::Cli, - console: &crate::console::Console, + console: &mozart_core::console::Console, ) -> anyhow::Result<()> { let working_dir = match &cli.working_dir { Some(dir) => PathBuf::from(dir), @@ -91,7 +91,7 @@ pub fn execute( // Check file exists if !file.exists() { - return Err(crate::exit_code::bail( + return Err(mozart_core::exit_code::bail( VALIDATE_FILE_ERROR, format!("{} not found.", file.display()), )); @@ -101,7 +101,7 @@ pub fn execute( let content = match std::fs::read_to_string(&file) { Ok(c) => c, Err(_) => { - return Err(crate::exit_code::bail( + return Err(mozart_core::exit_code::bail( VALIDATE_FILE_ERROR, format!("{} is not readable.", file.display()), )); @@ -112,7 +112,7 @@ pub fn execute( let json_value: serde_json::Value = match serde_json::from_str(&content) { Ok(v) => v, Err(e) => { - return Err(crate::exit_code::bail( + return Err(mozart_core::exit_code::bail( VALIDATE_JSON_ERROR, format!("{} does not contain valid JSON: {e}", file.display()), )); @@ -147,7 +147,7 @@ pub fn execute( args.strict, ); if exit_code != 0 { - return Err(crate::exit_code::bail_silent(exit_code)); + return Err(mozart_core::exit_code::bail_silent(exit_code)); } Ok(()) @@ -208,7 +208,7 @@ fn check_name(obj: &serde_json::Map<String, serde_json::Value>, result: &mut Val // Must contain a slash (vendor/package format) if !name.is_empty() - && !crate::validation::validate_package_name(name) + && !mozart_core::validation::validate_package_name(name) && !name.contains('/') { result.errors.push(format!( @@ -365,7 +365,7 @@ fn check_minimum_stability( result: &mut ValidationResult, ) { if let Some(stability) = obj.get("minimum-stability").and_then(|v| v.as_str()) - && !crate::validation::validate_stability(stability) + && !mozart_core::validation::validate_stability(stability) { result.errors.push(format!( "The minimum-stability \"{stability}\" is invalid. \ @@ -391,7 +391,7 @@ fn check_lock_freshness( return; } - match crate::lockfile::LockFile::read_from_file(&lock_path) { + match mozart_registry::lockfile::LockFile::read_from_file(&lock_path) { Ok(lock) => { if !lock.is_fresh(composer_json_content) { lock_errors.push( @@ -422,35 +422,37 @@ fn output_result( if result.has_errors() { eprintln!( "{}", - crate::console::error(&format!( + mozart_core::console::error(&format!( "{name} is invalid, the following errors/warnings were found:" )) ); } else if result.has_publish_errors() && check_publish { eprintln!( "{}", - crate::console::info(&format!( + mozart_core::console::info(&format!( "{name} is valid for simple usage with Composer but has" )) ); eprintln!( "{}", - crate::console::info("strict errors that make it unable to be published as a package") + mozart_core::console::info( + "strict errors that make it unable to be published as a package" + ) ); eprintln!( "{}", - crate::console::warning( + mozart_core::console::warning( "See https://getcomposer.org/doc/04-schema.md for details on the schema" ) ); } else if result.has_warnings() { eprintln!( "{}", - crate::console::info(&format!("{name} is valid, but with a few warnings")) + mozart_core::console::info(&format!("{name} is valid, but with a few warnings")) ); eprintln!( "{}", - crate::console::warning( + mozart_core::console::warning( "See https://getcomposer.org/doc/04-schema.md for details on the schema" ) ); @@ -458,12 +460,15 @@ fn output_result( let kind = if check_lock { "errors" } else { "warnings" }; println!( "{}", - crate::console::info(&format!( + mozart_core::console::info(&format!( "{name} is valid but your composer.lock has some {kind}" )) ); } else { - println!("{}", crate::console::info(&format!("{name} is valid"))); + println!( + "{}", + mozart_core::console::info(&format!("{name} is valid")) + ); } // Collect error and warning message lines @@ -506,7 +511,7 @@ fn output_result( // Print errors for msg in &all_errors { if msg.starts_with('#') { - eprintln!("{}", crate::console::error(msg)); + eprintln!("{}", mozart_core::console::error(msg)); } else { eprintln!("{msg}"); } @@ -515,7 +520,7 @@ fn output_result( // Print warnings for msg in &all_warnings { if msg.starts_with('#') { - eprintln!("{}", crate::console::warning(msg)); + eprintln!("{}", mozart_core::console::warning(msg)); } else { eprintln!("{msg}"); } @@ -907,7 +912,7 @@ mod tests { #[test] fn test_check_lock_freshness_fresh_lock() { - use crate::lockfile::LockFile; + use mozart_registry::lockfile::LockFile; use tempfile::tempdir; let dir = tempdir().unwrap(); @@ -943,7 +948,7 @@ mod tests { #[test] fn test_check_lock_freshness_stale_lock() { - use crate::lockfile::LockFile; + use mozart_registry::lockfile::LockFile; use tempfile::tempdir; let dir = tempdir().unwrap(); |
