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