diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/args/mod.rs | 36 | ||||
-rw-r--r-- | cli/npm/byonm.rs | 2 | ||||
-rw-r--r-- | cli/npm/managed/mod.rs | 2 | ||||
-rw-r--r-- | cli/npm/managed/resolvers/common/lifecycle_scripts.rs | 21 | ||||
-rw-r--r-- | cli/npm/mod.rs | 2 | ||||
-rw-r--r-- | cli/worker.rs | 11 |
6 files changed, 57 insertions, 17 deletions
diff --git a/cli/args/mod.rs b/cli/args/mod.rs index 995a04823..c3a4c2937 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -69,6 +69,8 @@ use std::collections::HashMap; use std::env; use std::io::BufReader; use std::io::Cursor; +use std::io::Read; +use std::io::Seek; use std::net::SocketAddr; use std::num::NonZeroUsize; use std::path::Path; @@ -742,15 +744,33 @@ pub enum NpmProcessStateKind { Byonm, } -pub(crate) const NPM_RESOLUTION_STATE_ENV_VAR_NAME: &str = - "DENO_DONT_USE_INTERNAL_NODE_COMPAT_STATE"; - static NPM_PROCESS_STATE: Lazy<Option<NpmProcessState>> = Lazy::new(|| { - let state = std::env::var(NPM_RESOLUTION_STATE_ENV_VAR_NAME).ok()?; - let state: NpmProcessState = serde_json::from_str(&state).ok()?; - // remove the environment variable so that sub processes - // that are spawned do not also use this. - std::env::remove_var(NPM_RESOLUTION_STATE_ENV_VAR_NAME); + use deno_runtime::ops::process::NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME; + let fd = std::env::var(NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME).ok()?; + std::env::remove_var(NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME); + let fd = fd.parse::<usize>().ok()?; + let mut file = { + use deno_runtime::deno_io::FromRawIoHandle; + unsafe { std::fs::File::from_raw_io_handle(fd as _) } + }; + let mut buf = Vec::new(); + // seek to beginning. after the file is written the position will be inherited by this subprocess, + // and also this file might have been read before + file.seek(std::io::SeekFrom::Start(0)).unwrap(); + file + .read_to_end(&mut buf) + .inspect_err(|e| { + log::error!("failed to read npm process state from fd {fd}: {e}"); + }) + .ok()?; + let state: NpmProcessState = serde_json::from_slice(&buf) + .inspect_err(|e| { + log::error!( + "failed to deserialize npm process state: {e} {}", + String::from_utf8_lossy(&buf) + ) + }) + .ok()?; Some(state) }); diff --git a/cli/npm/byonm.rs b/cli/npm/byonm.rs index fc7069e1f..4c8bbd394 100644 --- a/cli/npm/byonm.rs +++ b/cli/npm/byonm.rs @@ -14,9 +14,9 @@ use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node::DenoPkgJsonFsAdapter; use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodeRequireResolver; -use deno_runtime::deno_node::NpmProcessStateProvider; use deno_runtime::deno_node::PackageJson; use deno_runtime::fs_util::specifier_to_file_path; +use deno_runtime::ops::process::NpmProcessStateProvider; use deno_semver::package::PackageReq; use deno_semver::Version; use node_resolver::errors::PackageFolderResolveError; diff --git a/cli/npm/managed/mod.rs b/cli/npm/managed/mod.rs index 0be26b785..40c92cd46 100644 --- a/cli/npm/managed/mod.rs +++ b/cli/npm/managed/mod.rs @@ -22,7 +22,7 @@ use deno_npm::NpmSystemInfo; use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodeRequireResolver; -use deno_runtime::deno_node::NpmProcessStateProvider; +use deno_runtime::ops::process::NpmProcessStateProvider; use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; use node_resolver::errors::PackageFolderResolveError; diff --git a/cli/npm/managed/resolvers/common/lifecycle_scripts.rs b/cli/npm/managed/resolvers/common/lifecycle_scripts.rs index f700d4bf9..b358c3585 100644 --- a/cli/npm/managed/resolvers/common/lifecycle_scripts.rs +++ b/cli/npm/managed/resolvers/common/lifecycle_scripts.rs @@ -2,7 +2,9 @@ use super::bin_entries::BinEntries; use crate::args::LifecycleScriptsConfig; +use deno_core::anyhow::Context; use deno_npm::resolution::NpmResolutionSnapshot; +use deno_runtime::deno_io::FromRawIoHandle; use deno_semver::package::PackageNv; use deno_semver::Version; use std::borrow::Cow; @@ -163,9 +165,24 @@ impl<'a> LifecycleScripts<'a> { ); let mut env_vars = crate::task_runner::real_env_vars(); + // we want to pass the current state of npm resolution down to the deno subprocess + // (that may be running as part of the script). we do this with an inherited temp file + // + // SAFETY: we are sharing a single temp file across all of the scripts. the file position + // will be shared among these, which is okay since we run only one script at a time. + // However, if we concurrently run scripts in the future we will + // have to have multiple temp files. + let temp_file_fd = + deno_runtime::ops::process::npm_process_state_tempfile( + process_state.as_bytes(), + ).context("failed to create npm process state tempfile for running lifecycle scripts")?; + // SAFETY: fd/handle is valid + let _temp_file = + unsafe { std::fs::File::from_raw_io_handle(temp_file_fd) }; // make sure the file gets closed env_vars.insert( - crate::args::NPM_RESOLUTION_STATE_ENV_VAR_NAME.to_string(), - process_state, + deno_runtime::ops::process::NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME + .to_string(), + (temp_file_fd as usize).to_string(), ); for (package, package_path) in self.packages_with_scripts { // add custom commands for binaries from the package's dependencies. this will take precedence over the diff --git a/cli/npm/mod.rs b/cli/npm/mod.rs index bedde6455..15ac8ebb2 100644 --- a/cli/npm/mod.rs +++ b/cli/npm/mod.rs @@ -14,7 +14,7 @@ use deno_core::error::AnyError; use deno_core::serde_json; use deno_npm::registry::NpmPackageInfo; use deno_runtime::deno_node::NodeRequireResolver; -use deno_runtime::deno_node::NpmProcessStateProvider; +use deno_runtime::ops::process::NpmProcessStateProvider; use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; use node_resolver::NpmResolver; diff --git a/cli/worker.rs b/cli/worker.rs index 861419f1e..c355d18bd 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -29,6 +29,7 @@ use deno_runtime::deno_tls::RootCertStoreProvider; use deno_runtime::deno_web::BlobStore; use deno_runtime::fmt_errors::format_js_error; use deno_runtime::inspector_server::InspectorServer; +use deno_runtime::ops::process::NpmProcessStateProviderRc; use deno_runtime::ops::worker_host::CreateWebWorkerCb; use deno_runtime::permissions::RuntimePermissionDescriptorParser; use deno_runtime::web_worker::WebWorker; @@ -147,13 +148,13 @@ impl SharedWorkerState { NodeExtInitServices { node_require_resolver: self.npm_resolver.clone().into_require_resolver(), node_resolver: self.node_resolver.clone(), - npm_process_state_provider: self - .npm_resolver - .clone() - .into_process_state_provider(), npm_resolver: self.npm_resolver.clone().into_npm_resolver(), } } + + pub fn npm_process_state_provider(&self) -> NpmProcessStateProviderRc { + self.npm_resolver.clone().into_process_state_provider() + } } pub struct CliMainWorker { @@ -614,6 +615,7 @@ impl CliMainWorkerFactory { module_loader, fs: shared.fs.clone(), node_services: Some(shared.create_node_init_services()), + npm_process_state_provider: Some(shared.npm_process_state_provider()), get_error_class_fn: Some(&errors::get_error_class_name), cache_storage_dir, origin_storage_dir, @@ -820,6 +822,7 @@ fn create_web_worker_callback( strace_ops: shared.options.strace_ops.clone(), close_on_idle: args.close_on_idle, maybe_worker_metadata: args.maybe_worker_metadata, + npm_process_state_provider: Some(shared.npm_process_state_provider()), }; WebWorker::bootstrap_from_options( |