Skip to main content

zoi_cli/cmd/uninstall/
args.rs

1use clap::Args;
2use zoi_common::Runnable;
3
4use crate::cli::InstallScope;
5use crate::pkg::plugin::PluginManager;
6
7/// Arguments for the `uninstall` command.
8#[derive(Args, Debug, Clone)]
9pub struct UninstallArgs {
10    /// The package identifier(s).
11    #[arg(
12        value_name = "INST_PACKAGES",
13        required = true,
14        help = "Package identifier (e.g. @repo/name, path, or URL)"
15    )]
16    pub packages: Vec<String>,
17
18    /// The scope to uninstall the package from
19    #[arg(long, value_enum, conflicts_with_all = &["local", "global"])]
20    pub scope: Option<InstallScope>,
21
22    /// Uninstall packages from the current project (alias for --scope=project)
23    #[arg(long, conflicts_with = "global")]
24    pub local: bool,
25
26    /// Uninstall packages globally for the current user (alias for
27    /// --scope=user)
28    #[arg(long)]
29    pub global: bool,
30
31    /// Remove the package from the project's zoi.yaml
32    #[arg(long)]
33    pub save: bool,
34
35    /// Recursively remove dependencies that are no longer needed
36    #[arg(short, long)]
37    pub recursive: bool,
38
39    /// Do not actually uninstall, just show what would be done
40    #[arg(long)]
41    pub dry_run: bool,
42
43    /// Explain uninstall decisions (dependency impact and safety blocks)
44    #[arg(long)]
45    pub explain: bool,
46
47    /// Emit machine-readable uninstall plan JSON
48    #[arg(long)]
49    pub plan_json: bool
50}
51
52impl Runnable for UninstallArgs {
53    fn run(&self, yes: bool) -> anyhow::Result<()> {
54        let plugin_manager = PluginManager::new()?;
55        super::run(
56            &self.packages,
57            self.scope,
58            self.local,
59            self.global,
60            self.save,
61            yes,
62            self.recursive,
63            Some(&plugin_manager),
64            self.explain,
65            self.plan_json,
66            self.dry_run
67        )
68    }
69}