diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-10 16:22:06 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-10 16:22:06 +0900 |
| commit | dd13f29a3535bf15bb2494da4c67b5e2c61bbda5 (patch) | |
| tree | 8a0bbdd3ebe24e310d12ebd400b1ccc2a1988458 /crates | |
| parent | deb44112883ab7ff932b0ab7c547680a615c7821 (diff) | |
| download | php-mozart-dd13f29a3535bf15bb2494da4c67b5e2c61bbda5.tar.gz php-mozart-dd13f29a3535bf15bb2494da4c67b5e2c61bbda5.tar.zst php-mozart-dd13f29a3535bf15bb2494da4c67b5e2c61bbda5.zip | |
refactor(package): move version guesser and array dumper under package module
Mirror Composer's namespace layout: VersionGuesser/VersionParser move from
vcs/ to package/version/, and ArrayDumper is extracted out of the status
command into package/dumper/, matching Composer\Package\Version and
Composer\Package\Dumper.
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/mozart-core/src/package.rs | 2 | ||||
| -rw-r--r-- | crates/mozart-core/src/package/dumper.rs | 3 | ||||
| -rw-r--r-- | crates/mozart-core/src/package/dumper/array_dumper.rs | 55 | ||||
| -rw-r--r-- | crates/mozart-core/src/package/version.rs | 5 | ||||
| -rw-r--r-- | crates/mozart-core/src/package/version/version_guesser.rs (renamed from crates/mozart-core/src/vcs/version_guesser.rs) | 32 | ||||
| -rw-r--r-- | crates/mozart-core/src/package/version/version_parser.rs | 8 | ||||
| -rw-r--r-- | crates/mozart-core/src/vcs.rs | 1 | ||||
| -rw-r--r-- | crates/mozart/src/commands/status.rs | 104 |
8 files changed, 104 insertions, 106 deletions
diff --git a/crates/mozart-core/src/package.rs b/crates/mozart-core/src/package.rs index 0d5c482..c6a3ae9 100644 --- a/crates/mozart-core/src/package.rs +++ b/crates/mozart-core/src/package.rs @@ -6,6 +6,8 @@ use std::fs; use std::path::Path; pub mod archiver; +pub mod dumper; +pub mod version; /// Package stability level. /// Higher value = less stable. diff --git a/crates/mozart-core/src/package/dumper.rs b/crates/mozart-core/src/package/dumper.rs new file mode 100644 index 0000000..18af6b0 --- /dev/null +++ b/crates/mozart-core/src/package/dumper.rs @@ -0,0 +1,3 @@ +mod array_dumper; + +pub use array_dumper::*; diff --git a/crates/mozart-core/src/package/dumper/array_dumper.rs b/crates/mozart-core/src/package/dumper/array_dumper.rs new file mode 100644 index 0000000..cd53e7a --- /dev/null +++ b/crates/mozart-core/src/package/dumper/array_dumper.rs @@ -0,0 +1,55 @@ +use crate::composer::{InstallationSource, LocalPackage}; + +/// Mirrors `Composer\Package\Dumper\ArrayDumper`. Serialises a `LocalPackage` +/// into the JSON shape that `VersionGuesser::guess_version` expects. +#[derive(Default)] +pub struct ArrayDumper; + +impl ArrayDumper { + pub fn new() -> Self { + Self + } + + pub fn dump(&self, package: &LocalPackage) -> serde_json::Value { + build_package_config(package) + } +} + +/// Serialises a `LocalPackage` to the JSON shape consumed by +/// `VersionGuesser::guess_version`. Mirrors `ArrayDumper::dump($package)` — +/// we include all fields that `VersionGuesser` inspects. +fn build_package_config(package: &LocalPackage) -> serde_json::Value { + let mut obj = serde_json::Map::new(); + obj.insert("name".into(), package.pretty_name().into()); + obj.insert("version".into(), package.pretty_version().into()); + if let Some(t) = package.package_type() { + obj.insert("type".into(), t.into()); + } + obj.insert("extra".into(), package.extra().clone()); + if let Some(src) = package.source() { + let mut s = serde_json::Map::new(); + s.insert("type".into(), src.kind.clone().into()); + s.insert("url".into(), src.url.clone().into()); + if let Some(r) = &src.reference { + s.insert("reference".into(), r.clone().into()); + } + obj.insert("source".into(), serde_json::Value::Object(s)); + } + if let Some(dist) = package.dist() { + let mut d = serde_json::Map::new(); + d.insert("type".into(), dist.kind.clone().into()); + d.insert("url".into(), dist.url.clone().into()); + if let Some(r) = &dist.reference { + d.insert("reference".into(), r.clone().into()); + } + obj.insert("dist".into(), serde_json::Value::Object(d)); + } + if let Some(is) = package.installation_source() { + let s = match is { + InstallationSource::Source => "source", + InstallationSource::Dist => "dist", + }; + obj.insert("installation-source".into(), s.into()); + } + serde_json::Value::Object(obj) +} diff --git a/crates/mozart-core/src/package/version.rs b/crates/mozart-core/src/package/version.rs new file mode 100644 index 0000000..a4cbe52 --- /dev/null +++ b/crates/mozart-core/src/package/version.rs @@ -0,0 +1,5 @@ +mod version_guesser; +mod version_parser; + +pub use version_guesser::*; +pub use version_parser::*; diff --git a/crates/mozart-core/src/vcs/version_guesser.rs b/crates/mozart-core/src/package/version/version_guesser.rs index 58b758e..b8071e8 100644 --- a/crates/mozart-core/src/vcs/version_guesser.rs +++ b/crates/mozart-core/src/package/version/version_guesser.rs @@ -1,14 +1,5 @@ -//! `VersionGuesser` — derive a package's current version from the working -//! copy, mirroring `Composer\Package\Version\VersionGuesser`. -//! -//! Differences from the PHP version: -//! - Fossil is not supported (Mozart has no Fossil driver). -//! - `Platform::isInputCompletionProcess()` short-circuit is omitted. -//! - `guess_feature_version` runs candidate comparisons sequentially. -//! Composer parallelises via `executeAsync`; ours is simpler at the -//! cost of speed when many candidate branches exist. - -use super::process::ProcessExecutor; +use crate::package::version::VersionParser; +use crate::vcs::process::ProcessExecutor; use mozart_semver::{Version, normalize_branch}; use regex::Regex; use serde_json::Value; @@ -17,25 +8,6 @@ use std::sync::LazyLock; const DEFAULT_BRANCH_ALIAS: &str = "9999999-dev"; -/// Mirrors `Composer\Package\Version\VersionParser` (itself a thin wrapper -/// around `Composer\Semver\VersionParser`). In Rust, semver parsing is -/// handled by `mozart_semver` directly, so this type carries no state; -/// it exists to keep `VersionGuesser::new` signature compatible with the -/// PHP constructor. -pub struct VersionParser; - -impl Default for VersionParser { - fn default() -> Self { - Self::new() - } -} - -impl VersionParser { - pub fn new() -> Self { - Self - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct GuessedVersion { pub version: String, diff --git a/crates/mozart-core/src/package/version/version_parser.rs b/crates/mozart-core/src/package/version/version_parser.rs new file mode 100644 index 0000000..d2f5ccf --- /dev/null +++ b/crates/mozart-core/src/package/version/version_parser.rs @@ -0,0 +1,8 @@ +#[derive(Default)] +pub struct VersionParser; + +impl VersionParser { + pub fn new() -> Self { + Self + } +} diff --git a/crates/mozart-core/src/vcs.rs b/crates/mozart-core/src/vcs.rs index e7ca383..11db58d 100644 --- a/crates/mozart-core/src/vcs.rs +++ b/crates/mozart-core/src/vcs.rs @@ -3,4 +3,3 @@ pub mod driver; pub mod process; pub mod repository; pub mod util; -pub mod version_guesser; diff --git a/crates/mozart/src/commands/status.rs b/crates/mozart/src/commands/status.rs index 7cd7546..d538138 100644 --- a/crates/mozart/src/commands/status.rs +++ b/crates/mozart/src/commands/status.rs @@ -1,30 +1,22 @@ use crate::composer::Composer; use clap::Args; -use mozart_core::composer::{InstallationSource, LocalPackage}; +use mozart_core::composer::InstallationSource; use mozart_core::console::IoInterface; use mozart_core::console_writeln; use mozart_core::console_writeln_error; use mozart_core::exit_code; -use mozart_core::vcs::version_guesser::{VersionGuesser, VersionParser}; +use mozart_core::package::dumper::ArrayDumper; +use mozart_core::package::version::{VersionGuesser, VersionParser}; #[derive(Args)] pub struct StatusArgs {} -struct VcsVerChange { - previous: VerRef, - current: VerRef, -} - -struct VerRef { - version: String, - reference: String, -} - pub async fn execute( _args: &StatusArgs, cli: &super::Cli, io: std::sync::Arc<std::sync::Mutex<Box<dyn IoInterface>>>, ) -> anyhow::Result<()> { + // init repos let composer = Composer::require(cli.working_dir()?)?; let installed_repo = composer.repository_manager().local_repository(); @@ -40,6 +32,7 @@ pub async fn execute( let guesser = VersionGuesser::new(parser); let dumper = ArrayDumper::new(); + // list packages for package in installed_repo.get_canonical_packages() { let Some(downloader) = dm.get_downloader_for_package(package) else { continue; @@ -147,26 +140,30 @@ pub async fn execute( "<warning>You have version variations in the following dependencies:</warning>" ); - for (path, change) in &vcs_version_changes { + for (path, changes) in &vcs_version_changes { if cli.is_verbose() { - let mut prev = if change.previous.version.is_empty() { - change.previous.reference.clone() + // If we don't can't find a version, use the ref instead. + let mut current_version = if changes.current.version.is_empty() { + changes.current.reference.clone() } else { - change.previous.version.clone() + changes.current.version.clone() }; - let mut curr = if change.current.version.is_empty() { - change.current.reference.clone() + let mut previous_version = if changes.previous.version.is_empty() { + changes.previous.reference.clone() } else { - change.current.version.clone() + changes.previous.version.clone() }; + if io.lock().unwrap().is_very_verbose() { - prev.push_str(&format!(" ({})", change.previous.reference)); - curr.push_str(&format!(" ({})", change.current.reference)); + // Output the ref regardless of whether or not it's being used as the version + current_version.push_str(&format!(" ({})", changes.current.reference)); + previous_version.push_str(&format!(" ({})", changes.previous.reference)); } + console_writeln!(io, "<info>{path}</info>:"); console_writeln!( io, - " From <comment>{prev}</comment> to <comment>{curr}</comment>" + " From <comment>{previous_version}</comment> to <comment>{current_version}</comment>" ); } else { console_writeln!(io, "{}", path); @@ -191,62 +188,19 @@ pub async fn execute( Ok(()) } +struct VcsVerChange { + previous: VerRef, + current: VerRef, +} + +struct VerRef { + version: String, + reference: String, +} + fn indent_block(s: &str) -> String { s.split('\n') .map(|line| format!(" {}", line.trim_start())) .collect::<Vec<_>>() .join("\n") } - -/// Mirrors `Composer\Package\Dumper\ArrayDumper`. Serialises a `LocalPackage` -/// into the JSON shape that `VersionGuesser::guess_version` expects. -struct ArrayDumper; - -impl ArrayDumper { - fn new() -> Self { - Self - } - - fn dump(&self, package: &LocalPackage) -> serde_json::Value { - build_package_config(package) - } -} - -/// Serialises a `LocalPackage` to the JSON shape consumed by -/// `VersionGuesser::guess_version`. Mirrors `ArrayDumper::dump($package)` — -/// we include all fields that `VersionGuesser` inspects. -fn build_package_config(package: &LocalPackage) -> serde_json::Value { - let mut obj = serde_json::Map::new(); - obj.insert("name".into(), package.pretty_name().into()); - obj.insert("version".into(), package.pretty_version().into()); - if let Some(t) = package.package_type() { - obj.insert("type".into(), t.into()); - } - obj.insert("extra".into(), package.extra().clone()); - if let Some(src) = package.source() { - let mut s = serde_json::Map::new(); - s.insert("type".into(), src.kind.clone().into()); - s.insert("url".into(), src.url.clone().into()); - if let Some(r) = &src.reference { - s.insert("reference".into(), r.clone().into()); - } - obj.insert("source".into(), serde_json::Value::Object(s)); - } - if let Some(dist) = package.dist() { - let mut d = serde_json::Map::new(); - d.insert("type".into(), dist.kind.clone().into()); - d.insert("url".into(), dist.url.clone().into()); - if let Some(r) = &dist.reference { - d.insert("reference".into(), r.clone().into()); - } - obj.insert("dist".into(), serde_json::Value::Object(d)); - } - if let Some(is) = package.installation_source() { - let s = match is { - InstallationSource::Source => "source", - InstallationSource::Dist => "dist", - }; - obj.insert("installation-source".into(), s.into()); - } - serde_json::Value::Object(obj) -} |
