aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/mozart-autoload/Cargo.toml2
-rw-r--r--crates/mozart-autoload/src/autoload.rs233
-rw-r--r--crates/mozart-autoload/src/lib.rs1
-rw-r--r--crates/mozart-class-map-generator/Cargo.toml11
-rw-r--r--crates/mozart-class-map-generator/src/classmap.rs239
-rw-r--r--crates/mozart-class-map-generator/src/lib.rs8
-rw-r--r--crates/mozart-class-map-generator/src/php_scanner.rs (renamed from crates/mozart-autoload/src/php_scanner.rs)0
-rw-r--r--crates/mozart-core/Cargo.toml2
-rw-r--r--crates/mozart-registry/Cargo.toml2
-rw-r--r--crates/mozart-registry/src/resolver.rs4
-rw-r--r--crates/mozart-semver/Cargo.toml (renamed from crates/mozart-constraint/Cargo.toml)2
-rw-r--r--crates/mozart-semver/src/lib.rs (renamed from crates/mozart-constraint/src/lib.rs)0
-rw-r--r--crates/mozart/Cargo.toml4
-rw-r--r--crates/mozart/src/commands/audit.rs6
-rw-r--r--crates/mozart/src/commands/check_platform_reqs.rs14
-rw-r--r--crates/mozart/src/commands/dependency.rs30
-rw-r--r--crates/mozart/src/commands/outdated.rs4
-rw-r--r--crates/mozart/src/commands/prohibits.rs2
18 files changed, 294 insertions, 270 deletions
diff --git a/crates/mozart-autoload/Cargo.toml b/crates/mozart-autoload/Cargo.toml
index 93037df..98c4f6f 100644
--- a/crates/mozart-autoload/Cargo.toml
+++ b/crates/mozart-autoload/Cargo.toml
@@ -4,10 +4,10 @@ version.workspace = true
edition.workspace = true
[dependencies]
+mozart-class-map-generator.workspace = true
mozart-registry.workspace = true
anyhow.workspace = true
md5.workspace = true
-regex.workspace = true
serde_json.workspace = true
[dev-dependencies]
diff --git a/crates/mozart-autoload/src/autoload.rs b/crates/mozart-autoload/src/autoload.rs
index 2e4158c..27f75ff 100644
--- a/crates/mozart-autoload/src/autoload.rs
+++ b/crates/mozart-autoload/src/autoload.rs
@@ -1,3 +1,4 @@
+use mozart_class_map_generator::{scan_classmap_dirs, scan_psr_for_classmap};
use mozart_registry::installed::InstalledPackages;
use mozart_registry::lockfile::LockedPackage;
use std::collections::{BTreeMap, HashSet};
@@ -453,238 +454,6 @@ fn generate_autoload_static(static_data: &AutoloadData, suffix: &str) -> String
out
}
-/// Recursively collect PHP files from a directory, skipping excluded paths.
-fn collect_php_files(
- dir: &Path,
- excluded: &[String],
- vendor_dir: &Path,
- project_dir: &Path,
-) -> Vec<PathBuf> {
- let mut result = Vec::new();
- if !dir.is_dir() {
- return result;
- }
- collect_php_files_inner(dir, excluded, vendor_dir, project_dir, &mut result);
- result
-}
-
-fn collect_php_files_inner(
- dir: &Path,
- excluded: &[String],
- vendor_dir: &Path,
- project_dir: &Path,
- result: &mut Vec<PathBuf>,
-) {
- let entries = match std::fs::read_dir(dir) {
- Ok(e) => e,
- Err(_) => return,
- };
- for entry in entries.flatten() {
- let path = entry.path();
-
- // Check if path matches any excluded pattern
- if is_excluded(&path, excluded, vendor_dir, project_dir) {
- continue;
- }
-
- if path.is_dir() {
- collect_php_files_inner(&path, excluded, vendor_dir, project_dir, result);
- } else if crate::php_scanner::is_php_ext(&path) {
- result.push(path);
- }
- }
-}
-
-/// Check whether a path matches any of the excluded patterns.
-fn is_excluded(path: &Path, excluded: &[String], vendor_dir: &Path, project_dir: &Path) -> bool {
- for exc in excluded {
- // Excluded patterns can be relative to project_dir or absolute
- let exc_path = if Path::new(exc).is_absolute() {
- PathBuf::from(exc)
- } else {
- project_dir.join(exc)
- };
- if path.starts_with(&exc_path) || path == exc_path {
- return true;
- }
- // Also check relative to vendor_dir
- let exc_vendor = vendor_dir.join(exc);
- if path.starts_with(&exc_vendor) || path == exc_vendor {
- return true;
- }
- }
- false
-}
-
-/// Scan directories for PHP class declarations and return a classmap.
-///
-/// `dirs` is a list of absolute directory paths to scan.
-/// Returns a `BTreeMap<class_name, file_path_expression>` where the path expression
-/// uses `$vendorDir` or `$baseDir` as appropriate.
-fn scan_classmap_dirs(
- dirs: &[PathBuf],
- vendor_dir: &Path,
- project_dir: &Path,
- excluded: &[String],
-) -> BTreeMap<String, String> {
- let mut classmap = BTreeMap::new();
-
- for dir in dirs {
- let files = collect_php_files(dir, excluded, vendor_dir, project_dir);
- for file in files {
- match crate::php_scanner::find_classes(&file) {
- Ok(classes) => {
- for class in classes {
- let path_expr = path_to_php_expr(&file, vendor_dir, project_dir);
- classmap.entry(class).or_insert(path_expr);
- }
- }
- Err(_) => continue,
- }
- }
- }
-
- classmap
-}
-
-/// Convert an absolute file path to a PHP path expression using `$vendorDir` or `$baseDir`.
-fn path_to_php_expr(file: &Path, vendor_dir: &Path, project_dir: &Path) -> String {
- if let Ok(rel) = file.strip_prefix(vendor_dir) {
- let rel_str = rel.to_string_lossy().replace('\\', "/");
- format!("$vendorDir . '/{rel_str}'")
- } else if let Ok(rel) = file.strip_prefix(project_dir) {
- let rel_str = rel.to_string_lossy().replace('\\', "/");
- format!("$baseDir . '/{rel_str}'")
- } else {
- // Fall back to absolute path
- let abs = file.to_string_lossy().replace('\\', "/");
- format!("'{abs}'")
- }
-}
-
-/// Convert an absolute file path to a static PHP path expression using `__DIR__ . '/..` form.
-fn path_to_static_expr(file: &Path, vendor_dir: &Path, project_dir: &Path) -> String {
- if let Ok(rel) = file.strip_prefix(vendor_dir) {
- let rel_str = rel.to_string_lossy().replace('\\', "/");
- format!("__DIR__ . '/..' . '/{rel_str}'")
- } else if let Ok(rel) = file.strip_prefix(project_dir) {
- let rel_str = rel.to_string_lossy().replace('\\', "/");
- format!("__DIR__ . '/../..' . '/{rel_str}'")
- } else {
- let abs = file.to_string_lossy().replace('\\', "/");
- format!("'{abs}'")
- }
-}
-
-/// Scan PSR-4 and PSR-0 directories for class declarations (used in optimize mode).
-///
-/// Returns `(dynamic_classmap, static_classmap, psr_violations)`.
-fn scan_psr_for_classmap(
- psr4: &BTreeMap<String, Vec<String>>,
- psr0: &BTreeMap<String, Vec<String>>,
- vendor_dir: &Path,
- project_dir: &Path,
- excluded: &[String],
-) -> (
- BTreeMap<String, String>,
- BTreeMap<String, String>,
- Vec<String>,
-) {
- let mut dyn_map: BTreeMap<String, String> = BTreeMap::new();
- let mut static_map: BTreeMap<String, String> = BTreeMap::new();
- let mut violations: Vec<String> = Vec::new();
-
- // Helper: resolve a PHP path expression to an absolute path.
- let resolve = |expr: &str| -> Option<PathBuf> {
- // Expressions look like:
- // $vendorDir . '/psr/log/src'
- // $baseDir . '/src'
- // __DIR__ . '/..' . '/psr/log/src'
- // __DIR__ . '/../..' . '/src'
- if let Some(rest) = expr.strip_prefix("$vendorDir . '") {
- let rel = rest.trim_end_matches('\'');
- Some(vendor_dir.join(rel.trim_start_matches('/')))
- } else if let Some(rest) = expr.strip_prefix("$baseDir . '") {
- let rel = rest.trim_end_matches('\'');
- Some(project_dir.join(rel.trim_start_matches('/')))
- } else if expr == "$vendorDir" {
- Some(vendor_dir.to_path_buf())
- } else if expr == "$baseDir" {
- Some(project_dir.to_path_buf())
- } else {
- None
- }
- };
-
- // Scan PSR-4 dirs
- for (ns, paths) in psr4 {
- for path_expr in paths {
- if let Some(abs_dir) = resolve(path_expr) {
- let files = collect_php_files(&abs_dir, excluded, vendor_dir, project_dir);
- for file in files {
- match crate::php_scanner::find_classes(&file) {
- Ok(classes) => {
- for class in classes {
- // PSR-4 validation
- let file_str = file.to_string_lossy();
- let dir_str = abs_dir.to_string_lossy();
- let base_ns = ns.as_str();
- if !crate::php_scanner::validate_psr4_class(
- &class, base_ns, &file_str, &dir_str,
- ) {
- violations.push(format!(
- "Class {class} in {file_str} does not comply with PSR-4 (namespace prefix: {ns})"
- ));
- }
- let dyn_expr = path_to_php_expr(&file, vendor_dir, project_dir);
- let static_expr =
- path_to_static_expr(&file, vendor_dir, project_dir);
- dyn_map.entry(class.clone()).or_insert(dyn_expr);
- static_map.entry(class).or_insert(static_expr);
- }
- }
- Err(_) => continue,
- }
- }
- }
- }
- }
-
- // Scan PSR-0 dirs
- for (ns, paths) in psr0 {
- for path_expr in paths {
- if let Some(abs_dir) = resolve(path_expr) {
- let files = collect_php_files(&abs_dir, excluded, vendor_dir, project_dir);
- for file in files {
- match crate::php_scanner::find_classes(&file) {
- Ok(classes) => {
- for class in classes {
- let file_str = file.to_string_lossy();
- let dir_str = abs_dir.to_string_lossy();
- if !crate::php_scanner::validate_psr0_class(
- &class, &file_str, &dir_str,
- ) {
- violations.push(format!(
- "Class {class} in {file_str} does not comply with PSR-0 (namespace prefix: {ns})"
- ));
- }
- let dyn_expr = path_to_php_expr(&file, vendor_dir, project_dir);
- let static_expr =
- path_to_static_expr(&file, vendor_dir, project_dir);
- dyn_map.entry(class.clone()).or_insert(dyn_expr);
- static_map.entry(class).or_insert(static_expr);
- }
- }
- Err(_) => continue,
- }
- }
- }
- }
- }
-
- (dyn_map, static_map, violations)
-}
-
/// Generate `vendor/composer/platform_check.php`.
///
/// Returns `None` if mode is `Disabled` or there are no relevant requirements.
diff --git a/crates/mozart-autoload/src/lib.rs b/crates/mozart-autoload/src/lib.rs
index 9d798c6..fc80aed 100644
--- a/crates/mozart-autoload/src/lib.rs
+++ b/crates/mozart-autoload/src/lib.rs
@@ -1,2 +1 @@
pub mod autoload;
-pub mod php_scanner;
diff --git a/crates/mozart-class-map-generator/Cargo.toml b/crates/mozart-class-map-generator/Cargo.toml
new file mode 100644
index 0000000..15ae0cb
--- /dev/null
+++ b/crates/mozart-class-map-generator/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "mozart-class-map-generator"
+version.workspace = true
+edition.workspace = true
+
+[dependencies]
+anyhow.workspace = true
+regex.workspace = true
+
+[dev-dependencies]
+tempfile.workspace = true
diff --git a/crates/mozart-class-map-generator/src/classmap.rs b/crates/mozart-class-map-generator/src/classmap.rs
new file mode 100644
index 0000000..e1631f4
--- /dev/null
+++ b/crates/mozart-class-map-generator/src/classmap.rs
@@ -0,0 +1,239 @@
+use std::collections::BTreeMap;
+use std::path::{Path, PathBuf};
+
+/// Recursively collect PHP files from a directory, skipping excluded paths.
+pub fn collect_php_files(
+ dir: &Path,
+ excluded: &[String],
+ vendor_dir: &Path,
+ project_dir: &Path,
+) -> Vec<PathBuf> {
+ let mut result = Vec::new();
+ if !dir.is_dir() {
+ return result;
+ }
+ collect_php_files_inner(dir, excluded, vendor_dir, project_dir, &mut result);
+ result
+}
+
+fn collect_php_files_inner(
+ dir: &Path,
+ excluded: &[String],
+ vendor_dir: &Path,
+ project_dir: &Path,
+ result: &mut Vec<PathBuf>,
+) {
+ let entries = match std::fs::read_dir(dir) {
+ Ok(e) => e,
+ Err(_) => return,
+ };
+ for entry in entries.flatten() {
+ let path = entry.path();
+
+ // Check if path matches any excluded pattern
+ if is_excluded(&path, excluded, vendor_dir, project_dir) {
+ continue;
+ }
+
+ if path.is_dir() {
+ collect_php_files_inner(&path, excluded, vendor_dir, project_dir, result);
+ } else if crate::php_scanner::is_php_ext(&path) {
+ result.push(path);
+ }
+ }
+}
+
+/// Check whether a path matches any of the excluded patterns.
+pub fn is_excluded(
+ path: &Path,
+ excluded: &[String],
+ vendor_dir: &Path,
+ project_dir: &Path,
+) -> bool {
+ for exc in excluded {
+ // Excluded patterns can be relative to project_dir or absolute
+ let exc_path = if Path::new(exc).is_absolute() {
+ PathBuf::from(exc)
+ } else {
+ project_dir.join(exc)
+ };
+ if path.starts_with(&exc_path) || path == exc_path {
+ return true;
+ }
+ // Also check relative to vendor_dir
+ let exc_vendor = vendor_dir.join(exc);
+ if path.starts_with(&exc_vendor) || path == exc_vendor {
+ return true;
+ }
+ }
+ false
+}
+
+/// Scan directories for PHP class declarations and return a classmap.
+///
+/// `dirs` is a list of absolute directory paths to scan.
+/// Returns a `BTreeMap<class_name, file_path_expression>` where the path expression
+/// uses `$vendorDir` or `$baseDir` as appropriate.
+pub fn scan_classmap_dirs(
+ dirs: &[PathBuf],
+ vendor_dir: &Path,
+ project_dir: &Path,
+ excluded: &[String],
+) -> BTreeMap<String, String> {
+ let mut classmap = BTreeMap::new();
+
+ for dir in dirs {
+ let files = collect_php_files(dir, excluded, vendor_dir, project_dir);
+ for file in files {
+ match crate::php_scanner::find_classes(&file) {
+ Ok(classes) => {
+ for class in classes {
+ let path_expr = path_to_php_expr(&file, vendor_dir, project_dir);
+ classmap.entry(class).or_insert(path_expr);
+ }
+ }
+ Err(_) => continue,
+ }
+ }
+ }
+
+ classmap
+}
+
+/// Convert an absolute file path to a PHP path expression using `$vendorDir` or `$baseDir`.
+pub fn path_to_php_expr(file: &Path, vendor_dir: &Path, project_dir: &Path) -> String {
+ if let Ok(rel) = file.strip_prefix(vendor_dir) {
+ let rel_str = rel.to_string_lossy().replace('\\', "/");
+ format!("$vendorDir . '/{rel_str}'")
+ } else if let Ok(rel) = file.strip_prefix(project_dir) {
+ let rel_str = rel.to_string_lossy().replace('\\', "/");
+ format!("$baseDir . '/{rel_str}'")
+ } else {
+ // Fall back to absolute path
+ let abs = file.to_string_lossy().replace('\\', "/");
+ format!("'{abs}'")
+ }
+}
+
+/// Convert an absolute file path to a static PHP path expression using `__DIR__ . '/..` form.
+pub fn path_to_static_expr(file: &Path, vendor_dir: &Path, project_dir: &Path) -> String {
+ if let Ok(rel) = file.strip_prefix(vendor_dir) {
+ let rel_str = rel.to_string_lossy().replace('\\', "/");
+ format!("__DIR__ . '/..' . '/{rel_str}'")
+ } else if let Ok(rel) = file.strip_prefix(project_dir) {
+ let rel_str = rel.to_string_lossy().replace('\\', "/");
+ format!("__DIR__ . '/../..' . '/{rel_str}'")
+ } else {
+ let abs = file.to_string_lossy().replace('\\', "/");
+ format!("'{abs}'")
+ }
+}
+
+/// Scan PSR-4 and PSR-0 directories for class declarations (used in optimize mode).
+///
+/// Returns `(dynamic_classmap, static_classmap, psr_violations)`.
+pub fn scan_psr_for_classmap(
+ psr4: &BTreeMap<String, Vec<String>>,
+ psr0: &BTreeMap<String, Vec<String>>,
+ vendor_dir: &Path,
+ project_dir: &Path,
+ excluded: &[String],
+) -> (
+ BTreeMap<String, String>,
+ BTreeMap<String, String>,
+ Vec<String>,
+) {
+ let mut dyn_map: BTreeMap<String, String> = BTreeMap::new();
+ let mut static_map: BTreeMap<String, String> = BTreeMap::new();
+ let mut violations: Vec<String> = Vec::new();
+
+ // Helper: resolve a PHP path expression to an absolute path.
+ let resolve = |expr: &str| -> Option<PathBuf> {
+ // Expressions look like:
+ // $vendorDir . '/psr/log/src'
+ // $baseDir . '/src'
+ // __DIR__ . '/..' . '/psr/log/src'
+ // __DIR__ . '/../..' . '/src'
+ if let Some(rest) = expr.strip_prefix("$vendorDir . '") {
+ let rel = rest.trim_end_matches('\'');
+ Some(vendor_dir.join(rel.trim_start_matches('/')))
+ } else if let Some(rest) = expr.strip_prefix("$baseDir . '") {
+ let rel = rest.trim_end_matches('\'');
+ Some(project_dir.join(rel.trim_start_matches('/')))
+ } else if expr == "$vendorDir" {
+ Some(vendor_dir.to_path_buf())
+ } else if expr == "$baseDir" {
+ Some(project_dir.to_path_buf())
+ } else {
+ None
+ }
+ };
+
+ // Scan PSR-4 dirs
+ for (ns, paths) in psr4 {
+ for path_expr in paths {
+ if let Some(abs_dir) = resolve(path_expr) {
+ let files = collect_php_files(&abs_dir, excluded, vendor_dir, project_dir);
+ for file in files {
+ match crate::php_scanner::find_classes(&file) {
+ Ok(classes) => {
+ for class in classes {
+ // PSR-4 validation
+ let file_str = file.to_string_lossy();
+ let dir_str = abs_dir.to_string_lossy();
+ let base_ns = ns.as_str();
+ if !crate::php_scanner::validate_psr4_class(
+ &class, base_ns, &file_str, &dir_str,
+ ) {
+ violations.push(format!(
+ "Class {class} in {file_str} does not comply with PSR-4 (namespace prefix: {ns})"
+ ));
+ }
+ let dyn_expr = path_to_php_expr(&file, vendor_dir, project_dir);
+ let static_expr =
+ path_to_static_expr(&file, vendor_dir, project_dir);
+ dyn_map.entry(class.clone()).or_insert(dyn_expr);
+ static_map.entry(class).or_insert(static_expr);
+ }
+ }
+ Err(_) => continue,
+ }
+ }
+ }
+ }
+ }
+
+ // Scan PSR-0 dirs
+ for (ns, paths) in psr0 {
+ for path_expr in paths {
+ if let Some(abs_dir) = resolve(path_expr) {
+ let files = collect_php_files(&abs_dir, excluded, vendor_dir, project_dir);
+ for file in files {
+ match crate::php_scanner::find_classes(&file) {
+ Ok(classes) => {
+ for class in classes {
+ let file_str = file.to_string_lossy();
+ let dir_str = abs_dir.to_string_lossy();
+ if !crate::php_scanner::validate_psr0_class(
+ &class, &file_str, &dir_str,
+ ) {
+ violations.push(format!(
+ "Class {class} in {file_str} does not comply with PSR-0 (namespace prefix: {ns})"
+ ));
+ }
+ let dyn_expr = path_to_php_expr(&file, vendor_dir, project_dir);
+ let static_expr =
+ path_to_static_expr(&file, vendor_dir, project_dir);
+ dyn_map.entry(class.clone()).or_insert(dyn_expr);
+ static_map.entry(class).or_insert(static_expr);
+ }
+ }
+ Err(_) => continue,
+ }
+ }
+ }
+ }
+ }
+
+ (dyn_map, static_map, violations)
+}
diff --git a/crates/mozart-class-map-generator/src/lib.rs b/crates/mozart-class-map-generator/src/lib.rs
new file mode 100644
index 0000000..a17405c
--- /dev/null
+++ b/crates/mozart-class-map-generator/src/lib.rs
@@ -0,0 +1,8 @@
+pub mod classmap;
+pub mod php_scanner;
+
+pub use classmap::{
+ collect_php_files, is_excluded, path_to_php_expr, path_to_static_expr, scan_classmap_dirs,
+ scan_psr_for_classmap,
+};
+pub use php_scanner::{find_classes, is_php_ext, validate_psr0_class, validate_psr4_class};
diff --git a/crates/mozart-autoload/src/php_scanner.rs b/crates/mozart-class-map-generator/src/php_scanner.rs
index 3d0d51d..3d0d51d 100644
--- a/crates/mozart-autoload/src/php_scanner.rs
+++ b/crates/mozart-class-map-generator/src/php_scanner.rs
diff --git a/crates/mozart-core/Cargo.toml b/crates/mozart-core/Cargo.toml
index 885fdf4..599dbb3 100644
--- a/crates/mozart-core/Cargo.toml
+++ b/crates/mozart-core/Cargo.toml
@@ -4,10 +4,10 @@ version.workspace = true
edition.workspace = true
[dependencies]
+mozart-spdx-licenses.workspace = true
anyhow.workspace = true
colored.workspace = true
dialoguer.workspace = true
-mozart-spdx-licenses.workspace = true
regex.workspace = true
serde.workspace = true
serde_json.workspace = true
diff --git a/crates/mozart-registry/Cargo.toml b/crates/mozart-registry/Cargo.toml
index 8672708..d0159b6 100644
--- a/crates/mozart-registry/Cargo.toml
+++ b/crates/mozart-registry/Cargo.toml
@@ -4,9 +4,9 @@ version.workspace = true
edition.workspace = true
[dependencies]
-mozart-constraint.workspace = true
mozart-core.workspace = true
mozart-metadata-minifier.workspace = true
+mozart-semver.workspace = true
anyhow.workspace = true
filetime.workspace = true
flate2.workspace = true
diff --git a/crates/mozart-registry/src/resolver.rs b/crates/mozart-registry/src/resolver.rs
index 61895eb..e240dcd 100644
--- a/crates/mozart-registry/src/resolver.rs
+++ b/crates/mozart-registry/src/resolver.rs
@@ -15,8 +15,8 @@ use pubgrub::{
use crate::cache::Cache;
use crate::packagist;
-use mozart_constraint::{Constraint, VersionConstraint};
use mozart_core::package::Stability;
+use mozart_semver::{Constraint, VersionConstraint};
// ─────────────────────────────────────────────────────────────────────────────
// Stability constants
@@ -372,7 +372,7 @@ fn single_constraint_to_ranges(c: &Constraint) -> Result<ComposerVS, String> {
}
/// Convert a `constraint::Version` to a `ComposerVersion`.
-fn version_to_composer(v: &mozart_constraint::Version) -> Result<ComposerVersion, String> {
+fn version_to_composer(v: &mozart_semver::Version) -> Result<ComposerVersion, String> {
// Dev branches cannot be represented as ComposerVersion
if v.is_dev_branch {
return Err(format!(
diff --git a/crates/mozart-constraint/Cargo.toml b/crates/mozart-semver/Cargo.toml
index 49265d7..cee0804 100644
--- a/crates/mozart-constraint/Cargo.toml
+++ b/crates/mozart-semver/Cargo.toml
@@ -1,4 +1,4 @@
[package]
-name = "mozart-constraint"
+name = "mozart-semver"
version.workspace = true
edition.workspace = true
diff --git a/crates/mozart-constraint/src/lib.rs b/crates/mozart-semver/src/lib.rs
index 7c417ec..7c417ec 100644
--- a/crates/mozart-constraint/src/lib.rs
+++ b/crates/mozart-semver/src/lib.rs
diff --git a/crates/mozart/Cargo.toml b/crates/mozart/Cargo.toml
index 18b34bf..443cd9e 100644
--- a/crates/mozart/Cargo.toml
+++ b/crates/mozart/Cargo.toml
@@ -4,11 +4,11 @@ version.workspace = true
edition.workspace = true
[dependencies]
-mozart-constraint.workspace = true
mozart-archiver.workspace = true
mozart-autoload.workspace = true
mozart-core.workspace = true
mozart-registry.workspace = true
+mozart-semver.workspace = true
anyhow.workspace = true
clap.workspace = true
clap_complete.workspace = true
@@ -21,8 +21,8 @@ serde_json.workspace = true
sha1.workspace = true
tempfile.workspace = true
tokio.workspace = true
-tracing.workspace = true
tracing-subscriber.workspace = true
+tracing.workspace = true
[dev-dependencies]
assert_cmd.workspace = true
diff --git a/crates/mozart/src/commands/audit.rs b/crates/mozart/src/commands/audit.rs
index 8f15ef0..2faec19 100644
--- a/crates/mozart/src/commands/audit.rs
+++ b/crates/mozart/src/commands/audit.rs
@@ -273,7 +273,7 @@ fn filter_advisories(
.as_deref()
.unwrap_or(pkg.version.as_str());
- let installed_ver = match mozart_constraint::Version::parse(version_str) {
+ let installed_ver = match mozart_semver::Version::parse(version_str) {
Ok(v) => v,
Err(_) => {
eprintln!(
@@ -298,9 +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 mozart_constraint::VersionConstraint::parse(
- &normalized_constraint,
- ) {
+ let constraint = match mozart_semver::VersionConstraint::parse(&normalized_constraint) {
Ok(c) => c,
Err(_) => {
eprintln!(
diff --git a/crates/mozart/src/commands/check_platform_reqs.rs b/crates/mozart/src/commands/check_platform_reqs.rs
index 295f9b7..79a1da7 100644
--- a/crates/mozart/src/commands/check_platform_reqs.rs
+++ b/crates/mozart/src/commands/check_platform_reqs.rs
@@ -279,21 +279,21 @@ fn check_requirements(
}
Some(detected) => {
// Check all constraints
- let detected_version = match mozart_constraint::Version::parse(&detected.version) {
+ let detected_version = match mozart_semver::Version::parse(&detected.version) {
Ok(v) => v,
Err(_) => {
// Unparseable version → treat as 0.0.0
- mozart_constraint::Version::parse("0.0.0").unwrap()
+ mozart_semver::Version::parse("0.0.0").unwrap()
}
};
let mut failed_req: Option<(String, String)> = None;
for req in reqs {
- let constraint =
- match mozart_constraint::VersionConstraint::parse(&req.constraint) {
- Ok(c) => c,
- Err(_) => continue, // skip unparseable constraints
- };
+ let constraint = match mozart_semver::VersionConstraint::parse(&req.constraint)
+ {
+ Ok(c) => c,
+ Err(_) => continue, // skip unparseable constraints
+ };
if !constraint.matches(&detected_version) {
failed_req = Some((req.constraint.clone(), req.provider.clone()));
break;
diff --git a/crates/mozart/src/commands/dependency.rs b/crates/mozart/src/commands/dependency.rs
index 4714de2..5073be0 100644
--- a/crates/mozart/src/commands/dependency.rs
+++ b/crates/mozart/src/commands/dependency.rs
@@ -192,7 +192,7 @@ fn load_from_installed(working_dir: &Path) -> Result<Vec<PackageInfo>> {
pub fn get_dependents(
packages: &[PackageInfo],
needles: &[String],
- constraint: Option<&mozart_constraint::VersionConstraint>,
+ constraint: Option<&mozart_semver::VersionConstraint>,
inverted: bool,
recursive: bool,
) -> Result<Vec<DependencyResult>> {
@@ -317,7 +317,7 @@ fn recurse_dependents(
fn get_prohibitors(
packages: &[PackageInfo],
needles: &[String],
- constraint: Option<&mozart_constraint::VersionConstraint>,
+ constraint: Option<&mozart_semver::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) =
- mozart_constraint::VersionConstraint::parse(req_constraint_str)
+ mozart_semver::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) =
- mozart_constraint::VersionConstraint::parse(req_constraint_str)
+ mozart_semver::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) =
- mozart_constraint::VersionConstraint::parse(conflict_constraint_str)
+ mozart_semver::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: &mozart_constraint::VersionConstraint,
- pkg_constraint: &mozart_constraint::VersionConstraint,
+ requested: &mozart_semver::VersionConstraint,
+ pkg_constraint: &mozart_semver::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: &mozart_constraint::VersionConstraint,
- conflict_constraint: &mozart_constraint::VersionConstraint,
+ requested: &mozart_semver::VersionConstraint,
+ conflict_constraint: &mozart_semver::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: &mozart_constraint::VersionConstraint,
-) -> Vec<mozart_constraint::Version> {
- use mozart_constraint::Version;
+ constraint: &mozart_semver::VersionConstraint,
+) -> Vec<mozart_semver::Version> {
+ use mozart_semver::Version;
// Broad grid of versions to probe
let candidates: &[&str] = &[
@@ -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 = mozart_constraint::VersionConstraint::parse("2.0.0").unwrap();
+ let constraint = mozart_semver::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 = mozart_constraint::VersionConstraint::parse("2.0.0").unwrap();
+ let constraint = mozart_semver::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 = mozart_constraint::VersionConstraint::parse("2.5.0").unwrap();
+ let constraint = mozart_semver::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/outdated.rs b/crates/mozart/src/commands/outdated.rs
index eba0d52..1807435 100644
--- a/crates/mozart/src/commands/outdated.rs
+++ b/crates/mozart/src/commands/outdated.rs
@@ -371,8 +371,8 @@ fn classify_update(
// We have an update available — classify it
if let Some(constraint_str) = root_constraint
- && let Ok(constraint) = mozart_constraint::VersionConstraint::parse(constraint_str)
- && let Ok(latest_ver) = mozart_constraint::Version::parse(latest_normalized)
+ && let Ok(constraint) = mozart_semver::VersionConstraint::parse(constraint_str)
+ && let Ok(latest_ver) = mozart_semver::Version::parse(latest_normalized)
{
if constraint.matches(&latest_ver) {
return UpdateCategory::SemverCompatible;
diff --git a/crates/mozart/src/commands/prohibits.rs b/crates/mozart/src/commands/prohibits.rs
index 1f45b27..ca3bc35 100644
--- a/crates/mozart/src/commands/prohibits.rs
+++ b/crates/mozart/src/commands/prohibits.rs
@@ -43,7 +43,7 @@ pub async fn execute(
}
// Parse the version constraint the user is asking about
- let version_constraint = mozart_constraint::VersionConstraint::parse(&args.version)
+ let version_constraint = mozart_semver::VersionConstraint::parse(&args.version)
.map_err(|e| anyhow::anyhow!("Invalid version constraint '{}': {}", args.version, e))?;
let recursive = args.tree || args.recursive;