Skip to main content

cargo_leptos/config/
cli.rs

1use crate::command::NewCommand;
2use camino::Utf8PathBuf;
3use clap::{Parser, Subcommand, ValueEnum};
4use clap_complete::Shell;
5
6#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
7pub enum Log {
8    /// WASM build (wasm, wasm-opt, walrus)
9    Wasm,
10    /// Internal reload and csr server (hyper, axum)
11    Server,
12}
13
14#[derive(Debug, Clone, Parser, PartialEq, Default)]
15pub struct Opts {
16    /// Build artifacts in release mode, with optimizations.
17    #[arg(short, long)]
18    pub release: bool,
19
20    /// Precompress static assets with gzip and brotli. Applies to release builds only.
21    #[arg(short = 'P', long)]
22    pub precompress: bool,
23
24    /// Turn on partial hot-reloading. Requires rust nightly [beta]
25    #[arg(long)]
26    pub hot_reload: bool,
27
28    /// Which project to use, from a list of projects defined in a workspace
29    #[arg(short, long)]
30    pub project: Option<String>,
31
32    /// The features to use when compiling all targets
33    #[arg(long)]
34    pub features: Vec<String>,
35
36    /// The features to use when compiling the lib target
37    #[arg(long)]
38    pub lib_features: Vec<String>,
39
40    /// The cargo flags to pass to cargo when compiling the lib target
41    #[arg(long)]
42    pub lib_cargo_args: Option<Vec<String>>,
43
44    /// The features to use when compiling the bin target
45    #[arg(long)]
46    pub bin_features: Vec<String>,
47
48    /// The cargo flags to pass to cargo when compiling the bin target
49    #[arg(long)]
50    pub bin_cargo_args: Option<Vec<String>>,
51
52    /// Include debug information in Wasm output. Includes source maps and DWARF debug info.
53    #[arg(long)]
54    pub wasm_debug: bool,
55
56    /// Verbosity (none: info, errors & warnings, -v: verbose, -vv: very verbose).
57    #[arg(short, action = clap::ArgAction::Count)]
58    pub verbose: u8,
59
60    /// Clear the terminal before rebuilding
61    #[arg(long, short)]
62    pub clear: bool,
63
64    /// Minify javascript assets with swc. Applies to release builds only.
65    #[arg(long, default_value = "true", value_parser=clap::builder::BoolishValueParser::new(), action = clap::ArgAction::Set)]
66    pub js_minify: bool,
67
68    /// Split WASM binary based on #[lazy] macros.
69    #[arg(long)]
70    pub split: bool,
71
72    /// Only build the frontend.
73    #[arg(long)]
74    pub frontend_only: bool,
75
76    /// Only build the server.
77    #[arg(long, conflicts_with = "frontend_only")]
78    pub server_only: bool,
79}
80
81#[derive(Debug, Clone, Parser, PartialEq, Default)]
82pub struct BinOpts {
83    #[command(flatten)]
84    opts: Opts,
85
86    #[arg(trailing_var_arg = true)]
87    bin_args: Vec<String>,
88}
89
90#[derive(Debug, Clone, Parser, PartialEq, Default)]
91pub struct TestSpecificOpts {
92    /// Do not run the tests, only build them.
93    #[arg(long)]
94    pub no_run: bool,
95}
96
97impl TestSpecificOpts {
98    pub fn to_args(&self) -> Vec<String> {
99        let mut args = Vec::new();
100        if self.no_run {
101            args.push("--no-run".to_string());
102        }
103        args
104    }
105}
106
107#[derive(Debug, Clone, Parser, PartialEq, Default)]
108pub struct TestOpts {
109    #[command(flatten)]
110    opts: Opts,
111
112    #[command(flatten, next_help_heading = "Test-specific Options")]
113    pub opts_specific: TestSpecificOpts,
114}
115
116#[derive(Debug, Parser)]
117#[clap(version)]
118pub struct Cli {
119    /// Path to Cargo.toml.
120    #[arg(long)]
121    pub manifest_path: Option<Utf8PathBuf>,
122
123    /// Output logs from dependencies (multiple --log accepted).
124    #[arg(long)]
125    pub log: Vec<Log>,
126
127    #[command(subcommand)]
128    pub command: Commands,
129}
130
131impl Cli {
132    pub fn opts(&self) -> Option<Opts> {
133        match &self.command {
134            Commands::New(_) => None,
135            Commands::Serve(bin_opts) | Commands::Watch(bin_opts) => Some(bin_opts.opts.clone()),
136            Commands::Test(test_opts) => Some(test_opts.opts.clone()),
137            Commands::Build(opts) | Commands::EndToEnd(opts) => Some(opts.clone()),
138            _ => None,
139        }
140    }
141
142    pub fn opts_mut(&mut self) -> Option<&mut Opts> {
143        match &mut self.command {
144            Commands::New(_) => None,
145            Commands::Serve(bin_opts) | Commands::Watch(bin_opts) => Some(&mut bin_opts.opts),
146            Commands::Test(test_opts) => Some(&mut test_opts.opts),
147            Commands::Build(opts) | Commands::EndToEnd(opts) => Some(opts),
148            _ => None,
149        }
150    }
151
152    pub fn bin_args(&self) -> Option<&[String]> {
153        match &self.command {
154            Commands::Serve(bin_opts) | Commands::Watch(bin_opts) => {
155                Some(bin_opts.bin_args.as_ref())
156            }
157            _ => None,
158        }
159    }
160}
161
162#[derive(Debug, Subcommand, PartialEq)]
163pub enum Commands {
164    /// Build the server (feature ssr) and the client (wasm with feature hydrate).
165    Build(Opts),
166    /// Run the cargo tests for app, client and server.
167    Test(TestOpts),
168    /// Start the server and end-2-end tests.
169    EndToEnd(Opts),
170    /// Serve. Defaults to hydrate mode.
171    Serve(BinOpts),
172    /// Serve and automatically reload when files change.
173    Watch(BinOpts),
174    /// Start a wizard for creating a new project (using cargo-generate).
175    New(NewCommand),
176
177    /// Generate shell for `cargo-leptos`
178    Completions { shell: Shell },
179}