diff --git a/.github/workflows/ci.generate.ts b/.github/workflows/ci.generate.ts index ba2e067f2422ea..95b4688dc6bd87 100755 --- a/.github/workflows/ci.generate.ts +++ b/.github/workflows/ci.generate.ts @@ -5,7 +5,7 @@ import { stringify } from "jsr:@std/yaml@^0.221/stringify"; // Bump this number when you want to purge the cache. // Note: the tools/release/01_bump_crate_versions.ts script will update this version // automatically via regex, so ensure that this line maintains this format. -const cacheVersion = 1; +const cacheVersion = 2; const ubuntuX86Runner = "ubuntu-22.04"; const ubuntuX86XlRunner = "ubuntu-22.04-xl"; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f1014451d8cc7..061c794fd40638 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -367,8 +367,8 @@ jobs: path: |- ~/.cargo/registry/index ~/.cargo/registry/cache - key: '1-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}' - restore-keys: '1-cargo-home-${{ matrix.os }}-${{ matrix.arch }}' + key: '2-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}' + restore-keys: '2-cargo-home-${{ matrix.os }}-${{ matrix.arch }}' if: '!(matrix.skip)' - name: Restore cache build output (PR) uses: actions/cache/restore@v4 @@ -380,7 +380,7 @@ jobs: !./target/*/*.zip !./target/*/*.tar.gz key: never_saved - restore-keys: '1-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-' + restore-keys: '2-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-' - name: Apply and update mtime cache if: '!(matrix.skip) && (!startsWith(github.ref, ''refs/tags/''))' uses: ./.github/mtime_cache @@ -669,7 +669,7 @@ jobs: !./target/*/gn_out !./target/*/*.zip !./target/*/*.tar.gz - key: '1-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}' + key: '2-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}' publish-canary: name: publish canary runs-on: ubuntu-22.04 diff --git a/Cargo.lock b/Cargo.lock index 1fddcf5ba3416a..8015167bbc367d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1288,7 +1288,7 @@ dependencies = [ "indexmap", "log", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "serde", "serde_json", "sha2", @@ -1350,7 +1350,7 @@ dependencies = [ "futures", "libc", "memoffset 0.9.1", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project", "serde", "serde_json", @@ -1530,7 +1530,7 @@ dependencies = [ "log", "monch", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "regex", "serde", "serde_json", @@ -1590,7 +1590,7 @@ dependencies = [ "log", "once_cell", "os_pipe", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "tokio", "winapi", @@ -1945,10 +1945,11 @@ dependencies = [ [[package]] name = "deno_unsync" -version = "0.3.6" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10eb3aaf83c3431d4215741140ec3a63b0c0edb972ee898c89bdf8462e9e136b" +checksum = "c3c8b95582c2023dbb66fccc37421b374026f5915fa507d437cb566904db9a3a" dependencies = [ + "parking_lot 0.12.3", "tokio", ] @@ -2714,7 +2715,7 @@ dependencies = [ "anyhow", "crossbeam-channel", "deno_terminal", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "regex", "thiserror", ] @@ -4591,9 +4592,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core 0.9.9", @@ -6138,7 +6139,7 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "phf_shared 0.10.0", "precomputed-hash", "serde", @@ -6234,7 +6235,7 @@ dependencies = [ "indexmap", "is-macro", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "petgraph", "radix_fmt", "relative-path", @@ -6795,7 +6796,7 @@ dependencies = [ "nix 0.26.2", "once_cell", "os_pipe", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pretty_assertions", "prost", "prost-build", @@ -6918,7 +6919,7 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project-lite", "signal-hook-registry", "socket2", @@ -7202,7 +7203,7 @@ dependencies = [ "ipconfig", "lru-cache", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "resolv-conf", "serde", @@ -7676,7 +7677,7 @@ dependencies = [ "log", "naga", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "profiling", "raw-window-handle", "ron", @@ -7718,7 +7719,7 @@ dependencies = [ "ndk-sys", "objc", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "profiling", "range-alloc", "raw-window-handle", @@ -8145,7 +8146,7 @@ dependencies = [ "log", "num-traits", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "regex", "thiserror", diff --git a/cli/args/flags.rs b/cli/args/flags.rs index 56fb4f09d2614b..4d0465caabc689 100644 --- a/cli/args/flags.rs +++ b/cli/args/flags.rs @@ -546,6 +546,7 @@ pub struct Flags { pub inspect_wait: Option, pub inspect: Option, pub location: Option, + // TODO(bartlomieju): deprecated, to be removed in Deno 2. pub lock_write: bool, pub lock: Option, pub log_level: Option, @@ -3623,12 +3624,14 @@ If value is not provided, defaults to \"deno.lock\" in the current working direc .value_hint(ValueHint::FilePath) } +// TODO(bartlomieju): deprecated, to be removed in Deno 2. fn lock_write_arg() -> Arg { Arg::new("lock-write") .action(ArgAction::SetTrue) .long("lock-write") .help("Force overwriting the lock file.") .conflicts_with("no-lock") + .hide(true) } fn no_lock_arg() -> Arg { @@ -4747,6 +4750,7 @@ fn check_arg_parse(flags: &mut Flags, matches: &mut ArgMatches) { fn lock_args_parse(flags: &mut Flags, matches: &mut ArgMatches) { lock_arg_parse(flags, matches); no_lock_arg_parse(flags, matches); + // TODO(bartlomieju): deprecated, to be removed in Deno 2. if matches.get_flag("lock-write") { flags.lock_write = true; } diff --git a/cli/args/lockfile.rs b/cli/args/lockfile.rs index d18c871aad11b2..3421addae849f2 100644 --- a/cli/args/lockfile.rs +++ b/cli/args/lockfile.rs @@ -130,6 +130,10 @@ impl CliLockfile { }; let lockfile = if flags.lock_write { + log::warn!( + "{} \"--lock-write\" flag is deprecated and will be removed in Deno 2.", + crate::colors::yellow("Warning") + ); CliLockfile::new( Lockfile::new_empty(filename, true), flags.frozen_lockfile, diff --git a/cli/args/mod.rs b/cli/args/mod.rs index f747271b811b2b..83f038ec022732 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -1060,6 +1060,7 @@ impl CliOptions { pub async fn create_workspace_resolver( &self, file_fetcher: &FileFetcher, + pkg_json_dep_resolution: PackageJsonDepResolution, ) -> Result { let overrode_no_import_map = self .overrides @@ -1102,12 +1103,7 @@ impl CliOptions { .workspace .create_resolver( CreateResolverOptions { - // todo(dsherret): this should be false for nodeModulesDir: true - pkg_json_dep_resolution: if self.use_byonm() { - PackageJsonDepResolution::Disabled - } else { - PackageJsonDepResolution::Enabled - }, + pkg_json_dep_resolution, specified_import_map: cli_arg_specified_import_map, }, |specifier| { diff --git a/cli/factory.rs b/cli/factory.rs index 62ab251f1686d9..5b066c67fb5636 100644 --- a/cli/factory.rs +++ b/cli/factory.rs @@ -55,6 +55,7 @@ use std::collections::BTreeSet; use std::path::PathBuf; use deno_config::package_json::PackageJsonDepValue; +use deno_config::workspace::PackageJsonDepResolution; use deno_config::workspace::WorkspaceResolver; use deno_config::ConfigFile; use deno_core::error::AnyError; @@ -458,7 +459,15 @@ impl CliFactory { .get_or_try_init_async(async { let resolver = self .options - .create_workspace_resolver(self.file_fetcher()?) + .create_workspace_resolver( + self.file_fetcher()?, + if self.options.use_byonm() { + PackageJsonDepResolution::Disabled + } else { + // todo(dsherret): this should be false for nodeModulesDir: true + PackageJsonDepResolution::Enabled + }, + ) .await?; if !resolver.diagnostics().is_empty() { warn!( @@ -759,6 +768,7 @@ impl CliFactory { self.file_fetcher()?, self.http_client_provider(), self.npm_resolver().await?.as_ref(), + self.workspace_resolver().await?.as_ref(), self.options.npm_system_info(), )) } diff --git a/cli/js/40_jupyter.js b/cli/js/40_jupyter.js index 0e0a4d7ac5621a..ace50d6dccbc0e 100644 --- a/cli/js/40_jupyter.js +++ b/cli/js/40_jupyter.js @@ -337,7 +337,14 @@ async function formatInner(obj, raw) { internals.jupyter = { formatInner }; function enableJupyter() { - const { op_jupyter_broadcast } = core.ops; + const { op_jupyter_broadcast, op_jupyter_input } = core.ops; + + function input( + prompt, + password, + ) { + return op_jupyter_input(prompt, password); + } async function broadcast( msgType, @@ -412,6 +419,45 @@ function enableJupyter() { return; } + /** + * Prompt for user confirmation (in Jupyter Notebook context) + * Override confirm and prompt because they depend on a tty + * and in the Deno.jupyter environment that doesn't exist. + * @param {string} message - The message to display. + * @returns {Promise} User confirmation. + */ + function confirm(message = "Confirm") { + const answer = input(`${message} [y/N] `, false); + return answer === "Y" || answer === "y"; + } + + /** + * Prompt for user input (in Jupyter Notebook context) + * @param {string} message - The message to display. + * @param {string} defaultValue - The value used if none is provided. + * @param {object} options Options + * @param {boolean} options.password Hide the output characters + * @returns {Promise} The user input. + */ + function prompt( + message = "Prompt", + defaultValue = "", + { password = false } = {}, + ) { + if (defaultValue != "") { + message += ` [${defaultValue}]`; + } + const answer = input(`${message}`, password); + + if (answer === "") { + return defaultValue; + } + + return answer; + } + + globalThis.confirm = confirm; + globalThis.prompt = prompt; globalThis.Deno.jupyter = { broadcast, display, diff --git a/cli/ops/jupyter.rs b/cli/ops/jupyter.rs index 938418187faa14..9f5aa92df63c01 100644 --- a/cli/ops/jupyter.rs +++ b/cli/ops/jupyter.rs @@ -1,9 +1,14 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// NOTE(bartlomieju): unfortunately it appears that clippy is broken +// and can't allow a single line ignore for `await_holding_lock`. +#![allow(clippy::await_holding_lock)] + use std::cell::RefCell; use std::rc::Rc; use std::sync::Arc; +use jupyter_runtime::InputRequest; use jupyter_runtime::JupyterMessage; use jupyter_runtime::JupyterMessageContent; use jupyter_runtime::KernelIoPubConnection; @@ -11,14 +16,17 @@ use jupyter_runtime::StreamContent; use deno_core::error::AnyError; use deno_core::op; +use deno_core::parking_lot::Mutex; use deno_core::serde_json; use deno_core::OpState; use tokio::sync::mpsc; -use tokio::sync::Mutex; + +use crate::tools::jupyter::server::StdinConnectionProxy; deno_core::extension!(deno_jupyter, ops = [ op_jupyter_broadcast, + op_jupyter_input, ], options = { sender: mpsc::UnboundedSender, @@ -32,6 +40,63 @@ deno_core::extension!(deno_jupyter, }, ); +#[op] +#[string] +pub fn op_jupyter_input( + state: &mut OpState, + #[string] prompt: String, + is_password: bool, +) -> Result, AnyError> { + let (last_execution_request, stdin_connection_proxy) = { + ( + state.borrow::>>>().clone(), + state.borrow::>>().clone(), + ) + }; + + let maybe_last_request = last_execution_request.lock().clone(); + if let Some(last_request) = maybe_last_request { + let JupyterMessageContent::ExecuteRequest(msg) = &last_request.content + else { + return Ok(None); + }; + + if !msg.allow_stdin { + return Ok(None); + } + + let msg = JupyterMessage::new( + InputRequest { + prompt, + password: is_password, + } + .into(), + Some(&last_request), + ); + + let Ok(()) = stdin_connection_proxy.lock().tx.send(msg) else { + return Ok(None); + }; + + // Need to spawn a separate thread here, because `blocking_recv()` can't + // be used from the Tokio runtime context. + let join_handle = std::thread::spawn(move || { + stdin_connection_proxy.lock().rx.blocking_recv() + }); + let Ok(Some(response)) = join_handle.join() else { + return Ok(None); + }; + + let JupyterMessageContent::InputReply(msg) = response.content else { + return Ok(None); + }; + + return Ok(Some(msg.value)); + } + + Ok(None) +} + #[op(async)] pub async fn op_jupyter_broadcast( state: Rc>, @@ -49,7 +114,7 @@ pub async fn op_jupyter_broadcast( ) }; - let maybe_last_request = last_execution_request.lock().await.clone(); + let maybe_last_request = last_execution_request.lock().clone(); if let Some(last_request) = maybe_last_request { let content = JupyterMessageContent::from_type_and_content( &message_type, @@ -69,9 +134,7 @@ pub async fn op_jupyter_broadcast( .with_metadata(metadata) .with_buffers(buffers.into_iter().map(|b| b.to_vec().into()).collect()); - (iopub_connection.lock().await) - .send(jupyter_message) - .await?; + iopub_connection.lock().send(jupyter_message).await?; } Ok(()) diff --git a/cli/standalone/binary.rs b/cli/standalone/binary.rs index bf035577c94c07..c9371d853e8ee9 100644 --- a/cli/standalone/binary.rs +++ b/cli/standalone/binary.rs @@ -18,6 +18,7 @@ use std::process::Command; use deno_ast::ModuleSpecifier; use deno_config::workspace::PackageJsonDepResolution; use deno_config::workspace::Workspace; +use deno_config::workspace::WorkspaceResolver; use deno_core::anyhow::bail; use deno_core::anyhow::Context; use deno_core::error::AnyError; @@ -376,6 +377,7 @@ pub struct DenoCompileBinaryWriter<'a> { file_fetcher: &'a FileFetcher, http_client_provider: &'a HttpClientProvider, npm_resolver: &'a dyn CliNpmResolver, + workspace_resolver: &'a WorkspaceResolver, npm_system_info: NpmSystemInfo, } @@ -386,6 +388,7 @@ impl<'a> DenoCompileBinaryWriter<'a> { file_fetcher: &'a FileFetcher, http_client_provider: &'a HttpClientProvider, npm_resolver: &'a dyn CliNpmResolver, + workspace_resolver: &'a WorkspaceResolver, npm_system_info: NpmSystemInfo, ) -> Self { Self { @@ -393,6 +396,7 @@ impl<'a> DenoCompileBinaryWriter<'a> { file_fetcher, http_client_provider, npm_resolver, + workspace_resolver, npm_system_info, } } @@ -419,17 +423,15 @@ impl<'a> DenoCompileBinaryWriter<'a> { } set_windows_binary_to_gui(&mut original_binary)?; } - self - .write_standalone_binary( - writer, - original_binary, - eszip, - root_dir_url, - entrypoint, - cli_options, - compile_flags, - ) - .await + self.write_standalone_binary( + writer, + original_binary, + eszip, + root_dir_url, + entrypoint, + cli_options, + compile_flags, + ) } async fn get_base_binary( @@ -512,7 +514,7 @@ impl<'a> DenoCompileBinaryWriter<'a> { /// This functions creates a standalone deno binary by appending a bundle /// and magic trailer to the currently executing binary. #[allow(clippy::too_many_arguments)] - async fn write_standalone_binary( + fn write_standalone_binary( &self, writer: &mut impl Write, original_bin: Vec, @@ -530,9 +532,6 @@ impl<'a> DenoCompileBinaryWriter<'a> { Some(CaData::Bytes(bytes)) => Some(bytes.clone()), None => None, }; - let workspace_resolver = cli_options - .create_workspace_resolver(self.file_fetcher) - .await?; let root_path = root_dir_url.inner().to_file_path().unwrap(); let (npm_vfs, npm_files, node_modules) = match self.npm_resolver.as_inner() { @@ -599,7 +598,7 @@ impl<'a> DenoCompileBinaryWriter<'a> { ca_data, entrypoint_key: root_dir_url.specifier_key(entrypoint).into_owned(), workspace_resolver: SerializedWorkspaceResolver { - import_map: workspace_resolver.maybe_import_map().map(|i| { + import_map: self.workspace_resolver.maybe_import_map().map(|i| { SerializedWorkspaceResolverImportMap { specifier: if i.base_url().scheme() == "file" { root_dir_url.specifier_key(i.base_url()).into_owned() @@ -610,7 +609,8 @@ impl<'a> DenoCompileBinaryWriter<'a> { json: i.to_json(), } }), - package_jsons: workspace_resolver + package_jsons: self + .workspace_resolver .package_jsons() .map(|pkg_json| { ( @@ -621,7 +621,7 @@ impl<'a> DenoCompileBinaryWriter<'a> { ) }) .collect(), - pkg_json_resolution: workspace_resolver.pkg_json_dep_resolution(), + pkg_json_resolution: self.workspace_resolver.pkg_json_dep_resolution(), }, node_modules, disable_deprecated_api_warning: cli_options diff --git a/cli/standalone/virtual_fs.rs b/cli/standalone/virtual_fs.rs index ee91b9f7fe8438..0d39f8e958c2c9 100644 --- a/cli/standalone/virtual_fs.rs +++ b/cli/standalone/virtual_fs.rs @@ -787,7 +787,6 @@ impl FileBackedVfs { .entries .iter() .map(|entry| FsDirEntry { - parent_path: path.to_string_lossy().into_owned(), name: entry.name().to_string(), is_file: matches!(entry, VfsEntry::File(_)), is_directory: matches!(entry, VfsEntry::Dir(_)), diff --git a/cli/tools/jupyter/mod.rs b/cli/tools/jupyter/mod.rs index a5139044faa616..1197d3df77a5ec 100644 --- a/cli/tools/jupyter/mod.rs +++ b/cli/tools/jupyter/mod.rs @@ -179,6 +179,7 @@ pub async fn kernel( let mut op_state = op_state_rc.borrow_mut(); op_state.put(startup_data.iopub_connection.clone()); op_state.put(startup_data.last_execution_request.clone()); + op_state.put(startup_data.stdin_connection_proxy.clone()); } repl_session_proxy.start().await; diff --git a/cli/tools/jupyter/server.rs b/cli/tools/jupyter/server.rs index 6a3831c49feefb..6e203d17d67d35 100644 --- a/cli/tools/jupyter/server.rs +++ b/cli/tools/jupyter/server.rs @@ -3,6 +3,10 @@ // This file is forked/ported from // Copyright 2020 The Evcxr Authors. MIT license. +// NOTE(bartlomieju): unfortunately it appears that clippy is broken +// and can't allow a single line ignore for `await_holding_lock`. +#![allow(clippy::await_holding_lock)] + use std::collections::HashMap; use std::rc::Rc; use std::sync::Arc; @@ -12,12 +16,12 @@ use crate::tools::repl; use deno_core::anyhow::bail; use deno_core::error::AnyError; use deno_core::futures; +use deno_core::parking_lot::Mutex; use deno_core::serde_json; use deno_core::CancelFuture; use deno_core::CancelHandle; use tokio::sync::mpsc; use tokio::sync::oneshot; -use tokio::sync::Mutex; use jupyter_runtime::messaging; use jupyter_runtime::AsChildOf; @@ -40,8 +44,14 @@ pub struct JupyterServer { repl_session_proxy: JupyterReplProxy, } +pub struct StdinConnectionProxy { + pub tx: mpsc::UnboundedSender, + pub rx: mpsc::UnboundedReceiver, +} + pub struct StartupData { pub iopub_connection: Arc>, + pub stdin_connection_proxy: Arc>, pub last_execution_request: Arc>>, } @@ -58,7 +68,7 @@ impl JupyterServer { connection_info.create_kernel_shell_connection().await?; let control_connection = connection_info.create_kernel_control_connection().await?; - let _stdin_connection = + let mut stdin_connection = connection_info.create_kernel_stdin_connection().await?; let iopub_connection = connection_info.create_kernel_iopub_connection().await?; @@ -66,9 +76,19 @@ impl JupyterServer { let iopub_connection = Arc::new(Mutex::new(iopub_connection)); let last_execution_request = Arc::new(Mutex::new(None)); + let (stdin_tx1, mut stdin_rx1) = + mpsc::unbounded_channel::(); + let (stdin_tx2, stdin_rx2) = mpsc::unbounded_channel::(); + + let stdin_connection_proxy = Arc::new(Mutex::new(StdinConnectionProxy { + tx: stdin_tx1, + rx: stdin_rx2, + })); + let Ok(()) = setup_tx.send(StartupData { iopub_connection: iopub_connection.clone(), last_execution_request: last_execution_request.clone(), + stdin_connection_proxy, }) else { bail!("Failed to send startup data"); }; @@ -82,6 +102,24 @@ impl JupyterServer { repl_session_proxy, }; + let stdin_fut = deno_core::unsync::spawn(async move { + loop { + let Some(msg) = stdin_rx1.recv().await else { + return; + }; + let Ok(()) = stdin_connection.send(msg).await else { + return; + }; + + let Ok(msg) = stdin_connection.read().await else { + return; + }; + let Ok(()) = stdin_tx2.send(msg) else { + return; + }; + } + }); + let hearbeat_fut = deno_core::unsync::spawn(async move { loop { if let Err(err) = heartbeat.single_heartbeat().await { @@ -134,6 +172,7 @@ impl JupyterServer { shell_fut, stdio_fut, repl_session_fut, + stdin_fut, ]); if let Ok(result) = join_fut.or_cancel(cancel_handle).await { @@ -148,13 +187,15 @@ impl JupyterServer { last_execution_request: Arc>>, stdio_msg: StreamContent, ) { - let maybe_exec_result = last_execution_request.lock().await.clone(); + let maybe_exec_result = last_execution_request.lock().clone(); let Some(exec_request) = maybe_exec_result else { return; }; - let mut iopub_conn = iopub_connection.lock().await; - let result = iopub_conn.send(stdio_msg.as_child_of(&exec_request)).await; + let result = iopub_connection + .lock() + .send(stdio_msg.as_child_of(&exec_request)) + .await; if let Err(err) = result { log::error!("Output error: {}", err); @@ -429,7 +470,7 @@ impl JupyterServer { if !execute_request.silent && execute_request.store_history { self.execution_count += 1; } - *self.last_execution_request.lock().await = Some(parent_message.clone()); + *self.last_execution_request.lock() = Some(parent_message.clone()); self .send_iopub( @@ -613,7 +654,7 @@ impl JupyterServer { &mut self, message: JupyterMessage, ) -> Result<(), AnyError> { - self.iopub_connection.lock().await.send(message).await + self.iopub_connection.lock().send(message).await } } diff --git a/cli/tools/registry/mod.rs b/cli/tools/registry/mod.rs index 134a973f7d9925..3f59f4e1468cfa 100644 --- a/cli/tools/registry/mod.rs +++ b/cli/tools/registry/mod.rs @@ -12,7 +12,7 @@ use base64::prelude::BASE64_STANDARD; use base64::Engine; use deno_ast::ModuleSpecifier; use deno_config::workspace::JsrPackageConfig; -use deno_config::workspace::WorkspaceResolver; +use deno_config::workspace::PackageJsonDepResolution; use deno_core::anyhow::bail; use deno_core::anyhow::Context; use deno_core::error::AnyError; @@ -24,7 +24,6 @@ use deno_core::serde_json; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_runtime::deno_fetch::reqwest; -use deno_runtime::deno_fs::FileSystem; use deno_terminal::colors; use lsp_types::Url; use serde::Deserialize; @@ -81,8 +80,6 @@ pub async fn publish( let auth_method = get_auth_method(publish_flags.token, publish_flags.dry_run)?; - let workspace_resolver = cli_factory.workspace_resolver().await?.clone(); - let directory_path = cli_factory.cli_options().initial_cwd(); let cli_options = cli_factory.cli_options(); let publish_configs = cli_options.workspace.jsr_packages_for_publish(); @@ -103,6 +100,20 @@ pub async fn publish( } } } + let specifier_unfurler = Arc::new(SpecifierUnfurler::new( + if cli_options.unstable_sloppy_imports() { + Some(SloppyImportsResolver::new(cli_factory.fs().clone())) + } else { + None + }, + cli_options + .create_workspace_resolver( + cli_factory.file_fetcher()?, + PackageJsonDepResolution::Enabled, + ) + .await?, + cli_options.unstable_bare_node_builtins(), + )); let diagnostics_collector = PublishDiagnosticsCollector::default(); let publish_preparer = PublishPreparer::new( @@ -110,9 +121,8 @@ pub async fn publish( cli_factory.module_graph_creator().await?.clone(), cli_factory.parsed_source_cache().clone(), cli_factory.type_checker().await?.clone(), - cli_factory.fs().clone(), cli_factory.cli_options().clone(), - workspace_resolver, + specifier_unfurler, ); let prepared_data = publish_preparer @@ -191,8 +201,7 @@ struct PublishPreparer { source_cache: Arc, type_checker: Arc, cli_options: Arc, - sloppy_imports_resolver: Option>, - workspace_resolver: Arc, + specifier_unfurler: Arc, } impl PublishPreparer { @@ -201,23 +210,16 @@ impl PublishPreparer { module_graph_creator: Arc, source_cache: Arc, type_checker: Arc, - fs: Arc, cli_options: Arc, - workspace_resolver: Arc, + specifier_unfurler: Arc, ) -> Self { - let sloppy_imports_resolver = if cli_options.unstable_sloppy_imports() { - Some(Arc::new(SloppyImportsResolver::new(fs.clone()))) - } else { - None - }; Self { graph_diagnostics_collector, module_graph_creator, source_cache, type_checker, cli_options, - sloppy_imports_resolver, - workspace_resolver, + specifier_unfurler, } } @@ -432,18 +434,11 @@ impl PublishPreparer { let tarball = deno_core::unsync::spawn_blocking({ let diagnostics_collector = diagnostics_collector.clone(); - let workspace_resolver = self.workspace_resolver.clone(); - let sloppy_imports_resolver = self.sloppy_imports_resolver.clone(); + let unfurler = self.specifier_unfurler.clone(); let cli_options = self.cli_options.clone(); let source_cache = self.source_cache.clone(); let config_path = config_path.clone(); move || { - let bare_node_builtins = cli_options.unstable_bare_node_builtins(); - let unfurler = SpecifierUnfurler::new( - sloppy_imports_resolver.as_deref(), - &workspace_resolver, - bare_node_builtins, - ); let root_specifier = ModuleSpecifier::from_directory_path(&root_dir).unwrap(); let publish_paths = diff --git a/cli/tools/registry/unfurl.rs b/cli/tools/registry/unfurl.rs index 147b59f30c5dc9..758db07964b077 100644 --- a/cli/tools/registry/unfurl.rs +++ b/cli/tools/registry/unfurl.rs @@ -5,6 +5,7 @@ use deno_ast::SourceRange; use deno_ast::SourceTextInfo; use deno_config::package_json::PackageJsonDepValue; use deno_config::workspace::MappedResolution; +use deno_config::workspace::PackageJsonDepResolution; use deno_config::workspace::WorkspaceResolver; use deno_core::ModuleSpecifier; use deno_graph::DependencyDescriptor; @@ -40,18 +41,22 @@ impl SpecifierUnfurlerDiagnostic { } } -pub struct SpecifierUnfurler<'a> { - sloppy_imports_resolver: Option<&'a SloppyImportsResolver>, - workspace_resolver: &'a WorkspaceResolver, +pub struct SpecifierUnfurler { + sloppy_imports_resolver: Option, + workspace_resolver: WorkspaceResolver, bare_node_builtins: bool, } -impl<'a> SpecifierUnfurler<'a> { +impl SpecifierUnfurler { pub fn new( - sloppy_imports_resolver: Option<&'a SloppyImportsResolver>, - workspace_resolver: &'a WorkspaceResolver, + sloppy_imports_resolver: Option, + workspace_resolver: WorkspaceResolver, bare_node_builtins: bool, ) -> Self { + debug_assert_eq!( + workspace_resolver.pkg_json_dep_resolution(), + PackageJsonDepResolution::Enabled + ); Self { sloppy_imports_resolver, workspace_resolver, @@ -136,7 +141,7 @@ impl<'a> SpecifierUnfurler<'a> { // resolved // }; let resolved = - if let Some(sloppy_imports_resolver) = self.sloppy_imports_resolver { + if let Some(sloppy_imports_resolver) = &self.sloppy_imports_resolver { sloppy_imports_resolver .resolve(&resolved, deno_graph::source::ResolutionMode::Execution) .as_specifier() @@ -148,6 +153,12 @@ impl<'a> SpecifierUnfurler<'a> { if relative_resolved == specifier { None // nothing to unfurl } else { + log::debug!( + "Unfurled specifier: {} from {} -> {}", + specifier, + referrer, + relative_resolved + ); Some(relative_resolved) } } @@ -395,11 +406,9 @@ mod tests { deno_config::workspace::PackageJsonDepResolution::Enabled, ); let fs = Arc::new(RealFs); - let sloppy_imports_resolver = SloppyImportsResolver::new(fs); - let unfurler = SpecifierUnfurler::new( - Some(&sloppy_imports_resolver), - &workspace_resolver, + Some(SloppyImportsResolver::new(fs)), + workspace_resolver, true, ); diff --git a/cli/util/logger.rs b/cli/util/logger.rs index 3cd0cbe5d2c6cb..f3510c50200fdf 100644 --- a/cli/util/logger.rs +++ b/cli/util/logger.rs @@ -41,6 +41,7 @@ pub fn init(maybe_level: Option) { // wgpu crates (gfx_backend), have a lot of useless INFO and WARN logs .filter_module("wgpu", log::LevelFilter::Error) .filter_module("gfx", log::LevelFilter::Error) + .filter_module("globset", log::LevelFilter::Error) // used to make available the lsp_debug which is then filtered out at runtime // in the cli logger .filter_module("deno::lsp::performance", log::LevelFilter::Debug) diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index 8f9c431edfccbd..80a2e11c7c9bdf 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -1131,10 +1131,10 @@ class SubtleCrypto { * @param {number | null} length * @returns {Promise} */ - async deriveBits(algorithm, baseKey, length) { + async deriveBits(algorithm, baseKey, length = null) { webidl.assertBranded(this, SubtleCryptoPrototype); const prefix = "Failed to execute 'deriveBits' on 'SubtleCrypto'"; - webidl.requiredArguments(arguments.length, 3, prefix); + webidl.requiredArguments(arguments.length, 2, prefix); algorithm = webidl.converters.AlgorithmIdentifier( algorithm, prefix, diff --git a/ext/fs/interface.rs b/ext/fs/interface.rs index 6036f82284be8a..cb6fc4f639c7fa 100644 --- a/ext/fs/interface.rs +++ b/ext/fs/interface.rs @@ -69,10 +69,10 @@ pub enum FsFileType { Junction, } +/// WARNING: This is part of the public JS Deno API. #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct FsDirEntry { - pub parent_path: String, pub name: String, pub is_file: bool, pub is_directory: bool, diff --git a/ext/fs/std_fs.rs b/ext/fs/std_fs.rs index 79f66cc4bf7010..c501b8928eb61c 100644 --- a/ext/fs/std_fs.rs +++ b/ext/fs/std_fs.rs @@ -814,7 +814,6 @@ fn read_dir(path: &Path) -> FsResult> { }; } Some(FsDirEntry { - parent_path: path.to_string_lossy().to_string(), name, is_file: method_or_false!(is_file), is_directory: method_or_false!(is_dir), diff --git a/ext/node/polyfills/_fs/_fs_dirent.ts b/ext/node/polyfills/_fs/_fs_dirent.ts index 0f80fc135c7899..d4ad6bb4303635 100644 --- a/ext/node/polyfills/_fs/_fs_dirent.ts +++ b/ext/node/polyfills/_fs/_fs_dirent.ts @@ -2,7 +2,7 @@ import { notImplemented } from "ext:deno_node/_utils.ts"; export default class Dirent { - constructor(private entry: Deno.DirEntry) {} + constructor(private entry: Deno.DirEntry & { parentPath: string }) {} isBlockDevice(): boolean { notImplemented("Deno does not yet support identification of block devices"); diff --git a/ext/node/polyfills/_fs/_fs_readdir.ts b/ext/node/polyfills/_fs/_fs_readdir.ts index f8c0a59d6916b9..3b314227dc15a2 100644 --- a/ext/node/polyfills/_fs/_fs_readdir.ts +++ b/ext/node/polyfills/_fs/_fs_readdir.ts @@ -11,7 +11,7 @@ import { getValidatedPath } from "ext:deno_node/internal/fs/utils.mjs"; import { Buffer } from "node:buffer"; import { promisify } from "ext:deno_node/internal/util.mjs"; -function toDirent(val: Deno.DirEntry): Dirent { +function toDirent(val: Deno.DirEntry & { parentPath: string }): Dirent { return new Dirent(val); } @@ -67,13 +67,15 @@ export function readdir( } try { - asyncIterableToCallback(Deno.readDir(path.toString()), (val, done) => { + path = path.toString(); + asyncIterableToCallback(Deno.readDir(path), (val, done) => { if (typeof path !== "string") return; if (done) { callback(null, result); return; } if (options?.withFileTypes) { + val.parentPath = path; result.push(toDirent(val)); } else result.push(decode(val.name)); }, (e) => { @@ -130,8 +132,10 @@ export function readdirSync( } try { - for (const file of Deno.readDirSync(path.toString())) { + path = path.toString(); + for (const file of Deno.readDirSync(path)) { if (options?.withFileTypes) { + file.parentPath = path; result.push(toDirent(file)); } else result.push(decode(file.name)); } diff --git a/ext/node/polyfills/http.ts b/ext/node/polyfills/http.ts index b1a536113dbfb9..40155d998c6166 100644 --- a/ext/node/polyfills/http.ts +++ b/ext/node/polyfills/http.ts @@ -1657,7 +1657,7 @@ export class ServerImpl extends EventEmitter { #httpConnections: Set = new Set(); #listener?: Deno.Listener; - #addr: Deno.NetAddr; + #addr: Deno.NetAddr | null = null; #hasClosed = false; #server: Deno.HttpServer; #unref = false; @@ -1843,6 +1843,7 @@ export class ServerImpl extends EventEmitter { } address() { + if (this.#addr === null) return null; return { port: this.#addr.port, address: this.#addr.hostname, diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 0a750f891d7b75..44dc3c54d49eec 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -579,6 +579,7 @@ const NOT_IMPORTED_OPS = [ // Related to `Deno.jupyter` API "op_jupyter_broadcast", + "op_jupyter_input", // Related to `Deno.test()` API "op_test_event_step_result_failed",