aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-23 01:34:16 +0900
committernsfisis <nsfisis@gmail.com>2026-02-23 01:59:59 +0900
commitbb132ac9201b958f9f6b916e701d9bfb323166b9 (patch)
tree57bf5ee693ec2cf81aa0abea918f3d4ce1951bc7 /crates/mozart
parent612af0aaacda404b8e177d0c1a6d3bd937e8d39a (diff)
downloadphp-mozart-bb132ac9201b958f9f6b916e701d9bfb323166b9.tar.gz
php-mozart-bb132ac9201b958f9f6b916e701d9bfb323166b9.tar.zst
php-mozart-bb132ac9201b958f9f6b916e701d9bfb323166b9.zip
fix(prohibits): align behavior with Composer's why-not command
- Use installed packages by default instead of always preferring lock file - Error on unknown needle package instead of misleading "can be installed" - Return exit code 1 when prohibitors are found - Deduplicate output rows in dependency table - Print resolution hint suggesting require/update --dry-run Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart')
-rw-r--r--crates/mozart/src/commands/dependency.rs8
-rw-r--r--crates/mozart/src/commands/prohibits.rs48
2 files changed, 54 insertions, 2 deletions
diff --git a/crates/mozart/src/commands/dependency.rs b/crates/mozart/src/commands/dependency.rs
index f2856d9..0184f53 100644
--- a/crates/mozart/src/commands/dependency.rs
+++ b/crates/mozart/src/commands/dependency.rs
@@ -542,7 +542,15 @@ pub fn print_table(results: &[DependencyResult]) {
.max()
.unwrap_or(0);
+ let mut seen: HashSet<String> = HashSet::new();
for r in results {
+ let key = format!(
+ "{}|{}|{}|{}",
+ r.package_name, r.package_version, r.link_description, r.link_constraint
+ );
+ if !seen.insert(key) {
+ continue;
+ }
println!(
"{:<name_w$} {:<ver_w$} {:<desc_w$} {}",
mozart_core::console::info(&r.package_name),
diff --git a/crates/mozart/src/commands/prohibits.rs b/crates/mozart/src/commands/prohibits.rs
index 55a8175..f3b7916 100644
--- a/crates/mozart/src/commands/prohibits.rs
+++ b/crates/mozart/src/commands/prohibits.rs
@@ -44,12 +44,22 @@ pub async fn execute(
));
}
+ let target = args.package.to_lowercase();
+
+ // Fix #2: Verify the target package is known
+ let target_known = packages.iter().any(|p| p.name.to_lowercase() == target);
+ if !target_known {
+ anyhow::bail!(
+ "Could not find package \"{}\" in your project",
+ args.package
+ );
+ }
+
// Parse the version constraint the user is asking about
let version_constraint = mozart_semver::VersionConstraint::parse(&args.version)
.map_err(|e| anyhow::anyhow!("Invalid version constraint '{}': {}", args.version, e))?;
let recursive = args.tree || args.recursive;
- let target = args.package.to_lowercase();
let needles = vec![target];
let results = super::dependency::get_dependents(
@@ -78,5 +88,39 @@ pub async fn execute(
super::dependency::print_table(&results);
}
- Ok(())
+ // Fix #5: Print resolution hint message
+ // Determine the appropriate composer command based on whether the needle
+ // is in root's require or require-dev.
+ let needle_lower = args.package.to_lowercase();
+ let composer_command = packages
+ .iter()
+ .find(|p| p.is_root)
+ .map(|root| {
+ if root
+ .require
+ .keys()
+ .any(|k| k.to_lowercase() == needle_lower)
+ {
+ "require"
+ } else if root
+ .require_dev
+ .keys()
+ .any(|k| k.to_lowercase() == needle_lower)
+ {
+ "require --dev"
+ } else {
+ "update"
+ }
+ })
+ .unwrap_or("update");
+
+ eprintln!(
+ "Not finding what you were looking for? Try calling `composer {} \"{}:{}\" --dry-run` to get another view on the problem.",
+ composer_command, args.package, args.version
+ );
+
+ // Fix #3: Return exit code 1 when prohibitors are found
+ Err(mozart_core::exit_code::bail_silent(
+ mozart_core::exit_code::GENERAL_ERROR,
+ ))
}