aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart/src/commands
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-22 21:36:27 +0900
committernsfisis <nsfisis@gmail.com>2026-02-22 21:42:00 +0900
commit631ac98acac352955d3ffc2cb9e31b83921c42eb (patch)
tree000d8904a81cf49db066f0cfb3a9829c237c2039 /crates/mozart/src/commands
parent0496eccfb25e53c3f4cd3869b2f7bcc111927dcb (diff)
downloadphp-mozart-631ac98acac352955d3ffc2cb9e31b83921c42eb.tar.gz
php-mozart-631ac98acac352955d3ffc2cb9e31b83921c42eb.tar.zst
php-mozart-631ac98acac352955d3ffc2cb9e31b83921c42eb.zip
fix(suggests): align output formatting and root package filtering with Composer
Add blank lines between groups, use 78-dash separator in dual mode, sanitize reason strings by replacing newlines and stripping control characters, and include root package name in direct-deps filter so its suggestions are correctly shown by default. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart/src/commands')
-rw-r--r--crates/mozart/src/commands/suggests.rs30
1 files changed, 25 insertions, 5 deletions
diff --git a/crates/mozart/src/commands/suggests.rs b/crates/mozart/src/commands/suggests.rs
index 0268fe8..9150dd5 100644
--- a/crates/mozart/src/commands/suggests.rs
+++ b/crates/mozart/src/commands/suggests.rs
@@ -143,7 +143,7 @@ pub async fn execute(
render_by_suggestion(&filtered);
} else if args.by_package && args.by_suggestion {
render_by_package(&filtered);
- println!("---");
+ println!("{}", "-".repeat(78));
render_by_suggestion(&filtered);
} else {
// Default: by-package
@@ -379,12 +379,28 @@ fn compute_direct_deps(working_dir: &Path) -> anyhow::Result<HashSet<String>> {
}
let root = mozart_core::package::read_from_file(&composer_json_path)?;
let mut deps: HashSet<String> = HashSet::new();
+ // Include the root package itself so its suggestions are shown
+ if !root.name.is_empty() {
+ deps.insert(root.name.to_lowercase());
+ }
for name in root.require.keys().chain(root.require_dev.keys()) {
deps.insert(name.to_lowercase());
}
Ok(deps)
}
+// ─── Sanitization ────────────────────────────────────────────────────────────
+
+/// Sanitize a suggestion reason string for safe terminal output.
+/// Replaces newlines with spaces and strips control characters.
+fn sanitize_reason(reason: &str) -> String {
+ reason
+ .replace(['\n', '\r'], " ")
+ .chars()
+ .filter(|c| !c.is_control() || *c == ' ')
+ .collect()
+}
+
// ─── Rendering ───────────────────────────────────────────────────────────────
fn render_list(suggestions: &[&Suggestion]) {
@@ -405,12 +421,14 @@ fn render_by_package(suggestions: &[&Suggestion]) {
for (source, items) in &grouped {
println!("{} suggests:", source);
for s in items {
- if s.reason.is_empty() {
+ let reason = sanitize_reason(&s.reason);
+ if reason.is_empty() {
println!(" - {}", s.target);
} else {
- println!(" - {}: {}", s.target, s.reason);
+ println!(" - {}: {}", s.target, reason);
}
}
+ println!();
}
}
@@ -423,12 +441,14 @@ fn render_by_suggestion(suggestions: &[&Suggestion]) {
for (target, items) in &grouped {
println!("{} is suggested by:", target);
for s in items {
- if s.reason.is_empty() {
+ let reason = sanitize_reason(&s.reason);
+ if reason.is_empty() {
println!(" - {}", s.source);
} else {
- println!(" - {}: {}", s.source, s.reason);
+ println!(" - {}: {}", s.source, reason);
}
}
+ println!();
}
}