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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
use clap::{Args, Parser, Subcommand};
#[derive(Debug, Parser)]
#[command(name = "infinity-msfs")]
#[command(version)]
#[command(about = "MSFS WASM build tooling for Infinity Rust projects")]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
}
#[derive(Debug, Subcommand)]
pub enum Commands {
/// Build everything in `infinity-msfs.toml`: `[[rust.packages]]`
/// then `[[js.instruments]]`.
Build(BuildArgs),
#[command(alias = "list-projects")]
Projects(ProjectsArgs),
/// Manage the local MSFS 2024 SDK installation.
Sdk(SdkArgs),
/// Run pre-flight checks for the build environment.
Doctor,
/// Compile MSFS project XML files via `fspackagetool.exe`.
/// Windows-only and requires MSFS 2024 to be installed locally,
/// since the package tool drives a partial sim instance to do
/// the actual asset compilation.
Package(PackageArgs),
/// Watch source files and rebuild on change.
Watch(WatchArgs),
/// Scaffold a new MSFS project from a built-in template.
Create(CreateArgs),
}
#[derive(Debug, Args, Clone)]
pub struct CreateArgs {
/// Target directory. Prompts when omitted.
pub path: Option<std::path::PathBuf>,
/// Skip the picker and use a known template id
/// (e.g. `rust-wasm-gauge`, `ts-react`, `rescript-react`).
#[arg(short = 't', long = "template")]
pub template: Option<String>,
/// Skip the project_name prompt.
#[arg(short = 'n', long = "name")]
pub name: Option<String>,
/// Fail if any required field would prompt. For CI / scripted use.
#[arg(long = "no-input")]
pub no_input: bool,
/// Allow scaffolding into a non-empty directory.
#[arg(long)]
pub force: bool,
}
#[derive(Debug, Args, Clone)]
pub struct BuildArgs {
#[arg(long)]
pub release: bool,
/// Stream subprocess output directly instead of the compact progress UI.
#[arg(short = 'v', long)]
pub verbose: bool,
/// Restrict the build to the named entries. Matched against
/// `[[rust.packages]].cargo_package` AND `[[js.instruments]].name`.
/// May be passed multiple times.
#[arg(long = "only")]
pub only: Vec<String>,
/// Skip the JS pipeline.
#[arg(long = "rust-only", conflicts_with = "js_only")]
pub rust_only: bool,
/// Skip the cargo pipeline.
#[arg(long = "js-only")]
pub js_only: bool,
#[arg(long = "no-wasm-opt")]
pub no_wasm_opt: bool,
/// Rebuild every wasm gauge as a native `.dll` for the off-sim emulator
/// (infinity-emu) instead of a `.wasm` module. Links the shim import
/// library (see `[rust].shim_lib_dir` / `INFINITY_EMU_SHIM_DIR`) and skips
/// the JS pipeline. SimConnect-only `native` entries are unaffected.
#[arg(long)]
pub native: bool,
/// Minify bundled JS.
#[arg(long)]
pub minify: bool,
/// Emit JS sourcemaps. One of `inline`, `external`, `file`.
#[arg(long = "sourcemap")]
pub sourcemap: Option<String>,
/// Skip simulator-package emission for JS instruments
/// (produce the raw rolldown bundle only).
#[arg(long = "skip-simulator-package")]
pub skip_simulator_package: bool,
}
#[derive(Debug, Args, Clone)]
pub struct SdkArgs {
#[command(subcommand)]
pub command: SdkCommand,
}
#[derive(Debug, Subcommand, Clone)]
pub enum SdkCommand {
/// Download the latest MSFS 2024 SDK from sdk.flightsimulator.com and
/// extract the relevant subtree into the local cache.
Install(SdkInstallArgs),
/// Print the resolved SDK path.
Path,
/// Remove the cached SDK installation.
Remove,
}
#[derive(Debug, Args, Clone)]
pub struct SdkInstallArgs {
/// Re-download even if the latest version is already cached.
#[arg(long)]
pub force: bool,
}
#[derive(Debug, Args, Clone)]
pub struct ProjectsArgs {
/// Restrict the list to the named entries. Matched against
/// `[[rust.packages]].cargo_package` AND `[[js.instruments]].name`.
/// May be passed multiple times.
#[arg(long = "only")]
pub only: Vec<String>,
}
#[derive(Debug, Args, Clone)]
pub struct PackageArgs {
/// Restrict to the named `[[sim_packages]]` entries by `name`.
/// May be passed multiple times.
#[arg(long = "only")]
pub only: Vec<String>,
/// Stream subprocess output directly instead of the compact UI.
#[arg(short = 'v', long)]
pub verbose: bool,
/// Override `rebuild` for every selected entry.
#[arg(long)]
pub rebuild: bool,
/// Override `mirror` for every selected entry.
#[arg(long)]
pub mirror: bool,
/// Override `force_steam` for every selected entry.
#[arg(long = "force-steam")]
pub force_steam: bool,
/// Export to Marketplace into this directory (overrides per-entry
/// `marketplace`). Passed through to fspackagetool's
/// `-marketplace`.
#[arg(long)]
pub marketplace: Option<String>,
}
#[derive(Debug, Args, Clone)]
pub struct WatchArgs {
#[arg(long)]
pub release: bool,
/// Stream subprocess output directly instead of the compact UI.
#[arg(short = 'v', long)]
pub verbose: bool,
/// Restrict to the named entries. Matched against
/// `[[rust.packages]].cargo_package` AND `[[js.instruments]].name`.
/// May be passed multiple times.
#[arg(long = "only")]
pub only: Vec<String>,
#[arg(long = "no-wasm-opt")]
pub no_wasm_opt: bool,
/// Skip the JS pipeline.
#[arg(long = "rust-only", conflicts_with = "js_only")]
pub rust_only: bool,
/// Skip the cargo pipeline.
#[arg(long = "js-only")]
pub js_only: bool,
/// Debounce window in milliseconds. Events that arrive within
/// this window after the last event collapse into one rebuild.
#[arg(long, default_value_t = 300)]
pub debounce: u64,
/// Rebuild as native `.dll`s for the off-sim emulator (infinity-emu) on each
/// change, instead of `.wasm` modules. Same effect as `build --native`; pair
/// with `--rust-only` for the tightest gauge-iteration loop.
#[arg(long)]
pub native: bool,
}