vx_cli/commands/
mod.rs

1//! CLI command implementations
2
3use crate::cli::{Cli, Commands};
4use crate::ui::UI;
5use vx_core::PluginRegistry;
6
7pub mod config;
8pub mod execute;
9pub mod fetch;
10pub mod install;
11pub mod list;
12pub mod plugin;
13pub mod remove;
14pub mod stats;
15pub mod switch;
16pub mod update;
17pub mod use_cmd;
18pub mod venv_cmd;
19pub mod version;
20pub mod where_cmd;
21
22#[cfg(test)]
23pub mod tests;
24
25pub struct CommandHandler;
26
27impl CommandHandler {
28    pub async fn handle(cli: Cli, registry: &PluginRegistry) -> anyhow::Result<()> {
29        // Set verbose mode
30        UI::set_verbose(cli.verbose);
31
32        match cli.command {
33            Some(Commands::Version) => version::handle().await.map_err(Into::into),
34
35            Some(Commands::List { tool, status }) => {
36                list::handle(registry, tool.as_deref(), status)
37                    .await
38                    .map_err(Into::into)
39            }
40
41            Some(Commands::Install {
42                tool,
43                version,
44                force,
45            }) => install::handle(registry, &tool, version.as_deref(), force)
46                .await
47                .map_err(Into::into),
48
49            Some(Commands::Update { tool, apply: _ }) => {
50                update::handle(registry, tool.as_deref(), false)
51                    .await
52                    .map_err(Into::into)
53            }
54
55            Some(Commands::Remove {
56                tool,
57                version,
58                force,
59            }) => remove::handle(registry, &tool, version.as_deref(), force)
60                .await
61                .map_err(Into::into),
62
63            Some(Commands::Where { tool, all }) => where_cmd::handle(registry, &tool, all)
64                .await
65                .map_err(Into::into),
66
67            Some(Commands::Fetch {
68                tool,
69                latest,
70                prerelease,
71                detailed,
72                interactive,
73            }) => fetch::handle(registry, &tool, latest, detailed, interactive, prerelease)
74                .await
75                .map_err(Into::into),
76
77            Some(Commands::Use { tool_version }) => use_cmd::handle(registry, &tool_version)
78                .await
79                .map_err(Into::into),
80
81            Some(Commands::Switch {
82                tool_version,
83                global,
84            }) => switch::handle(registry, &tool_version, global)
85                .await
86                .map_err(Into::into),
87
88            Some(Commands::Config) => config::handle().await.map_err(Into::into),
89
90            Some(Commands::Init) => config::handle_init(vec![], None).await.map_err(Into::into),
91
92            Some(Commands::Cleanup) => stats::handle_cleanup(false, false, false)
93                .await
94                .map_err(Into::into),
95
96            Some(Commands::Stats) => stats::handle(registry).await.map_err(Into::into),
97
98            Some(Commands::Plugin { command }) => {
99                plugin::handle(registry, command).await.map_err(Into::into)
100            }
101
102            Some(Commands::Venv { command }) => venv_cmd::handle(command).await.map_err(Into::into),
103
104            None => {
105                // Handle tool execution
106                if cli.args.is_empty() {
107                    UI::error("No tool specified");
108                    UI::hint("Usage: vx <tool> [args...]");
109                    UI::hint("Example: vx uv pip install requests");
110                    UI::hint("Run 'vx list --all' to see supported tools");
111                    std::process::exit(1);
112                }
113
114                let tool_name = &cli.args[0];
115                let tool_args = &cli.args[1..];
116
117                // Use the executor to run the tool
118                let exit_code =
119                    execute::execute_tool(registry, tool_name, tool_args, cli.use_system_path)
120                        .await
121                        .map_err(anyhow::Error::from)?;
122                if exit_code != 0 {
123                    std::process::exit(exit_code);
124                }
125                Ok(())
126            }
127        }
128    }
129}