diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-02-21 14:11:18 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-02-21 14:11:18 +0900 |
| commit | 294bd3dd425a374eda13a52b925a2cd0c4db7f0a (patch) | |
| tree | f63a008b88113ac2548affbd0a662879f14b1ed7 /crates/mozart/src/commands/prohibits.rs | |
| parent | 48e88e9e204a38d1e31483412003f1492fa8fdcf (diff) | |
| download | php-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.rs | 53 |
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(()) } |
