aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart-registry/src/installer_executor
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-03 12:15:02 +0900
committernsfisis <nsfisis@gmail.com>2026-05-03 12:15:02 +0900
commit7badb54195131da9c3561c351138c0ba083e38e4 (patch)
tree0498ab8c3bfcf90e01fcecf451a10ad3844514ff /crates/mozart-registry/src/installer_executor
parentdffb6244ebb432477b83631d68584bbc7186dd94 (diff)
downloadphp-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/src/installer_executor')
-rw-r--r--crates/mozart-registry/src/installer_executor/mod.rs87
-rw-r--r--crates/mozart-registry/src/installer_executor/trace_recorder.rs6
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 } => {