1 //! The `wasmtime` command line tool.
2 //!
3 //! Primarily used to run WebAssembly modules.
4 //! See `wasmtime --help` for usage.
5
6 use clap::Parser;
7 use wasmtime::Result;
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.
version() -> &'static str51 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 /// Inspect `*.cwasm` files output from Wasmtime
90 #[cfg(feature = "objdump")]
91 Objdump(wasmtime_cli::commands::ObjdumpCommand),
92
93 #[cfg(feature = "wizer")]
94 Wizer(wasmtime_cli::commands::WizerCommand),
95 }
96
97 impl Wasmtime {
98 /// Executes the command.
execute(self) -> Result<()>99 pub fn execute(self) -> Result<()> {
100 #[cfg(feature = "run")]
101 let subcommand = self.subcommand.unwrap_or(Subcommand::Run(self.run));
102 #[cfg(not(feature = "run"))]
103 let subcommand = self.subcommand;
104
105 match subcommand {
106 #[cfg(feature = "run")]
107 Subcommand::Run(c) => c.execute(),
108
109 #[cfg(feature = "cache")]
110 Subcommand::Config(c) => c.execute(),
111
112 #[cfg(feature = "compile")]
113 Subcommand::Compile(c) => c.execute(),
114
115 #[cfg(feature = "explore")]
116 Subcommand::Explore(c) => c.execute(),
117
118 #[cfg(feature = "serve")]
119 Subcommand::Serve(c) => c.execute(),
120
121 #[cfg(feature = "cranelift")]
122 Subcommand::Settings(c) => c.execute(),
123
124 #[cfg(feature = "wast")]
125 Subcommand::Wast(c) => c.execute(),
126
127 #[cfg(feature = "completion")]
128 Subcommand::Completion(c) => c.execute(),
129
130 #[cfg(feature = "objdump")]
131 Subcommand::Objdump(c) => c.execute(),
132
133 #[cfg(feature = "wizer")]
134 Subcommand::Wizer(c) => c.execute(),
135 }
136 }
137 }
138
139 /// Generate shell completion scripts for this CLI.
140 ///
141 /// Shells have different paths for their completion scripts. Please refer to
142 /// their documentation. For example, to generate completions for the fish
143 /// shell, run the following command below:
144 ///
145 /// wasmtime completion fish > ~/.config/fish/completions/wasmtime.fish
146 ///
147 /// For a shell like zsh you can add this to your .zshrc or startup scripts:
148 ///
149 /// eval "$(wasmtime completion zsh)"
150 #[derive(Parser)]
151 #[cfg(feature = "completion")]
152 pub struct CompletionCommand {
153 /// The shell to generate completions for.
154 shell: clap_complete::Shell,
155 }
156
157 #[cfg(feature = "completion")]
158 impl CompletionCommand {
execute(&self) -> Result<()>159 pub fn execute(&self) -> Result<()> {
160 use clap::CommandFactory;
161
162 let mut cmd = Wasmtime::command();
163 let cli_name = cmd.get_name().to_owned();
164
165 clap_complete::generate(self.shell, &mut cmd, cli_name, &mut std::io::stdout());
166 Ok(())
167 }
168 }
169
170 #[allow(unreachable_code, reason = "empty enum with all features disabled")]
main() -> Result<()>171 fn main() -> Result<()> {
172 return Wasmtime::parse().execute();
173 }
174
175 #[test]
verify_cli()176 fn verify_cli() {
177 use clap::CommandFactory;
178 Wasmtime::command().debug_assert()
179 }
180