1use 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 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 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 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}