From 00ca564d6b116007aeddf19eb1bfb8b0e539d40d Mon Sep 17 00:00:00 2001 From: snek Date: Thu, 18 Sep 2025 13:17:12 +0200 Subject: [PATCH] refactor(unstable): improved arg handling and metadata --- cli/args/flags.rs | 10 ++--- cli/main.rs | 66 ++++++++++++++++++++------------- cli/tools/task.rs | 4 +- tests/specs/run/tunnel/test.out | 1 + tests/specs/run/tunnel/test.ts | 7 +++- 5 files changed, 55 insertions(+), 33 deletions(-) diff --git a/cli/args/flags.rs b/cli/args/flags.rs index eaf0923dd5..07aa978cd0 100644 --- a/cli/args/flags.rs +++ b/cli/args/flags.rs @@ -755,7 +755,7 @@ pub struct Flags { pub eszip: bool, pub node_conditions: Vec, pub preload: Vec, - pub connected: Option, + pub connected: bool, } #[derive(Clone, Debug, Eq, PartialEq, Default, Serialize, Deserialize)] @@ -4649,7 +4649,7 @@ fn connected_arg() -> Arg { .hide(true) .num_args(0..=1) .require_equals(true) - .default_missing_value("tunnel.global.prod.deno-cluster.net:443") + .action(ArgAction::SetTrue) } fn check_arg(checks_local_by_default: bool) -> Arg { @@ -5748,7 +5748,7 @@ fn run_parse( runtime_args_parse(flags, matches, true, true, true)?; ext_arg_parse(flags, matches); - flags.connected = matches.remove_one("connected"); + flags.connected = matches.get_flag("connected"); flags.code_cache_enabled = !matches.get_flag("no-code-cache"); let coverage_dir = matches.remove_one::("coverage"); @@ -5820,7 +5820,7 @@ fn serve_parse( } flags.code_cache_enabled = !matches.get_flag("no-code-cache"); - flags.connected = matches.remove_one("connected"); + flags.connected = matches.get_flag("connected"); let mut script_arg = matches.remove_many::("script_arg").ok_or_else(|| { @@ -5873,7 +5873,7 @@ fn task_parse( None }; - flags.connected = matches.remove_one("connected"); + flags.connected = matches.get_flag("connected"); let mut task_flags = TaskFlags { cwd: matches.remove_one::("cwd"), diff --git a/cli/main.rs b/cli/main.rs index d35809296b..10c52e5e13 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -656,6 +656,22 @@ async fn resolve_flags_and_init( .as_ref() .map(|files| files.iter().map(PathBuf::from).collect()); load_env_variables_from_env_files(env_file_paths.as_ref(), flags.log_level); + + if deno_lib::args::has_flag_env_var("DENO_CONNECTED") { + flags.connected = true; + } + + // Tunnel sets up env vars and OTEL, so connect before everything else. + if flags.connected { + if let Err(err) = initialize_tunnel(&flags).await { + exit_for_error(err.context("Failed to start with --connected")); + } + // SAFETY: We're doing this before any threads are created. + unsafe { + std::env::set_var("DENO_CONNECTED", "1"); + } + } + flags.unstable_config.fill_with_env(); if std::env::var("DENO_COMPAT").is_ok() { flags.unstable_config.enable_node_compat(); @@ -669,22 +685,6 @@ async fn resolve_flags_and_init( .collect(); } - // Tunnel is initialized before OTEL since - // OTEL data is submitted via the tunnel. - if let Some(host) = flags - .connected - .clone() - .or_else(|| env::var("DENO_CONNECTED").ok()) - { - if let Err(err) = initialize_tunnel(&host, &flags).await { - exit_for_error(err.context("Failed to start with --connected")); - } - // SAFETY: We're doing this before any threads are created. - unsafe { - std::env::set_var("DENO_CONNECTED", &host); - } - } - let otel_config = flags.otel_config(); init_logging(flags.log_level, Some(otel_config.clone())); deno_telemetry::init( @@ -933,13 +933,15 @@ async fn auth_tunnel( #[allow(clippy::print_stderr)] async fn initialize_tunnel( - host: &str, flags: &Flags, ) -> Result<(), deno_core::anyhow::Error> { let mut factory = CliFactory::from_flags(Arc::new(flags.clone())); let mut cli_options = factory.cli_options()?; let deploy_config = cli_options.start_dir.to_deploy_config()?; + let host = std::env::var("DENO_DEPLOY_TUNNEL_ENDPOINT") + .unwrap_or_else(|_| "tunnel.global.prod.deno-cluster.net:443".into()); + let env_token = env::var("DENO_DEPLOY_TOKEN").ok(); let env_org = env::var("DENO_DEPLOY_ORG").ok(); let env_app = env::var("DENO_DEPLOY_APP").ok(); @@ -994,14 +996,28 @@ async fn initialize_tunnel( "hostname".into(), deno_runtime::deno_os::sys_info::hostname(), ); - if let Some(entrypoint) = match &flags.subcommand { - DenoSubcommand::Run(run_flags) => Some(run_flags.script.to_owned()), - DenoSubcommand::Serve(serve_flags) => Some(serve_flags.script.to_owned()), - DenoSubcommand::Repl(_) => Some("".into()), - DenoSubcommand::Eval(_) => Some("".into()), - _ => None, - } { - metadata.insert("entrypoint".into(), entrypoint); + match &flags.subcommand { + DenoSubcommand::Run(run_flags) => { + metadata.insert("subcommand".into(), "run".into()); + metadata.insert("entrypoint".into(), run_flags.script.clone()); + } + DenoSubcommand::Serve(serve_flags) => { + metadata.insert("subcommand".into(), "serve".into()); + metadata.insert("entrypoint".into(), serve_flags.script.clone()); + } + DenoSubcommand::Task(task_flags) => { + metadata.insert("subcommand".into(), "task".into()); + if let Some(task) = &task_flags.task { + metadata.insert("task".into(), task.clone()); + } + } + DenoSubcommand::Repl(_) => { + metadata.insert("subcommand".into(), "repl".into()); + } + DenoSubcommand::Eval(_) => { + metadata.insert("subcommand".into(), "eval".into()); + } + _ => {} } let on_event = |event| { diff --git a/cli/tools/task.rs b/cli/tools/task.rs index 4ef6c991f6..8636c750a0 100644 --- a/cli/tools/task.rs +++ b/cli/tools/task.rs @@ -182,8 +182,8 @@ pub async fn execute_script( let progress_bar = factory.text_only_progress_bar(); let mut env_vars = task_runner::real_env_vars(); - if let Some(connected) = &flags.connected { - env_vars.insert("DENO_CONNECTED".into(), connected.into()); + if flags.connected { + env_vars.insert("DENO_CONNECTED".into(), "1".into()); } let no_of_concurrent_tasks = if let Ok(value) = std::env::var("DENO_JOBS") { diff --git a/tests/specs/run/tunnel/test.out b/tests/specs/run/tunnel/test.out index a462569bf3..1d9a21f3ad 100644 --- a/tests/specs/run/tunnel/test.out +++ b/tests/specs/run/tunnel/test.out @@ -1,3 +1,4 @@ +{ subcommand: "run", entrypoint: "client.ts" } You are connected to https://localhost:[WILDLINE] HTTP/1.1 200 OK content-type: application/json diff --git a/tests/specs/run/tunnel/test.ts b/tests/specs/run/tunnel/test.ts index cd44e67768..5aa78e1d56 100644 --- a/tests/specs/run/tunnel/test.ts +++ b/tests/specs/run/tunnel/test.ts @@ -16,12 +16,13 @@ const child = new Deno.Command(Deno.execPath(), { args: [ "run", "-A", - `--connected=localhost:${server.addr.port}`, + "--connected", "--cert", "../../../testdata/tls/RootCA.crt", "client.ts", ], env: { + DENO_DEPLOY_TUNNEL_ENDPOINT: `localhost:${server.addr.port}`, DENO_DEPLOY_TOKEN: "token", DENO_DEPLOY_ORG: "org", DENO_DEPLOY_APP: "app", @@ -61,6 +62,10 @@ async function handleConnection(incoming: Deno.QuicIncoming) { conn.close({ closeCode: 1, reason: "expected Control" }); return; } + console.log({ + subcommand: header.metadata.subcommand, + entrypoint: header.metadata.entrypoint, + }); const auth = await readStreamHeader(reader); if (auth.headerType !== "AuthenticateApp") { conn.close({ closeCode: 1, reason: "expected AuthenticateApp" });