From d0d05f14a4d1b36f517077ffdaa4b335c812190f Mon Sep 17 00:00:00 2001 From: nsfisis Date: Fri, 8 May 2026 21:59:08 +0900 Subject: fix(suggests): align with Composer's SuggestsCommand pipeline Port `Composer\Installer\SuggestedPackagesReporter` to `mozart_core::installer` (modes, add_package, add_suggestions_from_package, output, output_minimalistic, escape_output) and slim `commands/suggests.rs` to mirror `SuggestsCommand::execute`. Defines `HasSuggests`, `InstalledRepoLite`, `RootInfo` as the minimal stand-ins for Composer's `PackageInterface` / `InstalledRepository` / `onlyDependentsOf`. Also fixes a latent bug where `provide`/`replace` virtuals were read from `extra_fields` (always empty after a serde round-trip into LockedPackage's typed fields) and moves the "additional suggestions ... --all" hint to fire after the rendered sections, matching Composer's order. --- crates/mozart-registry/src/installed.rs | 19 +++++++++++++++++++ crates/mozart-registry/src/lockfile.rs | 14 ++++++++++++++ 2 files changed, 33 insertions(+) (limited to 'crates/mozart-registry/src') diff --git a/crates/mozart-registry/src/installed.rs b/crates/mozart-registry/src/installed.rs index da02c6a..108b844 100644 --- a/crates/mozart-registry/src/installed.rs +++ b/crates/mozart-registry/src/installed.rs @@ -1,3 +1,4 @@ +use mozart_core::installer::HasSuggests; use mozart_core::package::to_json_pretty; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; @@ -58,6 +59,24 @@ pub struct InstalledPackageEntry { pub extra_fields: BTreeMap, } +impl HasSuggests for InstalledPackageEntry { + fn pretty_name(&self) -> &str { + &self.name + } + + fn suggests(&self) -> Vec<(String, String)> { + let Some(val) = self.extra_fields.get("suggest") else { + return Vec::new(); + }; + let Some(obj) = val.as_object() else { + return Vec::new(); + }; + obj.iter() + .filter_map(|(target, reason)| reason.as_str().map(|r| (target.clone(), r.to_string()))) + .collect() + } +} + impl Default for InstalledPackages { fn default() -> Self { Self::new() diff --git a/crates/mozart-registry/src/lockfile.rs b/crates/mozart-registry/src/lockfile.rs index dd73020..fd6b5e3 100644 --- a/crates/mozart-registry/src/lockfile.rs +++ b/crates/mozart-registry/src/lockfile.rs @@ -3,6 +3,7 @@ use crate::repository::RepositorySet; use crate::resolver::ResolvedPackage; use indexmap::IndexMap; use indexmap::IndexSet; +use mozart_core::installer::HasSuggests; use mozart_core::package::{RawPackageData, to_json_pretty}; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, VecDeque}; @@ -134,6 +135,19 @@ pub struct LockedPackage { pub extra_fields: BTreeMap, } +impl HasSuggests for LockedPackage { + fn pretty_name(&self) -> &str { + &self.name + } + + fn suggests(&self) -> Vec<(String, String)> { + self.suggest + .as_ref() + .map(|m| m.iter().map(|(k, v)| (k.clone(), v.clone())).collect()) + .unwrap_or_default() + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct LockedSource { #[serde(rename = "type")] -- cgit v1.3.1