1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#![allow(missing_docs)] // Prevents double-documenting some things

use crate::PERSEUS_VERSION;
use clap::Parser;

// The documentation for the `Opts` struct will appear in the help page, hence
// the lack of puncutation and the lowercasing in places

/// The command-line interface for Perseus, a super-fast WebAssembly frontend
/// development framework!
#[derive(Parser)]
#[clap(version = PERSEUS_VERSION)]
// #[clap(setting = AppSettings::ColoredHelp)]
pub struct Opts {
    #[clap(subcommand)]
    pub subcmd: Subcommand,
}

#[derive(Parser)]
pub enum Subcommand {
    Build(BuildOpts),
    ExportErrorPage(ExportErrorPageOpts),
    Export(ExportOpts),
    Serve(ServeOpts),
    /// Serves your app as `perseus serve` does, but puts it in testing mode
    Test(ServeOpts),
    /// Removes build artifacts in the `dist/` directory
    Clean,
    Deploy(DeployOpts),
    Tinker(TinkerOpts),
    /// Runs one of the underlying commands that builds your app, allowing you
    /// to see more detailed logs
    #[clap(subcommand)]
    Snoop(SnoopSubcommand),
    New(NewOpts),
    Init(InitOpts),
}
/// Builds your app
#[derive(Parser)]
pub struct BuildOpts {
    /// Build for production
    #[clap(long)]
    pub release: bool,
}
/// Exports your app to purely static files
#[derive(Parser, Clone)]
pub struct ExportOpts {
    /// Export for production
    #[clap(long)]
    pub release: bool,
    /// Serve the generated static files locally
    #[clap(short, long)]
    pub serve: bool,
    /// Where to host your exported app
    #[clap(long, default_value = "127.0.0.1")]
    pub host: String,
    /// The port to host your exported app on
    #[clap(long, default_value = "8080")]
    pub port: u16,
    /// Watch the files in your working directory for changes (exluding
    /// `target/` and `dist/`)
    #[clap(short, long)]
    pub watch: bool,
    /// Marks a specific file/directory to be watched (directories will be
    /// recursively watched)
    #[clap(long)]
    pub custom_watch: Vec<String>,
}
/// Exports an error page for the given HTTP status code
#[derive(Parser, Clone)]
pub struct ExportErrorPageOpts {
    #[clap(short, long)]
    pub code: String,
    #[clap(short, long)]
    pub output: String,
}
/// Serves your app (set the `$HOST` and `$PORT` environment variables to change
/// the location it's served at)
#[derive(Parser, Clone)]
pub struct ServeOpts {
    /// Don't run the final binary, but print its location instead as the last
    /// line of output
    #[clap(long)]
    pub no_run: bool,
    /// Only build the server, and use the results of a previous `perseus build`
    #[clap(long)]
    pub no_build: bool,
    /// Build and serve for production
    #[clap(long)]
    pub release: bool,
    /// Make the final binary standalone (this is used in `perseus deploy` only,
    /// don't manually invoke it unless you have a good reason!)
    #[clap(long)]
    pub standalone: bool,
    /// Watch the files in your working directory for changes (exluding
    /// `target/` and `dist/`)
    #[clap(short, long)]
    pub watch: bool,
    /// Marks a specific file/directory to be watched (directories will be
    /// recursively watched)
    #[clap(long)]
    pub custom_watch: Vec<String>,
    /// Where to host your exported app
    #[clap(long, default_value = "127.0.0.1")]
    pub host: String,
    /// The port to host your exported app on
    #[clap(long, default_value = "8080")]
    pub port: u16,
}
/// Packages your app for deployment
#[derive(Parser)]
pub struct DeployOpts {
    /// Change the output from `pkg/` to somewhere else
    #[clap(short, long, default_value = "pkg")]
    pub output: String,
    /// Export you app to purely static files (see `export`)
    #[clap(short, long)]
    pub export_static: bool,
}
/// Runs the `tinker` action of plugins, which lets them modify the Perseus
/// engine
#[derive(Parser)]
pub struct TinkerOpts {
    /// Don't remove and recreate the `dist/` directory
    #[clap(long)]
    pub no_clean: bool,
}
/// Creates a new Perseus project in a directory of the given name, which will
/// be created in the current path
#[derive(Parser)]
pub struct NewOpts {
    /// The name of the new project, which will also be used for the directory
    #[clap(value_parser)]
    pub name: String,
    /// An optional custom URL to a Git repository to be used as a custom
    /// template (note that custom templates will not respect your project's
    /// name). This can be followed with `@branch` to fetch from `branch`
    /// rather than the default
    #[clap(short, long)]
    pub template: Option<String>,
    /// The path to a custom directory to create (if this is not provided, the
    /// project name will be used by default)
    #[clap(long)]
    pub dir: Option<String>,
}
/// Intializes a new Perseus project in the current directory
#[derive(Parser)]
pub struct InitOpts {
    /// The name of the new project
    #[clap(value_parser)]
    pub name: String,
}

#[derive(Parser)]
pub enum SnoopSubcommand {
    /// Snoops on the static generation process (this will let you see `dbg!`
    /// calls and the like)
    Build,
    /// Snoops on the Wasm building process (mostly for debugging errors)
    WasmBuild(SnoopWasmOpts),
    /// Snoops on the server process (run `perseus build` before this)
    Serve(SnoopServeOpts),
}

#[derive(Parser)]
pub struct SnoopWasmOpts {
    /// Produce a profiling build (for use with `twiggy` and the like)
    #[clap(short, long)]
    pub profiling: bool,
}

#[derive(Parser)]
pub struct SnoopServeOpts {
    /// Where to host your exported app
    #[clap(long, default_value = "127.0.0.1")]
    pub host: String,
    /// The port to host your exported app on
    #[clap(long, default_value = "8080")]
    pub port: u16,
}