server: reject unknown startup flags

This commit is contained in:
Brad Stein 2026-05-15 09:20:38 -03:00
parent 1bc1eaf0ef
commit 23ba1126d8
6 changed files with 61 additions and 16 deletions

6
Cargo.lock generated
View File

@ -1652,7 +1652,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "lesavka_client"
version = "0.22.39"
version = "0.22.40"
dependencies = [
"anyhow",
"async-stream",
@ -1686,7 +1686,7 @@ dependencies = [
[[package]]
name = "lesavka_common"
version = "0.22.39"
version = "0.22.40"
dependencies = [
"anyhow",
"base64",
@ -1698,7 +1698,7 @@ dependencies = [
[[package]]
name = "lesavka_server"
version = "0.22.39"
version = "0.22.40"
dependencies = [
"anyhow",
"base64",

View File

@ -4,7 +4,7 @@ path = "src/main.rs"
[package]
name = "lesavka_client"
version = "0.22.39"
version = "0.22.40"
edition = "2024"
[dependencies]

View File

@ -1,6 +1,6 @@
[package]
name = "lesavka_common"
version = "0.22.39"
version = "0.22.40"
edition = "2024"
build = "build.rs"

View File

@ -10,7 +10,7 @@ bench = false
[package]
name = "lesavka_server"
version = "0.22.39"
version = "0.22.40"
edition = "2024"
autobins = false

View File

@ -1,19 +1,37 @@
/*──────────────── main ───────────────────────*/
fn print_version_and_exit_requested() -> bool {
if std::env::args()
.skip(1)
.any(|arg| arg == "--version" || arg == "-V")
{
println!("{} {}", PKG_NAME, lesavka_server::VERSION);
return true;
fn usage_line() -> &'static str {
"Usage: lesavka-server [--version|-V] [--help|-h]"
}
fn handle_startup_args() -> anyhow::Result<bool> {
let args = std::env::args().skip(1).collect::<Vec<_>>();
match args.as_slice() {
[] => Ok(false),
[arg] if arg == "--version" || arg == "-V" => {
println!("{} {}", PKG_NAME, lesavka_server::VERSION);
Ok(true)
}
[arg] if arg == "--help" || arg == "-h" => {
println!("{}", usage_line());
Ok(true)
}
[arg] if arg.starts_with('-') => {
let suggestion = if "--version".starts_with(arg.as_str()) {
"; did you mean --version?"
} else {
""
};
anyhow::bail!("unknown option {arg:?}{suggestion}; {}", usage_line())
}
[arg] => anyhow::bail!("unexpected positional argument {arg:?}; {}", usage_line()),
_ => anyhow::bail!("too many arguments; {}", usage_line()),
}
false
}
#[cfg(not(coverage))]
#[tokio::main(worker_threads = 4)]
async fn main() -> anyhow::Result<()> {
if print_version_and_exit_requested() {
if handle_startup_args()? {
return Ok(());
}
@ -58,7 +76,7 @@ async fn main() -> anyhow::Result<()> {
#[cfg(coverage)]
#[tokio::main(worker_threads = 2)]
async fn main() -> anyhow::Result<()> {
if print_version_and_exit_requested() {
if handle_startup_args()? {
return Ok(());
}

View File

@ -134,6 +134,33 @@ fn server_binary_reports_version_without_starting_relay() {
}
}
#[test]
#[serial]
fn server_binary_rejects_truncated_version_flag_without_starting_relay() {
let Some(bin) = find_binary("lesavka-server") else {
return;
};
let output = Command::new(bin)
.arg("--versio")
.output()
.expect("run lesavka-server --versio");
assert!(
!output.status.success(),
"truncated flag should fail instead of starting a second relay"
);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
stderr.contains("unknown option")
&& stderr.contains("did you mean --version")
&& stderr.contains("Usage: lesavka-server"),
"truncated flag should produce a helpful CLI error; stderr was:\n{stderr}"
);
assert!(
!stderr.contains("Address already in use") && !stderr.contains("open singleton lock"),
"argument validation should happen before relay, log, or UVC startup; stderr was:\n{stderr}"
);
}
#[test]
#[serial]
fn server_binary_stays_up_with_missing_hid_nodes_and_current_version() {