aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart/src/commands/prohibits.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-21 14:11:18 +0900
committernsfisis <nsfisis@gmail.com>2026-02-21 14:11:18 +0900
commit294bd3dd425a374eda13a52b925a2cd0c4db7f0a (patch)
treef63a008b88113ac2548affbd0a662879f14b1ed7 /crates/mozart/src/commands/prohibits.rs
parent48e88e9e204a38d1e31483412003f1492fa8fdcf (diff)
downloadphp-mozart-294bd3dd425a374eda13a52b925a2cd0c4db7f0a.tar.gz
php-mozart-294bd3dd425a374eda13a52b925a2cd0c4db7f0a.tar.zst
php-mozart-294bd3dd425a374eda13a52b925a2cd0c4db7f0a.zip
feat(depends): implement depends and prohibits commands with shared dependency logic
Add the `depends` (why) and `prohibits` (why-not) commands that query the dependency graph to answer "which packages require X?" and "which packages prevent version Y of X from being installed?" respectively. Introduces the shared `dependency` module with package loading from lock file or installed.json, forward/inverted dependency graph walking, recursive traversal with cycle detection, and table/tree output formatters. Adds `conflict` field to LockedPackage for conflict-based prohibition detection, updating all struct literals across install, remove, require, and update test helpers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart/src/commands/prohibits.rs')
-rw-r--r--crates/mozart/src/commands/prohibits.rs53
1 files changed, 51 insertions, 2 deletions
diff --git a/crates/mozart/src/commands/prohibits.rs b/crates/mozart/src/commands/prohibits.rs
index 8f87644..d30e57f 100644
--- a/crates/mozart/src/commands/prohibits.rs
+++ b/crates/mozart/src/commands/prohibits.rs
@@ -1,4 +1,5 @@
use clap::Args;
+use std::path::PathBuf;
#[derive(Args)]
pub struct ProhibitsArgs {
@@ -21,6 +22,54 @@ pub struct ProhibitsArgs {
pub locked: bool,
}
-pub fn execute(_args: &ProhibitsArgs, _cli: &super::Cli) -> anyhow::Result<()> {
- todo!()
+pub fn execute(args: &ProhibitsArgs, cli: &super::Cli) -> anyhow::Result<()> {
+ let working_dir = match &cli.working_dir {
+ Some(dir) => PathBuf::from(dir),
+ None => std::env::current_dir()?,
+ };
+
+ let packages = super::dependency::load_packages(&working_dir, args.locked)?;
+
+ if packages.is_empty() {
+ println!(
+ "{}",
+ crate::console::info("No packages found. Run `mozart install` first.")
+ );
+ return Ok(());
+ }
+
+ // Parse the version constraint the user is asking about
+ let version_constraint = crate::constraint::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(
+ &packages,
+ &needles,
+ Some(&version_constraint),
+ true, // inverted = prohibits mode
+ recursive,
+ )?;
+
+ if results.is_empty() {
+ println!(
+ "{}",
+ crate::console::info(&format!(
+ "{} {} can be installed.",
+ args.package, args.version
+ ))
+ );
+ return Ok(());
+ }
+
+ if args.tree {
+ super::dependency::print_tree(&results, 0);
+ } else {
+ super::dependency::print_table(&results);
+ }
+
+ Ok(())
}