perseus_cli/parse.rs
1#![allow(missing_docs)] // Prevents double-documenting some things
2
3use crate::PERSEUS_VERSION;
4use clap::Parser;
5
6// The documentation for the `Opts` struct will appear in the help page, hence
7// the lack of punctuation and the lowercasing in places
8
9/// The command-line interface for Perseus, a super-fast WebAssembly frontend
10/// development framework!
11#[derive(Parser, Clone)]
12#[clap(version = PERSEUS_VERSION)]
13// #[clap(setting = AppSettings::ColoredHelp)]
14pub struct Opts {
15 #[clap(subcommand)]
16 pub subcmd: Subcommand,
17 // All the following arguments are global, and can provided to any subcommand
18 /// The path to `cargo` when used for engine builds
19 #[clap(long, default_value = "cargo", global = true)]
20 pub cargo_engine_path: String,
21 /// The path to `cargo` when used for browser builds
22 #[clap(long, default_value = "cargo", global = true)]
23 pub cargo_browser_path: String,
24 /// A path to `wasm-bindgen`, if you want to use a local installation (note
25 /// that the CLI will install it locally for you by default)
26 #[clap(long, global = true)]
27 pub wasm_bindgen_path: Option<String>,
28 /// A path to `wasm-opt`, if you want to use a local installation (note that
29 /// the CLI will install it locally for you by default)
30 #[clap(long, global = true)]
31 pub wasm_opt_path: Option<String>,
32 /// The path to `rustup`
33 #[clap(long, default_value = "rustup", global = true)]
34 pub rustup_path: String,
35 /// The value of `RUSTFLAGS` when building for Wasm in release mode (this
36 /// will not impact internal target-gating)
37 #[clap(
38 long,
39 default_value = "-C opt-level=z -C codegen-units=1",
40 global = true
41 )]
42 pub wasm_release_rustflags: String,
43 /// Any arguments to `cargo` when building for the engine-side
44 #[clap(long, default_value = "", global = true)]
45 pub cargo_engine_args: String,
46 /// Any arguments to `cargo` when building for the browser-side
47 #[clap(long, default_value = "", global = true)]
48 pub cargo_browser_args: String,
49 /// Any arguments to `wasm-bindgen`
50 #[clap(long, default_value = "", global = true)]
51 pub wasm_bindgen_args: String,
52 /// Any arguments to `wasm-opt` (only run in release builds)
53 #[clap(long, default_value = "-Oz", global = true)]
54 pub wasm_opt_args: String,
55 /// The path to `git` (for downloading custom templates for `perseus new`)
56 #[clap(long, default_value = "git", global = true)]
57 pub git_path: String,
58 /// The host for the reload server (you should almost never change this)
59 #[clap(long, default_value = "localhost", global = true)]
60 pub reload_server_host: String,
61 /// The port for the reload server (you should almost never change this)
62 #[clap(long, default_value = "3100", global = true)]
63 pub reload_server_port: u16,
64 /// If this is set, commands will be run sequentially rather than in
65 /// parallel (slows down operations, but reduces memory usage)
66 #[clap(long, global = true)]
67 pub sequential: bool,
68 /// Disable automatic browser reloading
69 #[clap(long, global = true)]
70 pub no_browser_reload: bool,
71 /// A custom version of `wasm-bindgen` to use (defaults to the latest
72 /// installed version, and after that the latest available from GitHub;
73 /// update to latest can be forced with `latest`)
74 #[clap(long, global = true)]
75 pub wasm_bindgen_version: Option<String>,
76 /// A custom version of `wasm-opt` to use (defaults to the latest installed
77 /// version, and after that the latest available from GitHub; update to
78 /// latest can be forced with `latest`)
79 #[clap(long, global = true)]
80 pub wasm_opt_version: Option<String>,
81 /// Disables the system-wide tools cache in `~/.cargo/perseus_tools/` (you
82 /// should set this for CI)
83 #[clap(long, global = true)]
84 pub no_system_tools_cache: bool,
85 /// Shows the logs from building and serving your app no matter what (the
86 /// default is to only show them on a compilation/build failure); this
87 /// is intended mainly for end-to-end debugging, although the `snoop`
88 /// commands are more useful for targeted debugging
89 #[clap(long, global = true)]
90 pub verbose: bool,
91}
92
93#[derive(Parser, Clone)]
94pub enum Subcommand {
95 Build(BuildOpts),
96 ExportErrorPage(ExportErrorPageOpts),
97 Export(ExportOpts),
98 Serve(ServeOpts),
99 Test(TestOpts),
100 /// Removes build artifacts in the `dist/` directory
101 Clean,
102 Deploy(DeployOpts),
103 Tinker(TinkerOpts),
104 /// Runs one of the underlying commands that builds your app, allowing you
105 /// to see more detailed logs
106 #[clap(subcommand)]
107 Snoop(SnoopSubcommand),
108 New(NewOpts),
109 Init(InitOpts),
110 /// Checks if your app builds properly for both the engine-side and the
111 /// browser-side
112 Check(CheckOpts),
113}
114/// Builds your app
115#[derive(Parser, Clone)]
116pub struct BuildOpts {
117 /// Build for production
118 #[clap(long)]
119 pub release: bool,
120 /// Watch the files in your working directory for changes (excluding
121 /// `target/` and `dist/`)
122 #[clap(short, long)]
123 pub watch: bool,
124 /// Marks a specific file/directory to be watched (directories will be
125 /// recursively watched)
126 #[clap(long)]
127 pub custom_watch: Vec<String>,
128}
129/// Exports your app to purely static files
130#[derive(Parser, Clone)]
131pub struct ExportOpts {
132 /// Export for production
133 #[clap(long)]
134 pub release: bool,
135 /// Serve the generated static files locally
136 #[clap(short, long)]
137 pub serve: bool,
138 /// Where to host your exported app
139 #[clap(long, default_value = "127.0.0.1")]
140 pub host: String,
141 /// The port to host your exported app on
142 #[clap(long, default_value = "8080")]
143 pub port: u16,
144 /// Watch the files in your working directory for changes (excluding
145 /// `target/` and `dist/`)
146 #[clap(short, long)]
147 pub watch: bool,
148 /// Marks a specific file/directory to be watched (directories will be
149 /// recursively watched)
150 #[clap(long)]
151 pub custom_watch: Vec<String>,
152}
153/// Exports an error page for the given HTTP status code
154#[derive(Parser, Clone)]
155pub struct ExportErrorPageOpts {
156 #[clap(short, long)]
157 pub code: String,
158 #[clap(short, long)]
159 pub output: String,
160}
161/// Serves your app
162#[derive(Parser, Clone)]
163pub struct ServeOpts {
164 /// Don't run the final binary, but print its location instead as the last
165 /// line of output
166 #[clap(long)]
167 pub no_run: bool,
168 /// Only build the server, and use the results of a previous `perseus build`
169 #[clap(long)]
170 pub no_build: bool,
171 /// Build and serve for production
172 #[clap(long)]
173 pub release: bool,
174 /// Make the final binary standalone (this is used in `perseus deploy` only,
175 /// don't manually invoke it unless you have a good reason!)
176 #[clap(long)]
177 pub standalone: bool,
178 /// Watch the files in your working directory for changes (excluding
179 /// `target/` and `dist/`)
180 #[clap(short, long)]
181 pub watch: bool,
182 /// Marks a specific file/directory to be watched (directories will be
183 /// recursively watched)
184 #[clap(long)]
185 pub custom_watch: Vec<String>,
186 /// Where to host your exported app
187 #[clap(long, default_value = "127.0.0.1")]
188 pub host: String,
189 /// The port to host your exported app on
190 #[clap(long, default_value = "8080")]
191 pub port: u16,
192}
193/// Serves your app as `perseus serve` does, but puts it in testing mode
194#[derive(Parser, Clone)]
195pub struct TestOpts {
196 /// Only build the testing server, and use the results of a previous
197 /// `perseus build`
198 #[clap(long)]
199 pub no_build: bool,
200 /// Show the browser window when testing (by default, the browser is used in
201 /// 'headless' mode); this can be useful for debugging failing tests in
202 /// some cases
203 #[clap(long)]
204 pub show_browser: bool,
205 /// Watch the files in your working directory for changes (excluding
206 /// `target/` and `dist/`)
207 #[clap(short, long)]
208 pub watch: bool,
209 /// Marks a specific file/directory to be watched (directories will be
210 /// recursively watched)
211 #[clap(long)]
212 pub custom_watch: Vec<String>,
213 /// Where to host your exported app
214 #[clap(long, default_value = "127.0.0.1")]
215 pub host: String,
216 /// The port to host your exported app on
217 #[clap(long, default_value = "8080")]
218 pub port: u16,
219}
220/// Packages your app for deployment
221#[derive(Parser, Clone)]
222pub struct DeployOpts {
223 /// Change the output from `pkg/` to somewhere else
224 #[clap(short, long, default_value = "pkg")]
225 pub output: String,
226 /// Export your app to purely static files (see `export`)
227 #[clap(short, long)]
228 pub export_static: bool,
229 /// Don't minify JavaScript (this will decrease performance)
230 #[clap(long)]
231 pub no_minify_js: bool,
232}
233/// Runs the `tinker` action of plugins, which lets them modify the Perseus
234/// engine
235#[derive(Parser, Clone)]
236pub struct TinkerOpts {
237 /// Don't remove and recreate the `dist/` directory
238 #[clap(long)]
239 pub no_clean: bool,
240}
241/// Creates a new Perseus project in a directory of the given name, which will
242/// be created in the current path
243#[derive(Parser, Clone)]
244pub struct NewOpts {
245 /// The name of the new project, which will also be used for the directory
246 #[clap(value_parser)]
247 pub name: String,
248 /// An optional custom URL to a Git repository to be used as a custom
249 /// template (note that custom templates will not respect your project's
250 /// name). This can be followed with `@branch` to fetch from `branch`
251 /// rather than the default
252 #[clap(short, long)]
253 pub template: Option<String>,
254 /// The path to a custom directory to create (if this is not provided, the
255 /// project name will be used by default)
256 #[clap(long)]
257 pub dir: Option<String>,
258}
259/// Initializes a new Perseus project in the current directory
260#[derive(Parser, Clone)]
261pub struct InitOpts {
262 /// The name of the new project
263 #[clap(value_parser)]
264 pub name: String,
265}
266
267#[derive(Parser, Clone)]
268pub enum SnoopSubcommand {
269 /// Snoops on the static generation process (this will let you see `dbg!`
270 /// calls and the like)
271 Build {
272 /// Watch the files in your working directory for changes (excluding
273 /// `target/` and `dist/`)
274 #[clap(short, long)]
275 watch: bool,
276 /// Marks a specific file/directory to be watched (directories will be
277 /// recursively watched)
278 #[clap(long)]
279 custom_watch: Vec<String>,
280 },
281 /// Snoops on the Wasm building process (mostly for debugging errors)
282 WasmBuild {
283 /// Watch the files in your working directory for changes (excluding
284 /// `target/` and `dist/`)
285 #[clap(short, long)]
286 watch: bool,
287 /// Marks a specific file/directory to be watched (directories will be
288 /// recursively watched)
289 #[clap(long)]
290 custom_watch: Vec<String>,
291 },
292 /// Snoops on the server process (run `perseus build` before this)
293 Serve(SnoopServeOpts),
294}
295
296#[derive(Parser, Clone)]
297pub struct SnoopServeOpts {
298 /// Where to host your exported app
299 #[clap(long, default_value = "127.0.0.1")]
300 pub host: String,
301 /// The port to host your exported app on
302 #[clap(long, default_value = "8080")]
303 pub port: u16,
304 /// Watch the files in your working directory for changes (excluding
305 /// `target/` and `dist/`)
306 #[clap(short, long)]
307 pub watch: bool,
308 /// Marks a specific file/directory to be watched (directories will be
309 /// recursively watched)
310 #[clap(long)]
311 pub custom_watch: Vec<String>,
312}
313
314#[derive(Parser, Clone)]
315pub struct CheckOpts {
316 /// Watch the files in your working directory for changes (excluding
317 /// `target/` and `dist/`)
318 #[clap(short, long)]
319 pub watch: bool,
320 /// Marks a specific file/directory to be watched (directories will be
321 /// recursively watched)
322 #[clap(long)]
323 pub custom_watch: Vec<String>,
324 /// Make sure the app's page generation works properly (this will take much
325 /// longer, but almost guarantees that your app will actually build);
326 /// use this to catch errors in build state and the like
327 #[clap(short, long)]
328 pub generate: bool,
329}