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 #[cfg(feature = "wizer")] 94 Wizer(wasmtime_cli::commands::WizerCommand), 95 } 96 97 impl Wasmtime { 98 /// Executes the command. 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 { 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")] 171 fn main() -> Result<()> { 172 return Wasmtime::parse().execute(); 173 } 174 175 #[test] 176 fn verify_cli() { 177 use clap::CommandFactory; 178 Wasmtime::command().debug_assert() 179 } 180