1#![doc = include_str!("../README.md")]
2#![expect(
6 clippy::print_stdout,
7 clippy::print_stderr,
8 reason = "reporting to the terminal is this binary's job"
9)]
10
11mod build_android;
12mod check;
13mod http;
14mod miri;
15mod print_gpu;
16mod publish;
17mod run_wasm;
18mod step;
19mod test;
20mod test_wasm;
21
22use argh::FromArgs;
23
24fn main() {
25 if let Err(error) = run() {
26 eprintln!("{error}");
27 std::process::exit(1);
28 }
29}
30
31fn run() -> Result<(), String> {
32 let args: Args = argh::from_env();
33 match args.task {
34 Task::Check(task) => check::run(task.release),
35 Task::Test(task) => test::run(task.release),
36 Task::TestWasm(task) => test_wasm::run(&task),
37 Task::Miri(task) => miri::run(&task),
38 Task::RunWasm(task) => run_wasm::run(&task),
39 Task::BuildAndroid(task) => build_android::run(&task),
40 Task::Publish(task) => publish::run(&task),
41 Task::PrintGpu(task) => print_gpu::run(&task),
42 }
43}
44
45#[derive(FromArgs)]
47struct Args {
48 #[argh(subcommand)]
50 task: Task,
51}
52
53#[derive(FromArgs)]
58#[argh(subcommand)]
59enum Task {
60 Check(CheckArgs),
63 Test(TestArgs),
65 TestWasm(TestWasmArgs),
67 Miri(MiriArgs),
69 RunWasm(RunWasmArgs),
71 BuildAndroid(BuildAndroidArgs),
73 Publish(PublishArgs),
75 PrintGpu(PrintGpuArgs),
77}
78
79#[derive(FromArgs)]
81#[argh(
82 subcommand,
83 name = "check",
84 description = "run the typo and TOML checks, clippy and the doc build over the whole workspace, then check formatting"
85)]
86struct CheckArgs {
87 #[argh(switch)]
89 release: bool,
90}
91
92#[derive(FromArgs)]
94#[argh(
95 subcommand,
96 name = "test",
97 description = "run the workspace's tests through nextest, then the doctests"
98)]
99struct TestArgs {
100 #[argh(switch)]
102 release: bool,
103}
104
105#[derive(FromArgs)]
107#[argh(
108 subcommand,
109 name = "test-wasm",
110 description = "run the GPU tests in a real browser through wasm and WebGL2"
111)]
112struct TestWasmArgs {
113 #[argh(switch)]
115 show: bool,
116}
117
118#[derive(FromArgs)]
120#[argh(
121 subcommand,
122 name = "miri",
123 description = "run the ECS's tests under Miri, which is what checks its unsafe"
124)]
125struct MiriArgs {}
126
127#[derive(FromArgs)]
129#[argh(
130 subcommand,
131 name = "run-wasm",
132 description = "build the web examples and serve them for a browser"
133)]
134struct RunWasmArgs {
135 #[argh(option, default = "WebApp::All")]
137 app: WebApp,
138 #[argh(switch)]
140 no_serve: bool,
141 #[argh(positional, greedy)]
143 cargo_args: Vec<String>,
144}
145
146#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, argh::FromArgValue)]
148enum WebApp {
149 Unlit3d,
151 Unlit3dx,
153 #[default]
155 All,
156}
157
158#[derive(FromArgs)]
160#[argh(
161 subcommand,
162 name = "build-android",
163 description = "build the Android example's shared library and the APK around it"
164)]
165struct BuildAndroidArgs {
166 #[argh(switch)]
168 release: bool,
169}
170
171#[derive(FromArgs)]
173#[argh(
174 subcommand,
175 name = "print-gpu",
176 description = "print the GPU device the tests draw with, as JSON"
177)]
178struct PrintGpuArgs {
179 #[argh(option)]
182 tier: Option<String>,
183}
184
185#[derive(FromArgs)]
187#[argh(
188 subcommand,
189 name = "publish",
190 description = "publish the workspace's crates to crates.io, in dependency order"
191)]
192struct PublishArgs {
193 #[argh(positional, greedy)]
195 cargo_args: Vec<String>,
196}