diff --git a/crates/clusterflux-coordinator/src/main.rs b/crates/clusterflux-coordinator/src/main.rs index 8c9ce7d..8344f5f 100644 --- a/crates/clusterflux-coordinator/src/main.rs +++ b/crates/clusterflux-coordinator/src/main.rs @@ -5,17 +5,40 @@ use clusterflux_core::{ProjectId, TenantId, UserId}; use serde_json::json; fn main() -> Result<(), Box> { + let raw_args = std::env::args().skip(1).collect::>(); + match raw_args.as_slice() { + [flag] if matches!(flag.as_str(), "--version" | "-V") => { + println!("clusterflux-coordinator {}", env!("CARGO_PKG_VERSION")); + return Ok(()); + } + [flag] if matches!(flag.as_str(), "--help" | "-h") => { + println!( + "Clusterflux coordinator.\n\n\ + Usage: clusterflux-coordinator [OPTIONS]\n\n\ + Options:\n \ + --listen
[default: 127.0.0.1:0]\n \ + --allow-local-trusted-loopback\n \ + -h, --help\n \ + -V, --version" + ); + return Ok(()); + } + _ => {} + } + let mut listen = "127.0.0.1:0".to_owned(); let mut allow_local_trusted = std::env::var("CLUSTERFLUX_ALLOW_LOCAL_TRUSTED_LOOPBACK") .ok() .as_deref() == Some("1"); - let mut args = std::env::args().skip(1); + let mut args = raw_args.into_iter(); while let Some(arg) = args.next() { if arg == "--listen" { listen = args.next().ok_or("--listen requires an address")?; } else if arg == "--allow-local-trusted-loopback" { allow_local_trusted = true; + } else { + return Err(format!("unknown argument: {arg}").into()); } } diff --git a/crates/clusterflux-dap/src/main.rs b/crates/clusterflux-dap/src/main.rs index 5e02bcd..b0a9c14 100644 --- a/crates/clusterflux-dap/src/main.rs +++ b/crates/clusterflux-dap/src/main.rs @@ -36,6 +36,26 @@ use demo_backend::{LINUX_THREAD, MAIN_THREAD, PACKAGE_THREAD, WINDOWS_THREAD}; use virtual_model::{process_id, RuntimeBackend}; fn main() -> Result<()> { + let raw_args = std::env::args().skip(1).collect::>(); + match raw_args.as_slice() { + [flag] if matches!(flag.as_str(), "--version" | "-V") => { + println!("clusterflux-debug-dap {}", env!("CARGO_PKG_VERSION")); + return Ok(()); + } + [flag] if matches!(flag.as_str(), "--help" | "-h") => { + println!( + "Clusterflux Debug Adapter Protocol server.\n\n\ + Usage: clusterflux-debug-dap\n\n\ + The adapter communicates over standard input and output.\n\n\ + Options:\n \ + -h, --help\n \ + -V, --version" + ); + return Ok(()); + } + [] => {} + [argument, ..] => anyhow::bail!("unknown argument: {argument}"), + } adapter::run_adapter() } diff --git a/crates/clusterflux-node/src/main.rs b/crates/clusterflux-node/src/main.rs index 8f2960b..2ada582 100644 --- a/crates/clusterflux-node/src/main.rs +++ b/crates/clusterflux-node/src/main.rs @@ -8,5 +8,34 @@ mod task_artifacts; mod task_reports; fn main() -> Result<(), Box> { + let raw_args = std::env::args().skip(1).collect::>(); + match raw_args.as_slice() { + [flag] if matches!(flag.as_str(), "--version" | "-V") => { + println!("clusterflux-node {}", env!("CARGO_PKG_VERSION")); + return Ok(()); + } + [flag] if matches!(flag.as_str(), "--help" | "-h") => { + println!( + "Clusterflux node worker.\n\n\ + Usage: clusterflux-node --coordinator [OPTIONS]\n\n\ + Options:\n \ + --coordinator \n \ + --tenant [default: tenant]\n \ + --project-id [default: project]\n \ + --node [default: node]\n \ + --project-root \n \ + --enrollment-grant \n \ + --public-key \n \ + --worker\n \ + --emit-ready\n \ + --control-poll-ms \n \ + --assignment-poll-ms [default: 500]\n \ + -h, --help\n \ + -V, --version" + ); + return Ok(()); + } + _ => {} + } daemon::run() } diff --git a/packages.nix b/packages.nix index ed60115..1305b67 100644 --- a/packages.nix +++ b/packages.nix @@ -37,6 +37,15 @@ let test -x "$out/bin/clusterflux-node" test -x "$out/bin/clusterflux-coordinator" test -x "$out/bin/clusterflux-debug-dap" + for command in \ + clusterflux \ + clusterflux-node \ + clusterflux-coordinator \ + clusterflux-debug-dap + do + ${pkgs.coreutils}/bin/timeout 5 "$out/bin/$command" --version >/dev/null + ${pkgs.coreutils}/bin/timeout 5 "$out/bin/$command" --help >/dev/null + done ''; postFixup = let