xref: /wasmtime-44.0.1/src/bin/wasmtime.rs (revision 9fc41bae)
1 //! The `wasmtime` command line tool.
2 //!
3 //! Primarily used to run WebAssembly modules.
4 //! See `wasmtime --help` for usage.
5 
6 use anyhow::Result;
7 use clap::Parser;
8 
9 /// Wasmtime WebAssembly Runtime
10 #[derive(Parser)]
11 #[command(
12     name = "wasmtime",
13     version = version(),
14     after_help = "If a subcommand is not provided, the `run` subcommand will be used.\n\
15                   \n\
16                   Usage examples:\n\
17                   \n\
18                   Running a WebAssembly module with a start function:\n\
19                   \n  \
20                   wasmtime example.wasm
21                   \n\
22                   Passing command line arguments to a WebAssembly module:\n\
23                   \n  \
24                   wasmtime example.wasm arg1 arg2 arg3\n\
25                   \n\
26                   Invoking a specific function (e.g. `add`) in a WebAssembly module:\n\
27                   \n  \
28                   wasmtime --invoke add example.wasm 1 2\n",
29 
30     // This option enables the pattern below where we ask clap to parse twice
31     // sorta: once where it's trying to find a subcommand and once assuming
32     // a subcommand doesn't get passed. Clap should then, apparently,
33     // fill in the `subcommand` if found and otherwise fill in the
34     // `RunCommand`.
35     args_conflicts_with_subcommands = true
36 )]
37 struct Wasmtime {
38     #[cfg(not(feature = "run"))]
39     #[command(subcommand)]
40     subcommand: Subcommand,
41 
42     #[cfg(feature = "run")]
43     #[command(subcommand)]
44     subcommand: Option<Subcommand>,
45     #[command(flatten)]
46     #[cfg(feature = "run")]
47     run: wasmtime_cli::commands::RunCommand,
48 }
49 
50 /// If WASMTIME_VERSION_INFO is set, use it, otherwise use CARGO_PKG_VERSION.
51 fn version() -> &'static str {
52     option_env!("WASMTIME_VERSION_INFO").unwrap_or(env!("CARGO_PKG_VERSION"))
53 }
54 
55 #[derive(Parser)]
56 enum Subcommand {
57     /// Runs a WebAssembly module
58     #[cfg(feature = "run")]
59     Run(wasmtime_cli::commands::RunCommand),
60 
61     /// Controls Wasmtime configuration settings
62     #[cfg(feature = "cache")]
63     Config(wasmtime_cli::commands::ConfigCommand),
64 
65     /// Compiles a WebAssembly module.
66     #[cfg(feature = "compile")]
67     Compile(wasmtime_cli::commands::CompileCommand),
68 
69     /// Explore the compilation of a WebAssembly module to native code.
70     #[cfg(feature = "explore")]
71     Explore(wasmtime_cli::commands::ExploreCommand),
72 
73     /// Serves requests from a wasi-http proxy component.
74     #[cfg(feature = "serve")]
75     Serve(wasmtime_cli::commands::ServeCommand),
76 
77     /// Displays available Cranelift settings for a target.
78     #[cfg(feature = "cranelift")]
79     Settings(wasmtime_cli::commands::SettingsCommand),
80 
81     /// Runs a WebAssembly test script file
82     #[cfg(feature = "wast")]
83     Wast(wasmtime_cli::commands::WastCommand),
84 
85     /// Generate shell completions for the `wasmtime` CLI
86     #[cfg(feature = "completion")]
87     Completion(CompletionCommand),
88 }
89 
90 impl Wasmtime {
91     /// Executes the command.
92     pub fn execute(self) -> Result<()> {
93         #[cfg(feature = "run")]
94         let subcommand = self.subcommand.unwrap_or(Subcommand::Run(self.run));
95         #[cfg(not(feature = "run"))]
96         let subcommand = self.subcommand;
97 
98         match subcommand {
99             #[cfg(feature = "run")]
100             Subcommand::Run(c) => c.execute(),
101 
102             #[cfg(feature = "cache")]
103             Subcommand::Config(c) => c.execute(),
104 
105             #[cfg(feature = "compile")]
106             Subcommand::Compile(c) => c.execute(),
107 
108             #[cfg(feature = "explore")]
109             Subcommand::Explore(c) => c.execute(),
110 
111             #[cfg(feature = "serve")]
112             Subcommand::Serve(c) => c.execute(),
113 
114             #[cfg(feature = "cranelift")]
115             Subcommand::Settings(c) => c.execute(),
116 
117             #[cfg(feature = "wast")]
118             Subcommand::Wast(c) => c.execute(),
119 
120             #[cfg(feature = "completion")]
121             Subcommand::Completion(c) => c.execute(),
122         }
123     }
124 }
125 
126 /// Generate shell completion scripts for this CLI.
127 ///
128 /// Shells have different paths for their completion scripts. Please refer to
129 /// their documentation. For example, to generate completions for the fish
130 /// shell, run the following command below:
131 ///
132 ///     wasmtime completion fish > ~/.config/fish/completions/wasmtime.fish
133 ///
134 /// For a shell like zsh you can add this to your .zshrc or startup scripts:
135 ///
136 ///     eval "$(wasmtime completion zsh)"
137 #[derive(Parser)]
138 #[cfg(feature = "completion")]
139 pub struct CompletionCommand {
140     /// The shell to generate completions for.
141     shell: clap_complete::Shell,
142 }
143 
144 #[cfg(feature = "completion")]
145 impl CompletionCommand {
146     pub fn execute(&self) -> Result<()> {
147         use clap::CommandFactory;
148 
149         let mut cmd = Wasmtime::command();
150         let cli_name = cmd.get_name().to_owned();
151 
152         clap_complete::generate(self.shell, &mut cmd, cli_name, &mut std::io::stdout());
153         Ok(())
154     }
155 }
156 
157 fn main() -> Result<()> {
158     return Wasmtime::parse().execute();
159 }
160 
161 #[test]
162 fn verify_cli() {
163     use clap::CommandFactory;
164     Wasmtime::command().debug_assert()
165 }
166