mirror of
https://github.com/denoland/deno.git
synced 2025-09-22 10:22:34 +00:00
refactor: allow deno_permissions to compile to wasm32-unknown-unknown (#29487)
Some checks are pending
ci / pre-build (push) Waiting to run
ci / test debug linux-aarch64 (push) Blocked by required conditions
ci / test release linux-aarch64 (push) Blocked by required conditions
ci / test debug macos-aarch64 (push) Blocked by required conditions
ci / test release macos-aarch64 (push) Blocked by required conditions
ci / bench release linux-x86_64 (push) Blocked by required conditions
ci / lint debug linux-x86_64 (push) Blocked by required conditions
ci / lint debug macos-x86_64 (push) Blocked by required conditions
ci / lint debug windows-x86_64 (push) Blocked by required conditions
ci / test debug linux-x86_64 (push) Blocked by required conditions
ci / test release linux-x86_64 (push) Blocked by required conditions
ci / test debug macos-x86_64 (push) Blocked by required conditions
ci / test release macos-x86_64 (push) Blocked by required conditions
ci / test debug windows-x86_64 (push) Blocked by required conditions
ci / test release windows-x86_64 (push) Blocked by required conditions
ci / build wasm32 (push) Blocked by required conditions
ci / publish canary (push) Blocked by required conditions
Some checks are pending
ci / pre-build (push) Waiting to run
ci / test debug linux-aarch64 (push) Blocked by required conditions
ci / test release linux-aarch64 (push) Blocked by required conditions
ci / test debug macos-aarch64 (push) Blocked by required conditions
ci / test release macos-aarch64 (push) Blocked by required conditions
ci / bench release linux-x86_64 (push) Blocked by required conditions
ci / lint debug linux-x86_64 (push) Blocked by required conditions
ci / lint debug macos-x86_64 (push) Blocked by required conditions
ci / lint debug windows-x86_64 (push) Blocked by required conditions
ci / test debug linux-x86_64 (push) Blocked by required conditions
ci / test release linux-x86_64 (push) Blocked by required conditions
ci / test debug macos-x86_64 (push) Blocked by required conditions
ci / test release macos-x86_64 (push) Blocked by required conditions
ci / test debug windows-x86_64 (push) Blocked by required conditions
ci / test release windows-x86_64 (push) Blocked by required conditions
ci / build wasm32 (push) Blocked by required conditions
ci / publish canary (push) Blocked by required conditions
This commit is contained in:
parent
437afebf5c
commit
cb23193f74
17 changed files with 411 additions and 106 deletions
32
Cargo.lock
generated
32
Cargo.lock
generated
|
@ -1850,9 +1850,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_doc"
|
name = "deno_doc"
|
||||||
version = "0.175.0"
|
version = "0.176.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "161ec3cf8d07fc08a24a2600586881d9abafd48a0cb778633883dc8c1665d6fe"
|
checksum = "95ce3b4ff0fee9bd2f2c73996739556d986e1486cdc74e44da2b8f3296ea28bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
@ -2000,9 +2000,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_graph"
|
name = "deno_graph"
|
||||||
version = "0.92.0"
|
version = "0.93.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51fed59054a55f3cbd0db096168c58836ca9f94c7b7c1b0730f63064d7dc0f9e"
|
checksum = "8f7b63c5334fd2ee41db14596a5b03c37ce90dff057c1da9f573de515a3bb2c0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"capacity_builder",
|
"capacity_builder",
|
||||||
|
@ -2529,15 +2529,18 @@ dependencies = [
|
||||||
"fqdn",
|
"fqdn",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
"nix 0.27.1",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"sys_traits",
|
||||||
|
"temp_deno_which",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"url",
|
"url",
|
||||||
"which",
|
|
||||||
"winapi",
|
"winapi",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2559,10 +2562,10 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"simd-json",
|
"simd-json",
|
||||||
|
"sys_traits",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"tokio",
|
"tokio",
|
||||||
"which",
|
|
||||||
"winapi",
|
"winapi",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
@ -3571,9 +3574,9 @@ checksum = "31ae425815400e5ed474178a7a22e275a9687086a12ca63ec793ff292d8fdae8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "eszip"
|
name = "eszip"
|
||||||
version = "0.89.0"
|
version = "0.90.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38d9ea60ba198add01557b0f9e4d4df3795bbdc58a4c6774fee46734accdd64d"
|
checksum = "c5a6b90a53591e5adf9884048a79c291305b2a576d69fbc2b85de31d1a6e8372"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
@ -8398,9 +8401,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sys_traits"
|
name = "sys_traits"
|
||||||
version = "0.1.12"
|
version = "0.1.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db83fa685d1637625266341c69bf6e810632f5a53502d5d03fde8fcbcd3153f2"
|
checksum = "b0f8c2c55b6b4dd67f0f8df8de9bdf00b16c8ea4fbc4be0c2133d5d3924be5d4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"filetime",
|
"filetime",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
|
@ -8452,6 +8455,15 @@ version = "0.13.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
|
checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "temp_deno_which"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "366c5ccd670145885feb6efd6bbf2478ed236c4c3839046fcc8e2a1a84c51091"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.10.1"
|
version = "3.10.1"
|
||||||
|
|
11
Cargo.toml
11
Cargo.toml
|
@ -59,9 +59,9 @@ deno_core = { version = "0.348.0" }
|
||||||
|
|
||||||
deno_cache_dir = "=0.21.0"
|
deno_cache_dir = "=0.21.0"
|
||||||
deno_config = { version = "=0.54.2", features = ["workspace"] }
|
deno_config = { version = "=0.54.2", features = ["workspace"] }
|
||||||
deno_doc = "=0.175.0"
|
deno_doc = "=0.176.0"
|
||||||
deno_error = "=0.5.7"
|
deno_error = "=0.5.7"
|
||||||
deno_graph = { version = "=0.92.0", default-features = false }
|
deno_graph = { version = "=0.93.0", default-features = false }
|
||||||
deno_lint = "=0.75.0"
|
deno_lint = "=0.75.0"
|
||||||
deno_lockfile = "=0.28.0"
|
deno_lockfile = "=0.28.0"
|
||||||
deno_media_type = { version = "=0.2.8", features = ["module_specifier"] }
|
deno_media_type = { version = "=0.2.8", features = ["module_specifier"] }
|
||||||
|
@ -74,7 +74,7 @@ deno_task_shell = "=0.23.0"
|
||||||
deno_terminal = "=0.2.2"
|
deno_terminal = "=0.2.2"
|
||||||
deno_unsync = "0.4.3"
|
deno_unsync = "0.4.3"
|
||||||
deno_whoami = "0.1.0"
|
deno_whoami = "0.1.0"
|
||||||
eszip = "=0.89.0"
|
eszip = "=0.90.0"
|
||||||
|
|
||||||
denokv_proto = "0.10.0"
|
denokv_proto = "0.10.0"
|
||||||
denokv_remote = "0.10.0"
|
denokv_remote = "0.10.0"
|
||||||
|
@ -237,8 +237,10 @@ simd-json = "0.14.0"
|
||||||
slab = "0.4"
|
slab = "0.4"
|
||||||
smallvec = "1.8"
|
smallvec = "1.8"
|
||||||
socket2 = { version = "0.5.3", features = ["all"] }
|
socket2 = { version = "0.5.3", features = ["all"] }
|
||||||
sys_traits = "=0.1.12"
|
sys_traits = "=0.1.14"
|
||||||
tar = "=0.4.43"
|
tar = "=0.4.43"
|
||||||
|
# temporarily using until https://github.com/harryfei/which-rs/pull/109 is released
|
||||||
|
temp_deno_which = { version = "0.1.0", default-features = false }
|
||||||
tempfile = "3.4.0"
|
tempfile = "3.4.0"
|
||||||
termcolor = "1.1.3"
|
termcolor = "1.1.3"
|
||||||
thiserror = "2.0.12"
|
thiserror = "2.0.12"
|
||||||
|
@ -265,7 +267,6 @@ weak-table = "0.3.2"
|
||||||
web-transport-proto = "0.2.3"
|
web-transport-proto = "0.2.3"
|
||||||
webpki-root-certs = "0.26.5"
|
webpki-root-certs = "0.26.5"
|
||||||
webpki-roots = "0.26"
|
webpki-roots = "0.26"
|
||||||
which = "6"
|
|
||||||
yoke = { version = "0.7.4", features = ["derive"] }
|
yoke = { version = "0.7.4", features = ["derive"] }
|
||||||
zeromq = { version = "=0.4.1", default-features = false, features = ["tcp-transport", "tokio-runtime"] }
|
zeromq = { version = "=0.4.1", default-features = false, features = ["tcp-transport", "tokio-runtime"] }
|
||||||
zip = { version = "2.4.1", default-features = false, features = ["flate2"] }
|
zip = { version = "2.4.1", default-features = false, features = ["flate2"] }
|
||||||
|
|
28
cli/cache/mod.rs
vendored
28
cli/cache/mod.rs
vendored
|
@ -4,7 +4,6 @@ use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use deno_ast::MediaType;
|
|
||||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||||
use deno_cache_dir::file_fetcher::FetchLocalOptions;
|
use deno_cache_dir::file_fetcher::FetchLocalOptions;
|
||||||
use deno_cache_dir::file_fetcher::FetchNoFollowErrorKind;
|
use deno_cache_dir::file_fetcher::FetchNoFollowErrorKind;
|
||||||
|
@ -75,7 +74,6 @@ pub struct FetchCacher {
|
||||||
file_fetcher: Arc<CliFileFetcher>,
|
file_fetcher: Arc<CliFileFetcher>,
|
||||||
global_http_cache: Arc<GlobalHttpCache>,
|
global_http_cache: Arc<GlobalHttpCache>,
|
||||||
in_npm_pkg_checker: DenoInNpmPackageChecker,
|
in_npm_pkg_checker: DenoInNpmPackageChecker,
|
||||||
module_info_cache: Arc<ModuleInfoCache>,
|
|
||||||
permissions: PermissionsContainer,
|
permissions: PermissionsContainer,
|
||||||
sys: CliSys,
|
sys: CliSys,
|
||||||
is_deno_publish: bool,
|
is_deno_publish: bool,
|
||||||
|
@ -87,7 +85,6 @@ impl FetchCacher {
|
||||||
file_fetcher: Arc<CliFileFetcher>,
|
file_fetcher: Arc<CliFileFetcher>,
|
||||||
global_http_cache: Arc<GlobalHttpCache>,
|
global_http_cache: Arc<GlobalHttpCache>,
|
||||||
in_npm_pkg_checker: DenoInNpmPackageChecker,
|
in_npm_pkg_checker: DenoInNpmPackageChecker,
|
||||||
module_info_cache: Arc<ModuleInfoCache>,
|
|
||||||
sys: CliSys,
|
sys: CliSys,
|
||||||
options: FetchCacherOptions,
|
options: FetchCacherOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -95,7 +92,6 @@ impl FetchCacher {
|
||||||
file_fetcher,
|
file_fetcher,
|
||||||
global_http_cache,
|
global_http_cache,
|
||||||
in_npm_pkg_checker,
|
in_npm_pkg_checker,
|
||||||
module_info_cache,
|
|
||||||
sys,
|
sys,
|
||||||
file_header_overrides: options.file_header_overrides,
|
file_header_overrides: options.file_header_overrides,
|
||||||
permissions: options.permissions,
|
permissions: options.permissions,
|
||||||
|
@ -287,28 +283,4 @@ impl Loader for FetchCacher {
|
||||||
}
|
}
|
||||||
.boxed_local()
|
.boxed_local()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cache_module_info(
|
|
||||||
&self,
|
|
||||||
specifier: &ModuleSpecifier,
|
|
||||||
media_type: MediaType,
|
|
||||||
source: &Arc<[u8]>,
|
|
||||||
module_info: &deno_graph::ModuleInfo,
|
|
||||||
) {
|
|
||||||
log::debug!("Caching module info for {}", specifier);
|
|
||||||
let source_hash = CacheDBHash::from_hashable(source);
|
|
||||||
let result = self.module_info_cache.set_module_info(
|
|
||||||
specifier,
|
|
||||||
media_type,
|
|
||||||
source_hash,
|
|
||||||
module_info,
|
|
||||||
);
|
|
||||||
if let Err(err) = result {
|
|
||||||
log::debug!(
|
|
||||||
"Error saving module cache info for {}. {:#}",
|
|
||||||
specifier,
|
|
||||||
err
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
22
cli/cache/module_info.rs
vendored
22
cli/cache/module_info.rs
vendored
|
@ -136,6 +136,28 @@ impl ModuleInfoCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl deno_graph::source::ModuleInfoCacher for ModuleInfoCache {
|
||||||
|
fn cache_module_info(
|
||||||
|
&self,
|
||||||
|
specifier: &ModuleSpecifier,
|
||||||
|
media_type: MediaType,
|
||||||
|
source: &Arc<[u8]>,
|
||||||
|
module_info: &deno_graph::ModuleInfo,
|
||||||
|
) {
|
||||||
|
log::debug!("Caching module info for {}", specifier);
|
||||||
|
let source_hash = CacheDBHash::from_hashable(source);
|
||||||
|
let result =
|
||||||
|
self.set_module_info(specifier, media_type, source_hash, module_info);
|
||||||
|
if let Err(err) = result {
|
||||||
|
log::debug!(
|
||||||
|
"Error saving module cache info for {}. {:#}",
|
||||||
|
specifier,
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ModuleInfoCacheModuleAnalyzer<'a> {
|
pub struct ModuleInfoCacheModuleAnalyzer<'a> {
|
||||||
module_info_cache: &'a ModuleInfoCache,
|
module_info_cache: &'a ModuleInfoCache,
|
||||||
parsed_source_cache: &'a Arc<ParsedSourceCache>,
|
parsed_source_cache: &'a Arc<ParsedSourceCache>,
|
||||||
|
|
|
@ -816,6 +816,7 @@ impl ModuleGraphBuilder {
|
||||||
jsr_url_provider: &CliJsrUrlProvider,
|
jsr_url_provider: &CliJsrUrlProvider,
|
||||||
npm_resolver: Some(self.npm_graph_resolver.as_ref()),
|
npm_resolver: Some(self.npm_graph_resolver.as_ref()),
|
||||||
module_analyzer: &analyzer,
|
module_analyzer: &analyzer,
|
||||||
|
module_info_cacher: self.module_info_cache.as_ref(),
|
||||||
reporter: maybe_file_watcher_reporter,
|
reporter: maybe_file_watcher_reporter,
|
||||||
resolver: Some(&graph_resolver),
|
resolver: Some(&graph_resolver),
|
||||||
locker: locker.as_mut().map(|l| l as _),
|
locker: locker.as_mut().map(|l| l as _),
|
||||||
|
@ -998,7 +999,6 @@ impl ModuleGraphBuilder {
|
||||||
self.file_fetcher.clone(),
|
self.file_fetcher.clone(),
|
||||||
self.global_http_cache.clone(),
|
self.global_http_cache.clone(),
|
||||||
self.in_npm_pkg_checker.clone(),
|
self.in_npm_pkg_checker.clone(),
|
||||||
self.module_info_cache.clone(),
|
|
||||||
self.sys.clone(),
|
self.sys.clone(),
|
||||||
cache::FetchCacherOptions {
|
cache::FetchCacherOptions {
|
||||||
file_header_overrides: self.cli_options.resolve_file_header_overrides(),
|
file_header_overrides: self.cli_options.resolve_file_header_overrides(),
|
||||||
|
|
|
@ -1899,21 +1899,6 @@ impl deno_graph::source::Loader for OpenDocumentsGraphLoader<'_> {
|
||||||
None => self.inner_loader.load(specifier, options),
|
None => self.inner_loader.load(specifier, options),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cache_module_info(
|
|
||||||
&self,
|
|
||||||
specifier: &deno_ast::ModuleSpecifier,
|
|
||||||
media_type: MediaType,
|
|
||||||
source: &Arc<[u8]>,
|
|
||||||
module_info: &deno_graph::ModuleInfo,
|
|
||||||
) {
|
|
||||||
self.inner_loader.cache_module_info(
|
|
||||||
specifier,
|
|
||||||
media_type,
|
|
||||||
source,
|
|
||||||
module_info,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_and_analyze_module(
|
fn parse_and_analyze_module(
|
||||||
|
|
|
@ -582,7 +582,7 @@ impl sys_traits::BaseFsReadDir for DenoRtSys {
|
||||||
&self,
|
&self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
) -> std::io::Result<
|
) -> std::io::Result<
|
||||||
Box<dyn Iterator<Item = std::io::Result<Self::ReadDirEntry>> + '_>,
|
Box<dyn Iterator<Item = std::io::Result<Self::ReadDirEntry>>>,
|
||||||
> {
|
> {
|
||||||
if self.0.is_path_within(path) {
|
if self.0.is_path_within(path) {
|
||||||
let entries = self.0.read_dir_with_metadata(path)?;
|
let entries = self.0.read_dir_with_metadata(path)?;
|
||||||
|
@ -905,12 +905,21 @@ impl sys_traits::ThreadSleep for DenoRtSys {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl sys_traits::EnvCurrentDir for DenoRtSys {
|
impl sys_traits::EnvCurrentDir for DenoRtSys {
|
||||||
|
#[inline]
|
||||||
fn env_current_dir(&self) -> std::io::Result<PathBuf> {
|
fn env_current_dir(&self) -> std::io::Result<PathBuf> {
|
||||||
#[allow(clippy::disallowed_types)] // ok because we're implementing the fs
|
#[allow(clippy::disallowed_types)] // ok because we're implementing the fs
|
||||||
sys_traits::impls::RealSys.env_current_dir()
|
sys_traits::impls::RealSys.env_current_dir()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl sys_traits::EnvHomeDir for DenoRtSys {
|
||||||
|
#[inline]
|
||||||
|
fn env_home_dir(&self) -> Option<PathBuf> {
|
||||||
|
#[allow(clippy::disallowed_types)] // ok because we're implementing the fs
|
||||||
|
sys_traits::impls::RealSys.env_home_dir()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl sys_traits::BaseEnvVar for DenoRtSys {
|
impl sys_traits::BaseEnvVar for DenoRtSys {
|
||||||
fn base_env_var_os(
|
fn base_env_var_os(
|
||||||
&self,
|
&self,
|
||||||
|
@ -1381,16 +1390,23 @@ impl FileBackedVfs {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_dir_with_metadata<'a>(
|
pub fn read_dir_with_metadata(
|
||||||
&'a self,
|
&self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
) -> std::io::Result<impl Iterator<Item = FileBackedVfsDirEntry> + 'a> {
|
) -> std::io::Result<impl Iterator<Item = FileBackedVfsDirEntry>> {
|
||||||
let dir = self.dir_entry(path)?;
|
let dir = self.dir_entry(path)?;
|
||||||
let path = path.to_path_buf();
|
let path = path.to_path_buf();
|
||||||
Ok(dir.entries.iter().map(move |entry| FileBackedVfsDirEntry {
|
Ok(
|
||||||
|
dir
|
||||||
|
.entries
|
||||||
|
.iter()
|
||||||
|
.map(move |entry| FileBackedVfsDirEntry {
|
||||||
parent_path: path.to_path_buf(),
|
parent_path: path.to_path_buf(),
|
||||||
metadata: FileBackedVfsMetadata::from_vfs_entry_ref(entry.as_ref()),
|
metadata: FileBackedVfsMetadata::from_vfs_entry_ref(entry.as_ref()),
|
||||||
}))
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into_iter(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_link(&self, path: &Path) -> std::io::Result<PathBuf> {
|
pub fn read_link(&self, path: &Path) -> std::io::Result<PathBuf> {
|
||||||
|
|
|
@ -81,6 +81,7 @@ async fn generate_doc_nodes_for_builtin_types(
|
||||||
jsr_url_provider: Default::default(),
|
jsr_url_provider: Default::default(),
|
||||||
locker: None,
|
locker: None,
|
||||||
module_analyzer: analyzer,
|
module_analyzer: analyzer,
|
||||||
|
module_info_cacher: Default::default(),
|
||||||
npm_resolver: None,
|
npm_resolver: None,
|
||||||
reporter: None,
|
reporter: None,
|
||||||
resolver: None,
|
resolver: None,
|
||||||
|
|
|
@ -28,10 +28,10 @@ pin-project-lite.workspace = true
|
||||||
rand.workspace = true
|
rand.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
simd-json.workspace = true
|
simd-json.workspace = true
|
||||||
|
sys_traits = { workspace = true, features = ["real", "winapi", "libc"] }
|
||||||
tempfile.workspace = true
|
tempfile.workspace = true
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
which.workspace = true
|
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
nix = { workspace = true, features = ["signal", "process"] }
|
nix = { workspace = true, features = ["signal", "process"] }
|
||||||
|
|
|
@ -254,7 +254,7 @@ pub enum ProcessError {
|
||||||
BorrowMut(std::cell::BorrowMutError),
|
BorrowMut(std::cell::BorrowMutError),
|
||||||
#[class(generic)]
|
#[class(generic)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Which(which::Error),
|
Which(deno_permissions::which::Error),
|
||||||
#[class(type)]
|
#[class(type)]
|
||||||
#[error("Child process has already terminated.")]
|
#[error("Child process has already terminated.")]
|
||||||
ChildProcessAlreadyTerminated,
|
ChildProcessAlreadyTerminated,
|
||||||
|
@ -800,9 +800,14 @@ fn resolve_cmd(cmd: &str, env: &RunEnv) -> Result<PathBuf, ProcessError> {
|
||||||
Ok(resolve_path(cmd, &env.cwd))
|
Ok(resolve_path(cmd, &env.cwd))
|
||||||
} else {
|
} else {
|
||||||
let path = env.envs.get(&EnvVarKey::new(OsString::from("PATH")));
|
let path = env.envs.get(&EnvVarKey::new(OsString::from("PATH")));
|
||||||
match which::which_in(cmd, path, &env.cwd) {
|
match deno_permissions::which::which_in(
|
||||||
|
sys_traits::impls::RealSys,
|
||||||
|
cmd,
|
||||||
|
path.cloned(),
|
||||||
|
env.cwd.clone(),
|
||||||
|
) {
|
||||||
Ok(cmd) => Ok(cmd),
|
Ok(cmd) => Ok(cmd),
|
||||||
Err(which::Error::CannotFindBinaryPath) => {
|
Err(deno_permissions::which::Error::CannotFindBinaryPath) => {
|
||||||
Err(std::io::Error::from(std::io::ErrorKind::NotFound).into())
|
Err(std::io::Error::from(std::io::ErrorKind::NotFound).into())
|
||||||
}
|
}
|
||||||
Err(err) => Err(ProcessError::Which(err)),
|
Err(err) => Err(ProcessError::Which(err)),
|
||||||
|
|
|
@ -180,7 +180,7 @@ impl<TSys: FsReadDir> BaseFsReadDir for NodeResolutionSys<TSys> {
|
||||||
&self,
|
&self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
) -> std::io::Result<
|
) -> std::io::Result<
|
||||||
Box<dyn Iterator<Item = std::io::Result<Self::ReadDirEntry>> + '_>,
|
Box<dyn Iterator<Item = std::io::Result<Self::ReadDirEntry>>>,
|
||||||
> {
|
> {
|
||||||
self.sys.base_fs_read_dir(path)
|
self.sys.base_fs_read_dir(path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,12 @@ use deno_permissions::WriteDescriptor;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RuntimePermissionDescriptorParser<
|
pub struct RuntimePermissionDescriptorParser<
|
||||||
TSys: sys_traits::EnvCurrentDir + Send + Sync,
|
TSys: deno_permissions::which::WhichSys + Send + Sync,
|
||||||
> {
|
> {
|
||||||
sys: TSys,
|
sys: TSys,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TSys: sys_traits::EnvCurrentDir + Send + Sync>
|
impl<TSys: deno_permissions::which::WhichSys + Send + Sync>
|
||||||
RuntimePermissionDescriptorParser<TSys>
|
RuntimePermissionDescriptorParser<TSys>
|
||||||
{
|
{
|
||||||
pub fn new(sys: TSys) -> Self {
|
pub fn new(sys: TSys) -> Self {
|
||||||
|
@ -55,7 +55,7 @@ impl<TSys: sys_traits::EnvCurrentDir + Send + Sync>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TSys: sys_traits::EnvCurrentDir + Send + Sync + std::fmt::Debug>
|
impl<TSys: deno_permissions::which::WhichSys + Send + Sync + std::fmt::Debug>
|
||||||
deno_permissions::PermissionDescriptorParser
|
deno_permissions::PermissionDescriptorParser
|
||||||
for RuntimePermissionDescriptorParser<TSys>
|
for RuntimePermissionDescriptorParser<TSys>
|
||||||
{
|
{
|
||||||
|
@ -113,7 +113,11 @@ impl<TSys: sys_traits::EnvCurrentDir + Send + Sync + std::fmt::Debug>
|
||||||
&self,
|
&self,
|
||||||
text: &str,
|
text: &str,
|
||||||
) -> Result<AllowRunDescriptorParseResult, RunDescriptorParseError> {
|
) -> Result<AllowRunDescriptorParseResult, RunDescriptorParseError> {
|
||||||
Ok(AllowRunDescriptor::parse(text, &self.resolve_cwd()?)?)
|
Ok(AllowRunDescriptor::parse(
|
||||||
|
text,
|
||||||
|
&self.resolve_cwd()?,
|
||||||
|
&self.sys,
|
||||||
|
)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_deny_run_descriptor(
|
fn parse_deny_run_descriptor(
|
||||||
|
@ -149,7 +153,7 @@ impl<TSys: sys_traits::EnvCurrentDir + Send + Sync + std::fmt::Debug>
|
||||||
if requested.is_empty() {
|
if requested.is_empty() {
|
||||||
return Err(RunDescriptorParseError::EmptyRunQuery);
|
return Err(RunDescriptorParseError::EmptyRunQuery);
|
||||||
}
|
}
|
||||||
RunQueryDescriptor::parse(requested)
|
RunQueryDescriptor::parse(requested, &self.sys)
|
||||||
.map_err(RunDescriptorParseError::PathResolve)
|
.map_err(RunDescriptorParseError::PathResolve)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,17 @@ parking_lot.workspace = true
|
||||||
percent-encoding = { workspace = true, features = [] }
|
percent-encoding = { workspace = true, features = [] }
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
sys_traits.workspace = true
|
||||||
|
temp_deno_which.workspace = true
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
url.workspace = true
|
url.workspace = true
|
||||||
which.workspace = true
|
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { workspace = true, features = ["commapi", "knownfolders", "mswsock", "objbase", "psapi", "shlobj", "tlhelp32", "winbase", "winerror", "winuser", "winsock2", "processenv", "wincon", "wincontypes"] }
|
winapi = { workspace = true, features = ["commapi", "knownfolders", "mswsock", "objbase", "psapi", "shlobj", "tlhelp32", "winbase", "winerror", "winuser", "winsock2", "processenv", "wincon", "wincontypes"] }
|
||||||
|
windows-sys = { workspace = true, features = ["Win32_Storage_FileSystem"] }
|
||||||
|
|
||||||
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
nix = { workspace = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
sys_traits = { workspace = true, features = ["real"] }
|
||||||
|
|
|
@ -1,3 +1,49 @@
|
||||||
disallowed-methods = [
|
disallowed-methods = [
|
||||||
{ path = "std::str::FromStr", reason = "Don't want to have stuff like `'0.0.0.0'.parse().unwrap()`. Instead implement ConcreteType::parse methods." },
|
{ path = "std::str::FromStr", reason = "Don't want to have stuff like `'0.0.0.0'.parse().unwrap()`. Instead implement ConcreteType::parse methods." },
|
||||||
|
{ path = "std::env::current_dir", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::Path::canonicalize", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::Path::is_dir", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::Path::is_file", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::Path::is_symlink", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::Path::metadata", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::Path::read_dir", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::Path::read_link", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::Path::symlink_metadata", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::Path::try_exists", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::PathBuf::exists", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::PathBuf::canonicalize", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::PathBuf::is_dir", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::PathBuf::is_file", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::PathBuf::is_symlink", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::PathBuf::metadata", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::PathBuf::read_dir", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::PathBuf::read_link", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::PathBuf::symlink_metadata", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::PathBuf::try_exists", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::env::set_current_dir", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::env::temp_dir", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::canonicalize", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::copy", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::create_dir_all", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::create_dir", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::DirBuilder::new", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::hard_link", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::metadata", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::OpenOptions::new", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::read_dir", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::read_link", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::read_to_string", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::read", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::remove_dir_all", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::remove_dir", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::remove_file", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::rename", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::set_permissions", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::symlink_metadata", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::fs::write", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::Path::canonicalize", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "std::path::Path::exists", reason = "File system operations should be done using sys_traits" },
|
||||||
|
{ path = "url::Url::to_file_path", reason = "Use deno_path_util instead so it works in Wasm" },
|
||||||
|
{ path = "url::Url::from_file_path", reason = "Use deno_path_util instead so it works in Wasm" },
|
||||||
|
{ path = "url::Url::from_directory_path", reason = "Use deno_path_util instead so it works in Wasm" },
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,15 +28,19 @@ use serde::Serialize;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub mod prompter;
|
pub mod prompter;
|
||||||
|
pub mod which;
|
||||||
use prompter::permission_prompt;
|
use prompter::permission_prompt;
|
||||||
pub use prompter::set_prompt_callbacks;
|
pub use prompter::set_prompt_callbacks;
|
||||||
pub use prompter::set_prompter;
|
pub use prompter::set_prompter;
|
||||||
|
pub use prompter::DeniedPrompter;
|
||||||
pub use prompter::GetFormattedStackFn;
|
pub use prompter::GetFormattedStackFn;
|
||||||
pub use prompter::PermissionPrompter;
|
pub use prompter::PermissionPrompter;
|
||||||
pub use prompter::PromptCallback;
|
pub use prompter::PromptCallback;
|
||||||
pub use prompter::PromptResponse;
|
pub use prompter::PromptResponse;
|
||||||
use prompter::PERMISSION_EMOJI;
|
use prompter::PERMISSION_EMOJI;
|
||||||
|
|
||||||
|
use self::which::WhichSys;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum PermissionDeniedError {
|
pub enum PermissionDeniedError {
|
||||||
#[error("Requires {access}, {}", format_permission_error(.name))]
|
#[error("Requires {access}, {}", format_permission_error(.name))]
|
||||||
|
@ -1373,14 +1377,16 @@ pub enum PathResolveError {
|
||||||
impl RunQueryDescriptor {
|
impl RunQueryDescriptor {
|
||||||
pub fn parse(
|
pub fn parse(
|
||||||
requested: &str,
|
requested: &str,
|
||||||
|
sys: &impl which::WhichSys,
|
||||||
) -> Result<RunQueryDescriptor, PathResolveError> {
|
) -> Result<RunQueryDescriptor, PathResolveError> {
|
||||||
if is_path(requested) {
|
if is_path(requested) {
|
||||||
let path = PathBuf::from(requested);
|
let path = PathBuf::from(requested);
|
||||||
let resolved = if path.is_absolute() {
|
let resolved = if path.is_absolute() {
|
||||||
normalize_path(path)
|
normalize_path(path)
|
||||||
} else {
|
} else {
|
||||||
let cwd =
|
let cwd = sys
|
||||||
std::env::current_dir().map_err(PathResolveError::CwdResolve)?;
|
.env_current_dir()
|
||||||
|
.map_err(PathResolveError::CwdResolve)?;
|
||||||
normalize_path(cwd.join(path))
|
normalize_path(cwd.join(path))
|
||||||
};
|
};
|
||||||
Ok(RunQueryDescriptor::Path {
|
Ok(RunQueryDescriptor::Path {
|
||||||
|
@ -1388,7 +1394,11 @@ impl RunQueryDescriptor {
|
||||||
resolved,
|
resolved,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
match which::which(requested) {
|
let cwd = sys
|
||||||
|
.env_current_dir()
|
||||||
|
.map_err(PathResolveError::CwdResolve)?;
|
||||||
|
match which::which_in(sys.clone(), requested, sys.env_var_os("PATH"), cwd)
|
||||||
|
{
|
||||||
Ok(resolved) => Ok(RunQueryDescriptor::Path {
|
Ok(resolved) => Ok(RunQueryDescriptor::Path {
|
||||||
requested: requested.to_string(),
|
requested: requested.to_string(),
|
||||||
resolved,
|
resolved,
|
||||||
|
@ -1542,13 +1552,19 @@ impl AllowRunDescriptor {
|
||||||
pub fn parse(
|
pub fn parse(
|
||||||
text: &str,
|
text: &str,
|
||||||
cwd: &Path,
|
cwd: &Path,
|
||||||
|
sys: &impl WhichSys,
|
||||||
) -> Result<AllowRunDescriptorParseResult, which::Error> {
|
) -> Result<AllowRunDescriptorParseResult, which::Error> {
|
||||||
let is_path = is_path(text);
|
let is_path = is_path(text);
|
||||||
// todo(dsherret): canonicalize in #25458
|
// todo(dsherret): canonicalize in #25458
|
||||||
let path = if is_path {
|
let path = if is_path {
|
||||||
resolve_from_known_cwd(Path::new(text), cwd)
|
resolve_from_known_cwd(Path::new(text), cwd)
|
||||||
} else {
|
} else {
|
||||||
match which::which_in(text, std::env::var_os("PATH"), cwd) {
|
match which::which_in(
|
||||||
|
sys.clone(),
|
||||||
|
text,
|
||||||
|
sys.env_var_os("PATH"),
|
||||||
|
cwd.to_path_buf(),
|
||||||
|
) {
|
||||||
Ok(path) => path,
|
Ok(path) => path,
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
which::Error::CannotGetCurrentDirAndPathListEmpty => {
|
which::Error::CannotGetCurrentDirAndPathListEmpty => {
|
||||||
|
@ -3879,7 +3895,8 @@ mod tests {
|
||||||
&self,
|
&self,
|
||||||
requested: &str,
|
requested: &str,
|
||||||
) -> Result<RunQueryDescriptor, RunDescriptorParseError> {
|
) -> Result<RunQueryDescriptor, RunDescriptorParseError> {
|
||||||
RunQueryDescriptor::parse(requested).map_err(Into::into)
|
RunQueryDescriptor::parse(requested, &sys_traits::impls::RealSys)
|
||||||
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,13 @@
|
||||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||||
|
|
||||||
use std::fmt::Write;
|
|
||||||
use std::io::BufRead;
|
|
||||||
use std::io::IsTerminal;
|
|
||||||
use std::io::StderrLock;
|
|
||||||
use std::io::StdinLock;
|
|
||||||
use std::io::Write as IoWrite;
|
|
||||||
|
|
||||||
use deno_terminal::colors;
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
use crate::is_standalone;
|
|
||||||
|
|
||||||
/// Helper function to make control characters visible so users can see the underlying filename.
|
/// Helper function to make control characters visible so users can see the underlying filename.
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
fn escape_control_characters(s: &str) -> std::borrow::Cow<str> {
|
fn escape_control_characters(s: &str) -> std::borrow::Cow<str> {
|
||||||
|
use deno_terminal::colors;
|
||||||
|
|
||||||
if !s.contains(|c: char| c.is_ascii_control() || c.is_control()) {
|
if !s.contains(|c: char| c.is_ascii_control() || c.is_control()) {
|
||||||
return std::borrow::Cow::Borrowed(s);
|
return std::borrow::Cow::Borrowed(s);
|
||||||
}
|
}
|
||||||
|
@ -35,9 +28,6 @@ fn escape_control_characters(s: &str) -> std::borrow::Cow<str> {
|
||||||
|
|
||||||
pub const PERMISSION_EMOJI: &str = "⚠️";
|
pub const PERMISSION_EMOJI: &str = "⚠️";
|
||||||
|
|
||||||
// 10kB of permission prompting should be enough for anyone
|
|
||||||
const MAX_PERMISSION_PROMPT_LENGTH: usize = 10 * 1024;
|
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub enum PromptResponse {
|
pub enum PromptResponse {
|
||||||
Allow,
|
Allow,
|
||||||
|
@ -45,8 +35,13 @@ pub enum PromptResponse {
|
||||||
AllowAll,
|
AllowAll,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
type DefaultPrompter = TtyPrompter;
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
type DefaultPrompter = DeniedPrompter;
|
||||||
|
|
||||||
static PERMISSION_PROMPTER: Lazy<Mutex<Box<dyn PermissionPrompter>>> =
|
static PERMISSION_PROMPTER: Lazy<Mutex<Box<dyn PermissionPrompter>>> =
|
||||||
Lazy::new(|| Mutex::new(Box::new(TtyPrompter)));
|
Lazy::new(|| Mutex::new(Box::new(DefaultPrompter::default())));
|
||||||
|
|
||||||
static MAYBE_BEFORE_PROMPT_CALLBACK: Lazy<Mutex<Option<PromptCallback>>> =
|
static MAYBE_BEFORE_PROMPT_CALLBACK: Lazy<Mutex<Option<PromptCallback>>> =
|
||||||
Lazy::new(|| Mutex::new(None));
|
Lazy::new(|| Mutex::new(None));
|
||||||
|
@ -107,12 +102,26 @@ pub trait PermissionPrompter: Send + Sync {
|
||||||
) -> PromptResponse;
|
) -> PromptResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TtyPrompter;
|
#[derive(Default)]
|
||||||
|
pub struct DeniedPrompter;
|
||||||
|
|
||||||
|
impl PermissionPrompter for DeniedPrompter {
|
||||||
|
fn prompt(
|
||||||
|
&mut self,
|
||||||
|
_message: &str,
|
||||||
|
_name: &str,
|
||||||
|
_api_name: Option<&str>,
|
||||||
|
_is_unary: bool,
|
||||||
|
_get_stack: Option<GetFormattedStackFn>,
|
||||||
|
) -> PromptResponse {
|
||||||
|
PromptResponse::Deny
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn clear_stdin(
|
fn clear_stdin(
|
||||||
_stdin_lock: &mut StdinLock,
|
_stdin_lock: &mut std::io::StdinLock,
|
||||||
_stderr_lock: &mut StderrLock,
|
_stderr_lock: &mut std::io::StderrLock,
|
||||||
) -> Result<(), std::io::Error> {
|
) -> Result<(), std::io::Error> {
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
|
|
||||||
|
@ -163,11 +172,15 @@ fn clear_stdin(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(all(not(unix), not(target_arch = "wasm32")))]
|
||||||
fn clear_stdin(
|
fn clear_stdin(
|
||||||
stdin_lock: &mut StdinLock,
|
stdin_lock: &mut std::io::StdinLock,
|
||||||
stderr_lock: &mut StderrLock,
|
stderr_lock: &mut std::io::StderrLock,
|
||||||
) -> Result<(), std::io::Error> {
|
) -> Result<(), std::io::Error> {
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::io::StdinLock;
|
||||||
|
use std::io::Write as IoWrite;
|
||||||
|
|
||||||
use winapi::shared::minwindef::TRUE;
|
use winapi::shared::minwindef::TRUE;
|
||||||
use winapi::shared::minwindef::UINT;
|
use winapi::shared::minwindef::UINT;
|
||||||
use winapi::shared::minwindef::WORD;
|
use winapi::shared::minwindef::WORD;
|
||||||
|
@ -257,7 +270,7 @@ fn clear_stdin(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_cursor_up(
|
fn move_cursor_up(
|
||||||
stderr_lock: &mut StderrLock,
|
stderr_lock: &mut std::io::StderrLock,
|
||||||
) -> Result<(), std::io::Error> {
|
) -> Result<(), std::io::Error> {
|
||||||
write!(stderr_lock, "\x1B[1A")
|
write!(stderr_lock, "\x1B[1A")
|
||||||
}
|
}
|
||||||
|
@ -270,7 +283,9 @@ fn clear_stdin(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear n-lines in terminal and move cursor to the beginning of the line.
|
// Clear n-lines in terminal and move cursor to the beginning of the line.
|
||||||
fn clear_n_lines(stderr_lock: &mut StderrLock, n: usize) {
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
fn clear_n_lines(stderr_lock: &mut std::io::StderrLock, n: usize) {
|
||||||
|
use std::io::Write;
|
||||||
write!(stderr_lock, "\x1B[{n}A\x1B[0J").unwrap();
|
write!(stderr_lock, "\x1B[{n}A\x1B[0J").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,6 +304,11 @@ fn get_stdin_metadata() -> std::io::Result<std::fs::Metadata> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct TtyPrompter;
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
impl PermissionPrompter for TtyPrompter {
|
impl PermissionPrompter for TtyPrompter {
|
||||||
fn prompt(
|
fn prompt(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -298,6 +318,16 @@ impl PermissionPrompter for TtyPrompter {
|
||||||
is_unary: bool,
|
is_unary: bool,
|
||||||
get_stack: Option<GetFormattedStackFn>,
|
get_stack: Option<GetFormattedStackFn>,
|
||||||
) -> PromptResponse {
|
) -> PromptResponse {
|
||||||
|
use std::fmt::Write;
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::io::IsTerminal;
|
||||||
|
use std::io::Write as IoWrite;
|
||||||
|
|
||||||
|
use deno_terminal::colors;
|
||||||
|
|
||||||
|
// 10kB of permission prompting should be enough for anyone
|
||||||
|
const MAX_PERMISSION_PROMPT_LENGTH: usize = 10 * 1024;
|
||||||
|
|
||||||
if !std::io::stdin().is_terminal() || !std::io::stderr().is_terminal() {
|
if !std::io::stdin().is_terminal() || !std::io::stderr().is_terminal() {
|
||||||
return PromptResponse::Deny;
|
return PromptResponse::Deny;
|
||||||
};
|
};
|
||||||
|
@ -381,7 +411,7 @@ impl PermissionPrompter for TtyPrompter {
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
writeln!(&mut output, "┠─ {}", colors::italic(&msg)).unwrap();
|
writeln!(&mut output, "┠─ {}", colors::italic(&msg)).unwrap();
|
||||||
let msg = if is_standalone() {
|
let msg = if crate::is_standalone() {
|
||||||
format!("Specify the required permissions during compile time using `deno compile --allow-{name}`.")
|
format!("Specify the required permissions during compile time using `deno compile --allow-{name}`.")
|
||||||
} else {
|
} else {
|
||||||
format!("Run again with --allow-{name} to bypass this prompt.")
|
format!("Run again with --allow-{name} to bypass this prompt.")
|
||||||
|
|
186
runtime/permissions/which.rs
Normal file
186
runtime/permissions/which.rs
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||||
|
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
use std::ffi::OsString;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use temp_deno_which::sys::Sys;
|
||||||
|
pub use temp_deno_which::Error;
|
||||||
|
|
||||||
|
pub fn which_in(
|
||||||
|
sys: impl WhichSys,
|
||||||
|
binary_name: &str,
|
||||||
|
path: Option<OsString>,
|
||||||
|
cwd: PathBuf,
|
||||||
|
) -> Result<PathBuf, Error> {
|
||||||
|
let sys = WhichSysAdapter(sys);
|
||||||
|
let config = temp_deno_which::WhichConfig::new_with_sys(sys)
|
||||||
|
.custom_cwd(cwd)
|
||||||
|
.binary_name(OsString::from(binary_name));
|
||||||
|
let config = match path {
|
||||||
|
Some(path) => config.custom_path_list(path),
|
||||||
|
None => config,
|
||||||
|
};
|
||||||
|
config.first_result()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[sys_traits::auto_impl]
|
||||||
|
pub trait WhichSys:
|
||||||
|
sys_traits::EnvHomeDir
|
||||||
|
+ sys_traits::EnvCurrentDir
|
||||||
|
+ sys_traits::EnvVar
|
||||||
|
+ sys_traits::FsReadDir
|
||||||
|
+ sys_traits::FsMetadata
|
||||||
|
+ Clone
|
||||||
|
+ 'static
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct WhichSysAdapter<TSys: WhichSys>(TSys);
|
||||||
|
|
||||||
|
impl<TSys: WhichSys> Sys for WhichSysAdapter<TSys> {
|
||||||
|
type ReadDirEntry = WhichReadDirEntrySysAdapter<TSys::ReadDirEntry>;
|
||||||
|
|
||||||
|
type Metadata = WhichMetadataSysAdapter<TSys::Metadata>;
|
||||||
|
|
||||||
|
fn is_windows(&self) -> bool {
|
||||||
|
sys_traits::impls::is_windows()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_dir(&self) -> std::io::Result<std::path::PathBuf> {
|
||||||
|
self.0.env_current_dir()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn home_dir(&self) -> Option<std::path::PathBuf> {
|
||||||
|
self.0.env_home_dir()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn env_split_paths(&self, paths: &OsStr) -> Vec<std::path::PathBuf> {
|
||||||
|
if cfg!(target_arch = "wasm32") && self.is_windows() {
|
||||||
|
// not perfect, but good enough
|
||||||
|
paths
|
||||||
|
.to_string_lossy()
|
||||||
|
.split(";")
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
std::env::split_paths(paths).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn env_var_os(&self, name: &OsStr) -> Option<std::ffi::OsString> {
|
||||||
|
self.0.env_var_os(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(
|
||||||
|
&self,
|
||||||
|
path: &std::path::Path,
|
||||||
|
) -> std::io::Result<Self::Metadata> {
|
||||||
|
self.0.fs_metadata(path).map(WhichMetadataSysAdapter)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn symlink_metadata(
|
||||||
|
&self,
|
||||||
|
path: &std::path::Path,
|
||||||
|
) -> std::io::Result<Self::Metadata> {
|
||||||
|
self
|
||||||
|
.0
|
||||||
|
.fs_symlink_metadata(path)
|
||||||
|
.map(WhichMetadataSysAdapter)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_dir(
|
||||||
|
&self,
|
||||||
|
path: &std::path::Path,
|
||||||
|
) -> std::io::Result<
|
||||||
|
Box<dyn Iterator<Item = std::io::Result<Self::ReadDirEntry>>>,
|
||||||
|
> {
|
||||||
|
let iter = self.0.fs_read_dir(path)?;
|
||||||
|
let iter = Box::new(
|
||||||
|
iter
|
||||||
|
.into_iter()
|
||||||
|
.map(|value| value.map(WhichReadDirEntrySysAdapter)),
|
||||||
|
);
|
||||||
|
Ok(iter)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn is_valid_executable(
|
||||||
|
&self,
|
||||||
|
path: &std::path::Path,
|
||||||
|
) -> std::io::Result<bool> {
|
||||||
|
use nix::unistd::access;
|
||||||
|
use nix::unistd::AccessFlags;
|
||||||
|
|
||||||
|
match access(path, AccessFlags::X_OK) {
|
||||||
|
Ok(()) => Ok(true),
|
||||||
|
Err(nix::errno::Errno::ENOENT) => Ok(false),
|
||||||
|
Err(e) => Err(std::io::Error::from_raw_os_error(e as i32)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
fn is_valid_executable(
|
||||||
|
&self,
|
||||||
|
_path: &std::path::Path,
|
||||||
|
) -> std::io::Result<bool> {
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn is_valid_executable(
|
||||||
|
&self,
|
||||||
|
path: &std::path::Path,
|
||||||
|
) -> std::io::Result<bool> {
|
||||||
|
use std::os::windows::ffi::OsStrExt;
|
||||||
|
|
||||||
|
let name = path
|
||||||
|
.as_os_str()
|
||||||
|
.encode_wide()
|
||||||
|
.chain(Some(0))
|
||||||
|
.collect::<Vec<u16>>();
|
||||||
|
let mut bt: u32 = 0;
|
||||||
|
// SAFETY: winapi call
|
||||||
|
unsafe {
|
||||||
|
Ok(
|
||||||
|
windows_sys::Win32::Storage::FileSystem::GetBinaryTypeW(
|
||||||
|
name.as_ptr(),
|
||||||
|
&mut bt,
|
||||||
|
) != 0,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WhichReadDirEntrySysAdapter<TFsDirEntry: sys_traits::FsDirEntry>(
|
||||||
|
TFsDirEntry,
|
||||||
|
);
|
||||||
|
|
||||||
|
impl<TFsDirEntry: sys_traits::FsDirEntry> temp_deno_which::sys::SysReadDirEntry
|
||||||
|
for WhichReadDirEntrySysAdapter<TFsDirEntry>
|
||||||
|
{
|
||||||
|
fn file_name(&self) -> std::ffi::OsString {
|
||||||
|
self.0.file_name().into_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(&self) -> std::path::PathBuf {
|
||||||
|
self.0.path().into_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WhichMetadataSysAdapter<TMetadata: sys_traits::FsMetadataValue>(
|
||||||
|
TMetadata,
|
||||||
|
);
|
||||||
|
|
||||||
|
impl<TMetadata: sys_traits::FsMetadataValue> temp_deno_which::sys::SysMetadata
|
||||||
|
for WhichMetadataSysAdapter<TMetadata>
|
||||||
|
{
|
||||||
|
fn is_symlink(&self) -> bool {
|
||||||
|
self.0.file_type().is_symlink()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_file(&self) -> bool {
|
||||||
|
self.0.file_type().is_file()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue