diff --git a/src/main.rs b/src/main.rs index f52db6db..7abad554 100644 --- a/src/main.rs +++ b/src/main.rs @@ -120,8 +120,63 @@ fn make_socket(addr: &SocketAddr, reuse_port: bool) -> std::io::Result { #[tokio::main] async fn main() -> Result<(), Box> { - // Load .env file if present (for local development) - dotenvy::dotenv().ok(); + // Minimal CLI: + // --version Print version + branch + commit hash and exit. + // --config Load env from this file. When given, the default + // `./.env` probe is INTENTIONALLY skipped — tests + // use this to isolate from a developer's repo-root + // `.env`, and operators get a reproducible "this + // file and nothing else" boot. + let mut args = std::env::args().skip(1); + let mut config_path: Option = None; + while let Some(arg) = args.next() { + match arg.as_str() { + "--version" | "-V" => { + println!( + "OxiCloud v{} (branch={} commit={})", + env!("CARGO_PKG_VERSION"), + env!("GIT_BRANCH"), + env!("GIT_HASH"), + ); + return Ok(()); + } + "--config" => { + let Some(p) = args.next() else { + eprintln!("--config requires a path argument"); + std::process::exit(2); + }; + config_path = Some(p); + } + "--help" | "-h" => { + println!( + "OxiCloud v{}\n\nUSAGE:\n oxicloud [--config ]\n oxicloud --version\n oxicloud --help\n", + env!("CARGO_PKG_VERSION"), + ); + return Ok(()); + } + other => { + eprintln!("Unknown argument: {other}"); + eprintln!("Try `oxicloud --help`."); + std::process::exit(2); + } + } + } + + match config_path { + Some(ref path) => { + // Explicit file → hard error on a missing/unreadable path. + // Silent fallback would defeat the purpose of pinning the + // config source. + if let Err(e) = dotenvy::from_filename(path) { + eprintln!("failed to load --config {path}: {e}"); + std::process::exit(2); + } + } + None => { + // Default dev-convenience probe at CWD/.env. + dotenvy::dotenv().ok(); + } + } // Initialize tracing tracing_subscriber::registry() diff --git a/tests/api/run.sh b/tests/api/run.sh index 35ea846e..09997fe8 100755 --- a/tests/api/run.sh +++ b/tests/api/run.sh @@ -94,7 +94,12 @@ if [[ ! -x "$OXICLOUD_BIN" ]]; then fi log "Starting OxiCloud server ($BUILD_TARGET) on port $SERVER_PORT..." -"$OXICLOUD_BIN" & +# `--config` pins the env file the binary reads AND suppresses the default +# `.env` probe in main.rs, so a developer's repo-root `.env` can never leak +# into a test run. Bash also sourced the same file above, so anything the +# test harness itself reads via $OXICLOUD_* stays available; dotenvy won't +# override those already-exported values. +"$OXICLOUD_BIN" --config "$COMMON/server.env" & SERVER_PID=$! log "Waiting for server at $base_url..." wait_for_http "$base_url/ready" 120 diff --git a/tests/webdav/run.sh b/tests/webdav/run.sh index f05874b4..cfdc1656 100755 --- a/tests/webdav/run.sh +++ b/tests/webdav/run.sh @@ -74,13 +74,18 @@ wipe_storage "$OXICLOUD_STORAGE_PATH" BUILD_TARGET="${BUILD_TARGET:-debug}" OXICLOUD_BIN="$REPO_ROOT/target/$BUILD_TARGET/oxicloud" +# `--config` pins the env file the binary reads AND suppresses the default +# `.env` probe in main.rs, so a developer's repo-root `.env` can never leak +# into a test run. Bash also sourced the same file above, so anything the +# test harness itself reads via $OXICLOUD_* stays available; dotenvy won't +# override those already-exported values. if [[ -x "$OXICLOUD_BIN" ]]; then log "Starting pre-built OxiCloud server ($BUILD_TARGET) on port $SERVER_PORT..." - "$OXICLOUD_BIN" & + "$OXICLOUD_BIN" --config "$COMMON/server.env" & else log "Building and starting OxiCloud server on port $SERVER_PORT..." cd "$REPO_ROOT" - cargo run & + cargo run -- --config "$COMMON/server.env" & fi SERVER_PID=$! log "Waiting for server at $base_url..."