diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-03 12:15:02 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-03 12:15:02 +0900 |
| commit | 7badb54195131da9c3561c351138c0ba083e38e4 (patch) | |
| tree | 0498ab8c3bfcf90e01fcecf451a10ad3844514ff /crates/mozart-registry | |
| parent | dffb6244ebb432477b83631d68584bbc7186dd94 (diff) | |
| download | php-mozart-7badb54195131da9c3561c351138c0ba083e38e4.tar.gz php-mozart-7badb54195131da9c3561c351138c0ba083e38e4.tar.zst php-mozart-7badb54195131da9c3561c351138c0ba083e38e4.zip | |
fix(install): switch update trace to dist-ref mode when source refs match
Composer's UpdateOperation::format renders the from/to versions through
DISPLAY_SOURCE_REF_IF_DEV first, but if both sides come out identical it
re-renders in DISPLAY_SOURCE_REF (when source refs differ) or
DISPLAY_DIST_REF (when only dist refs differ) so the trace doesn't show
a useless `pkg (X => X)` line. Mozart skipped the switch and emitted the
default form on both halves, so a same-version-different-dist-ref update
showed up as `dev-master def000 => dev-master def000` instead of
`dev-master def000 => dev-master`.
Add format_update_pretty_versions to render the pair Composer's way and
plumb the resolved to_full_pretty through PackageOperation::Update so
the trace recorder uses it verbatim.
Unblocks update_installed_reference and update_picks_up_change_of_vcs_type
installer fixtures.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart-registry')
| -rw-r--r-- | crates/mozart-registry/src/installer_executor/mod.rs | 87 | ||||
| -rw-r--r-- | crates/mozart-registry/src/installer_executor/trace_recorder.rs | 6 |
2 files changed, 86 insertions, 7 deletions
diff --git a/crates/mozart-registry/src/installer_executor/mod.rs b/crates/mozart-registry/src/installer_executor/mod.rs index 704031f..a774490 100644 --- a/crates/mozart-registry/src/installer_executor/mod.rs +++ b/crates/mozart-registry/src/installer_executor/mod.rs @@ -32,12 +32,15 @@ pub enum PackageOperation<'a> { Install { package: &'a LockedPackage }, /// Replace an existing install with a new version. `from_version` is the /// pretty version that was installed before (no reference suffix — - /// drives the upgrade-vs-downgrade direction). `from_full_pretty` is the - /// formatted display string (`dev-master abc123`) used verbatim in the - /// trace output. + /// drives the upgrade-vs-downgrade direction). `from_full_pretty` / + /// `to_full_pretty` are the formatted display strings used verbatim in + /// the trace output; the caller renders them via + /// [`format_update_pretty_versions`] so the SOURCE_REF / DIST_REF mode + /// switch from Composer's `UpdateOperation::format` lands on both sides. Update { from_version: &'a str, from_full_pretty: &'a str, + to_full_pretty: &'a str, package: &'a LockedPackage, }, /// Mark an alias of a real package as installed. No filesystem effects — @@ -118,6 +121,84 @@ pub fn format_full_pretty_version_for_installed(entry: &InstalledPackageEntry) - ) } +/// Render the from/to display strings for an update trace line, mirroring +/// Composer's `UpdateOperation::format`. Defaults to `DISPLAY_SOURCE_REF_IF_DEV`, +/// then if both sides render identically: +/// +/// - source references differ → re-render in `DISPLAY_SOURCE_REF` mode, +/// - else dist references differ → re-render in `DISPLAY_DIST_REF` mode. +/// +/// Without the switch, two same-version-different-reference packages would +/// produce a useless `pkg (X => X)` trace line. +pub fn format_update_pretty_versions( + from_entry: &InstalledPackageEntry, + to_pkg: &LockedPackage, +) -> (String, String) { + let from_default = format_full_pretty_version_for_installed(from_entry); + let to_default = format_full_pretty_version(to_pkg); + if from_default != to_default { + return (from_default, to_default); + } + + let from_source_ref = from_entry + .source + .as_ref() + .and_then(|v| v.get("reference")) + .and_then(|v| v.as_str()); + let from_source_type = from_entry + .source + .as_ref() + .and_then(|v| v.get("type")) + .and_then(|v| v.as_str()); + let to_source_ref = to_pkg.source.as_ref().and_then(|s| s.reference.as_deref()); + let to_source_type = to_pkg.source.as_ref().map(|s| s.source_type.as_str()); + + if from_source_ref != to_source_ref { + return ( + format_with_explicit_reference(&from_entry.version, from_source_ref, from_source_type), + format_with_explicit_reference(&to_pkg.version, to_source_ref, to_source_type), + ); + } + + let from_dist_ref = from_entry + .dist + .as_ref() + .and_then(|v| v.get("reference")) + .and_then(|v| v.as_str()); + let to_dist_ref = to_pkg.dist.as_ref().and_then(|d| d.reference.as_deref()); + + if from_dist_ref != to_dist_ref { + return ( + format_with_explicit_reference(&from_entry.version, from_dist_ref, from_source_type), + format_with_explicit_reference(&to_pkg.version, to_dist_ref, to_source_type), + ); + } + + (from_default, to_default) +} + +/// Render `pretty_version` with an explicitly chosen reference, mirroring +/// Composer's `BasePackage::getFullPrettyVersion` with `DISPLAY_SOURCE_REF` +/// or `DISPLAY_DIST_REF`: skip the dev-stability gate, just truncate sha1 +/// references and concatenate. A `None` reference falls back to the bare +/// pretty version. +fn format_with_explicit_reference( + pretty_version: &str, + reference: Option<&str>, + source_type: Option<&str>, +) -> String { + let Some(reference) = reference else { + return pretty_version.to_string(); + }; + if matches!(source_type, Some("svn")) { + return format!("{} {}", pretty_version, reference); + } + if reference.len() == 40 { + return format!("{} {}", pretty_version, &reference[..7]); + } + format!("{} {}", pretty_version, reference) +} + /// Core of `BasePackage::getFullPrettyVersion()` factored over raw /// fields so both [`LockedPackage`] and [`InstalledPackageEntry`] can share /// the rendering logic. `version` drives the dev-stability check; the result diff --git a/crates/mozart-registry/src/installer_executor/trace_recorder.rs b/crates/mozart-registry/src/installer_executor/trace_recorder.rs index 785d161..5c49160 100644 --- a/crates/mozart-registry/src/installer_executor/trace_recorder.rs +++ b/crates/mozart-registry/src/installer_executor/trace_recorder.rs @@ -70,6 +70,7 @@ impl InstallerExecutor for TraceRecorderExecutor { PackageOperation::Update { from_version, from_full_pretty, + to_full_pretty, package, } => { let action = if is_upgrade(from_version, &package.version) { @@ -79,10 +80,7 @@ impl InstallerExecutor for TraceRecorderExecutor { }; self.trace.push(format!( "{} {} ({} => {})", - action, - package.name, - from_full_pretty, - format_full_pretty_version(package) + action, package.name, from_full_pretty, to_full_pretty )); } PackageOperation::MarkAliasInstalled { alias, target } => { |
