0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-01 20:25:12 -05:00

refactor: do not use deno_fs::FileSystem everywhere (#27508)

This changes the cli to mostly use `std::fs` via `sys_traits` instead of
the implemention of `deno_fs::FileSystem`.
This commit is contained in:
David Sherret 2024-12-31 11:29:07 -05:00 committed by David Sherret
parent 787646d486
commit 118fd69988
74 changed files with 1304 additions and 1437 deletions

10
Cargo.lock generated
View file

@ -1737,14 +1737,12 @@ dependencies = [
"deno_path_util 0.3.0", "deno_path_util 0.3.0",
"deno_permissions", "deno_permissions",
"filetime", "filetime",
"getrandom",
"junction", "junction",
"libc", "libc",
"nix", "nix",
"rand", "rand",
"rayon", "rayon",
"serde", "serde",
"sys_traits",
"thiserror 2.0.3", "thiserror 2.0.3",
"winapi", "winapi",
"windows-sys 0.59.0", "windows-sys 0.59.0",
@ -2042,6 +2040,7 @@ dependencies = [
"sm3", "sm3",
"spki", "spki",
"stable_deref_trait", "stable_deref_trait",
"sys_traits",
"thiserror 2.0.3", "thiserror 2.0.3",
"tokio", "tokio",
"tokio-eld", "tokio-eld",
@ -2261,6 +2260,7 @@ dependencies = [
"serde", "serde",
"signal-hook", "signal-hook",
"signal-hook-registry", "signal-hook-registry",
"sys_traits",
"tempfile", "tempfile",
"test_server", "test_server",
"thiserror 2.0.3", "thiserror 2.0.3",
@ -7680,12 +7680,14 @@ dependencies = [
[[package]] [[package]]
name = "sys_traits" name = "sys_traits"
version = "0.1.1" version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5a12729b699487bb50163466e87be7197871d83d04cc6815d430cf7c893bbd7" checksum = "6683465f4e1d8fd75069cbc36c646258c05b7d8d6676bcb5d71968b99b7d5ae2"
dependencies = [ dependencies = [
"filetime",
"getrandom", "getrandom",
"libc", "libc",
"parking_lot",
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]

View file

@ -193,7 +193,7 @@ slab = "0.4"
smallvec = "1.8" smallvec = "1.8"
socket2 = { version = "0.5.3", features = ["all"] } socket2 = { version = "0.5.3", features = ["all"] }
spki = "0.7.2" spki = "0.7.2"
sys_traits = "=0.1.1" sys_traits = "=0.1.4"
tar = "=0.4.40" tar = "=0.4.40"
tempfile = "3.4.0" tempfile = "3.4.0"
termcolor = "1.1.3" termcolor = "1.1.3"

View file

@ -158,7 +158,7 @@ shell-escape = "=0.1.5"
spki = { version = "0.7", features = ["pem"] } spki = { version = "0.7", features = ["pem"] }
sqlformat = "=0.3.2" sqlformat = "=0.3.2"
strsim = "0.11.1" strsim = "0.11.1"
sys_traits = { workspace = true, features = ["libc", "real", "winapi"] } sys_traits = { workspace = true, features = ["getrandom", "filetime", "libc", "real", "strip_unc", "winapi"] }
tar.workspace = true tar.workspace = true
tempfile.workspace = true tempfile.workspace = true
text-size = "=1.1.0" text-size = "=1.1.0"
@ -187,6 +187,7 @@ nix.workspace = true
[dev-dependencies] [dev-dependencies]
deno_bench_util.workspace = true deno_bench_util.workspace = true
pretty_assertions.workspace = true pretty_assertions.workspace = true
sys_traits = { workspace = true, features = ["memory"] }
test_util.workspace = true test_util.workspace = true
[package.metadata.winres] [package.metadata.winres]

View file

@ -13,12 +13,12 @@ use deno_core::serde_json;
use deno_lockfile::WorkspaceMemberConfig; use deno_lockfile::WorkspaceMemberConfig;
use deno_package_json::PackageJsonDepValue; use deno_package_json::PackageJsonDepValue;
use deno_path_util::fs::atomic_write_file_with_retries; use deno_path_util::fs::atomic_write_file_with_retries;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::PackageJson; use deno_runtime::deno_node::PackageJson;
use deno_semver::jsr::JsrDepPackageReq; use deno_semver::jsr::JsrDepPackageReq;
use crate::args::deno_json::import_map_deps; use crate::args::deno_json::import_map_deps;
use crate::cache; use crate::cache;
use crate::sys::CliSys;
use crate::Flags; use crate::Flags;
use crate::args::DenoSubcommand; use crate::args::DenoSubcommand;
@ -36,6 +36,7 @@ pub struct CliLockfileReadFromPathOptions {
#[derive(Debug)] #[derive(Debug)]
pub struct CliLockfile { pub struct CliLockfile {
sys: CliSys,
lockfile: Mutex<Lockfile>, lockfile: Mutex<Lockfile>,
pub filename: PathBuf, pub filename: PathBuf,
frozen: bool, frozen: bool,
@ -92,7 +93,7 @@ impl CliLockfile {
// do an atomic write to reduce the chance of multiple deno // do an atomic write to reduce the chance of multiple deno
// processes corrupting the file // processes corrupting the file
atomic_write_file_with_retries( atomic_write_file_with_retries(
&FsSysTraitsAdapter::new_real(), &self.sys,
&lockfile.filename, &lockfile.filename,
&bytes, &bytes,
cache::CACHE_PERM, cache::CACHE_PERM,
@ -103,6 +104,7 @@ impl CliLockfile {
} }
pub fn discover( pub fn discover(
sys: &CliSys,
flags: &Flags, flags: &Flags,
workspace: &Workspace, workspace: &Workspace,
maybe_external_import_map: Option<&serde_json::Value>, maybe_external_import_map: Option<&serde_json::Value>,
@ -165,11 +167,14 @@ impl CliLockfile {
.unwrap_or(false) .unwrap_or(false)
}); });
let lockfile = Self::read_from_path(CliLockfileReadFromPathOptions { let lockfile = Self::read_from_path(
file_path, sys,
frozen, CliLockfileReadFromPathOptions {
skip_write: flags.internal.lockfile_skip_write, file_path,
})?; frozen,
skip_write: flags.internal.lockfile_skip_write,
},
)?;
// initialize the lockfile with the workspace's configuration // initialize the lockfile with the workspace's configuration
let root_url = workspace.root_dir(); let root_url = workspace.root_dir();
@ -225,6 +230,7 @@ impl CliLockfile {
} }
pub fn read_from_path( pub fn read_from_path(
sys: &CliSys,
opts: CliLockfileReadFromPathOptions, opts: CliLockfileReadFromPathOptions,
) -> Result<CliLockfile, AnyError> { ) -> Result<CliLockfile, AnyError> {
let lockfile = match std::fs::read_to_string(&opts.file_path) { let lockfile = match std::fs::read_to_string(&opts.file_path) {
@ -243,6 +249,7 @@ impl CliLockfile {
} }
}; };
Ok(CliLockfile { Ok(CliLockfile {
sys: sys.clone(),
filename: lockfile.filename.clone(), filename: lockfile.filename.clone(),
lockfile: Mutex::new(lockfile), lockfile: Mutex::new(lockfile),
frozen: opts.frozen, frozen: opts.frozen,

View file

@ -30,7 +30,6 @@ use deno_npm::npm_rc::ResolvedNpmRc;
use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot;
use deno_npm::NpmSystemInfo; use deno_npm::NpmSystemInfo;
use deno_path_util::normalize_path; use deno_path_util::normalize_path;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_semver::npm::NpmPackageReqReference; use deno_semver::npm::NpmPackageReqReference;
use deno_semver::StackString; use deno_semver::StackString;
use deno_telemetry::OtelConfig; use deno_telemetry::OtelConfig;
@ -89,6 +88,7 @@ use thiserror::Error;
use crate::cache::DenoDirProvider; use crate::cache::DenoDirProvider;
use crate::file_fetcher::CliFileFetcher; use crate::file_fetcher::CliFileFetcher;
use crate::sys::CliSys;
use crate::util::fs::canonicalize_path_maybe_not_exists; use crate::util::fs::canonicalize_path_maybe_not_exists;
use crate::version; use crate::version;
@ -573,7 +573,7 @@ fn discover_npmrc(
// TODO(bartlomieju): update to read both files - one in the project root and one and // TODO(bartlomieju): update to read both files - one in the project root and one and
// home dir and then merge them. // home dir and then merge them.
// 3. Try `.npmrc` in the user's home directory // 3. Try `.npmrc` in the user's home directory
if let Some(home_dir) = sys_traits::impls::RealSys.env_home_dir() { if let Some(home_dir) = crate::sys::CliSys::default().env_home_dir() {
match try_to_read_npmrc(&home_dir) { match try_to_read_npmrc(&home_dir) {
Ok(Some((source, path))) => { Ok(Some((source, path))) => {
return try_to_parse_npmrc(source, &path).map(|r| (r, Some(path))); return try_to_parse_npmrc(source, &path).map(|r| (r, Some(path)));
@ -772,7 +772,9 @@ pub struct CliOptions {
} }
impl CliOptions { impl CliOptions {
#[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
sys: &CliSys,
flags: Arc<Flags>, flags: Arc<Flags>,
initial_cwd: PathBuf, initial_cwd: PathBuf,
maybe_lockfile: Option<Arc<CliLockfile>>, maybe_lockfile: Option<Arc<CliLockfile>>,
@ -797,8 +799,10 @@ impl CliOptions {
} }
let maybe_lockfile = maybe_lockfile.filter(|_| !force_global_cache); let maybe_lockfile = maybe_lockfile.filter(|_| !force_global_cache);
let deno_dir_provider = let deno_dir_provider = Arc::new(DenoDirProvider::new(
Arc::new(DenoDirProvider::new(flags.internal.cache_path.clone())); sys.clone(),
flags.internal.cache_path.clone(),
));
let maybe_node_modules_folder = resolve_node_modules_folder( let maybe_node_modules_folder = resolve_node_modules_folder(
&initial_cwd, &initial_cwd,
&flags, &flags,
@ -823,7 +827,7 @@ impl CliOptions {
}) })
} }
pub fn from_flags(flags: Arc<Flags>) -> Result<Self, AnyError> { pub fn from_flags(sys: &CliSys, flags: Arc<Flags>) -> Result<Self, AnyError> {
let initial_cwd = let initial_cwd =
std::env::current_dir().with_context(|| "Failed getting cwd.")?; std::env::current_dir().with_context(|| "Failed getting cwd.")?;
let maybe_vendor_override = flags.vendor.map(|v| match v { let maybe_vendor_override = flags.vendor.map(|v| match v {
@ -867,7 +871,7 @@ impl CliOptions {
ConfigFlag::Discover => { ConfigFlag::Discover => {
if let Some(start_paths) = flags.config_path_args(&initial_cwd) { if let Some(start_paths) = flags.config_path_args(&initial_cwd) {
WorkspaceDirectory::discover( WorkspaceDirectory::discover(
&FsSysTraitsAdapter::new_real(), sys,
WorkspaceDiscoverStart::Paths(&start_paths), WorkspaceDiscoverStart::Paths(&start_paths),
&resolve_workspace_discover_options(), &resolve_workspace_discover_options(),
)? )?
@ -878,7 +882,7 @@ impl CliOptions {
ConfigFlag::Path(path) => { ConfigFlag::Path(path) => {
let config_path = normalize_path(initial_cwd.join(path)); let config_path = normalize_path(initial_cwd.join(path));
WorkspaceDirectory::discover( WorkspaceDirectory::discover(
&FsSysTraitsAdapter::new_real(), sys,
WorkspaceDiscoverStart::ConfigFile(&config_path), WorkspaceDiscoverStart::ConfigFile(&config_path),
&resolve_workspace_discover_options(), &resolve_workspace_discover_options(),
)? )?
@ -917,6 +921,7 @@ impl CliOptions {
}; };
let maybe_lock_file = CliLockfile::discover( let maybe_lock_file = CliLockfile::discover(
sys,
&flags, &flags,
&start_dir.workspace, &start_dir.workspace,
external_import_map.as_ref().map(|(_, v)| v), external_import_map.as_ref().map(|(_, v)| v),
@ -925,6 +930,7 @@ impl CliOptions {
log::debug!("Finished config loading."); log::debug!("Finished config loading.");
Self::new( Self::new(
sys,
flags, flags,
initial_cwd, initial_cwd,
maybe_lock_file.map(Arc::new), maybe_lock_file.map(Arc::new),

13
cli/cache/deno_dir.rs vendored
View file

@ -3,6 +3,8 @@
use deno_cache_dir::DenoDirResolutionError; use deno_cache_dir::DenoDirResolutionError;
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
use crate::sys::CliSys;
use super::DiskCache; use super::DiskCache;
use std::env; use std::env;
@ -11,13 +13,15 @@ use std::path::PathBuf;
/// Lazily creates the deno dir which might be useful in scenarios /// Lazily creates the deno dir which might be useful in scenarios
/// where functionality wants to continue if the DENO_DIR can't be created. /// where functionality wants to continue if the DENO_DIR can't be created.
pub struct DenoDirProvider { pub struct DenoDirProvider {
sys: CliSys,
maybe_custom_root: Option<PathBuf>, maybe_custom_root: Option<PathBuf>,
deno_dir: OnceCell<Result<DenoDir, DenoDirResolutionError>>, deno_dir: OnceCell<Result<DenoDir, DenoDirResolutionError>>,
} }
impl DenoDirProvider { impl DenoDirProvider {
pub fn new(maybe_custom_root: Option<PathBuf>) -> Self { pub fn new(sys: CliSys, maybe_custom_root: Option<PathBuf>) -> Self {
Self { Self {
sys,
maybe_custom_root, maybe_custom_root,
deno_dir: Default::default(), deno_dir: Default::default(),
} }
@ -26,7 +30,9 @@ impl DenoDirProvider {
pub fn get_or_create(&self) -> Result<&DenoDir, DenoDirResolutionError> { pub fn get_or_create(&self) -> Result<&DenoDir, DenoDirResolutionError> {
self self
.deno_dir .deno_dir
.get_or_init(|| DenoDir::new(self.maybe_custom_root.clone())) .get_or_init(|| {
DenoDir::new(self.sys.clone(), self.maybe_custom_root.clone())
})
.as_ref() .as_ref()
.map_err(|err| match err { .map_err(|err| match err {
DenoDirResolutionError::NoCacheOrHomeDir => { DenoDirResolutionError::NoCacheOrHomeDir => {
@ -53,6 +59,7 @@ pub struct DenoDir {
impl DenoDir { impl DenoDir {
pub fn new( pub fn new(
sys: CliSys,
maybe_custom_root: Option<PathBuf>, maybe_custom_root: Option<PathBuf>,
) -> Result<Self, deno_cache_dir::DenoDirResolutionError> { ) -> Result<Self, deno_cache_dir::DenoDirResolutionError> {
let root = deno_cache_dir::resolve_deno_dir( let root = deno_cache_dir::resolve_deno_dir(
@ -64,7 +71,7 @@ impl DenoDir {
let deno_dir = Self { let deno_dir = Self {
root, root,
gen_cache: DiskCache::new(&gen_path), gen_cache: DiskCache::new(sys, &gen_path),
}; };
Ok(deno_dir) Ok(deno_dir)

View file

@ -1,12 +1,13 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::sys::CliSys;
use super::CACHE_PERM; use super::CACHE_PERM;
use deno_cache_dir::url_to_filename; use deno_cache_dir::url_to_filename;
use deno_core::url::Host; use deno_core::url::Host;
use deno_core::url::Url; use deno_core::url::Url;
use deno_path_util::fs::atomic_write_file_with_retries; use deno_path_util::fs::atomic_write_file_with_retries;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fs; use std::fs;
use std::path::Component; use std::path::Component;
@ -17,14 +18,16 @@ use std::str;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DiskCache { pub struct DiskCache {
sys: CliSys,
pub location: PathBuf, pub location: PathBuf,
} }
impl DiskCache { impl DiskCache {
/// `location` must be an absolute path. /// `location` must be an absolute path.
pub fn new(location: &Path) -> Self { pub fn new(sys: CliSys, location: &Path) -> Self {
assert!(location.is_absolute()); assert!(location.is_absolute());
Self { Self {
sys,
location: location.to_owned(), location: location.to_owned(),
} }
} }
@ -121,12 +124,7 @@ impl DiskCache {
pub fn set(&self, filename: &Path, data: &[u8]) -> std::io::Result<()> { pub fn set(&self, filename: &Path, data: &[u8]) -> std::io::Result<()> {
let path = self.location.join(filename); let path = self.location.join(filename);
atomic_write_file_with_retries( atomic_write_file_with_retries(&self.sys, &path, data, CACHE_PERM)
&FsSysTraitsAdapter::new_real(),
&path,
data,
CACHE_PERM,
)
} }
} }
@ -139,7 +137,7 @@ mod tests {
fn test_set_get_cache_file() { fn test_set_get_cache_file() {
let temp_dir = TempDir::new(); let temp_dir = TempDir::new();
let sub_dir = temp_dir.path().join("sub_dir"); let sub_dir = temp_dir.path().join("sub_dir");
let cache = DiskCache::new(&sub_dir.to_path_buf()); let cache = DiskCache::new(CliSys::default(), &sub_dir.to_path_buf());
let path = PathBuf::from("foo/bar.txt"); let path = PathBuf::from("foo/bar.txt");
cache.set(&path, b"hello").unwrap(); cache.set(&path, b"hello").unwrap();
assert_eq!(cache.get(&path).unwrap(), b"hello"); assert_eq!(cache.get(&path).unwrap(), b"hello");
@ -153,7 +151,7 @@ mod tests {
PathBuf::from("/deno_dir/") PathBuf::from("/deno_dir/")
}; };
let cache = DiskCache::new(&cache_location); let cache = DiskCache::new(CliSys::default(), &cache_location);
let mut test_cases = vec![ let mut test_cases = vec![
( (
@ -209,7 +207,7 @@ mod tests {
} else { } else {
"/foo" "/foo"
}; };
let cache = DiskCache::new(&PathBuf::from(p)); let cache = DiskCache::new(CliSys::default(), &PathBuf::from(p));
let mut test_cases = vec![ let mut test_cases = vec![
( (
@ -257,7 +255,7 @@ mod tests {
PathBuf::from("/deno_dir/") PathBuf::from("/deno_dir/")
}; };
let cache = DiskCache::new(&cache_location); let cache = DiskCache::new(CliSys::default(), &cache_location);
let mut test_cases = vec!["unknown://localhost/test.ts"]; let mut test_cases = vec!["unknown://localhost/test.ts"];

5
cli/cache/emit.rs vendored
View file

@ -159,12 +159,15 @@ impl EmitFileSerializer {
mod test { mod test {
use test_util::TempDir; use test_util::TempDir;
use crate::sys::CliSys;
use super::*; use super::*;
#[test] #[test]
pub fn emit_cache_general_use() { pub fn emit_cache_general_use() {
let temp_dir = TempDir::new(); let temp_dir = TempDir::new();
let disk_cache = DiskCache::new(temp_dir.path().as_path()); let disk_cache =
DiskCache::new(CliSys::default(), temp_dir.path().as_path());
let cache = EmitCache { let cache = EmitCache {
disk_cache: disk_cache.clone(), disk_cache: disk_cache.clone(),
file_serializer: EmitFileSerializer { file_serializer: EmitFileSerializer {

13
cli/cache/mod.rs vendored
View file

@ -5,6 +5,7 @@ use crate::file_fetcher::CliFetchNoFollowErrorKind;
use crate::file_fetcher::CliFileFetcher; use crate::file_fetcher::CliFileFetcher;
use crate::file_fetcher::FetchNoFollowOptions; use crate::file_fetcher::FetchNoFollowOptions;
use crate::file_fetcher::FetchPermissionsOptionRef; use crate::file_fetcher::FetchPermissionsOptionRef;
use crate::sys::CliSys;
use deno_ast::MediaType; use deno_ast::MediaType;
use deno_cache_dir::file_fetcher::CacheSetting; use deno_cache_dir::file_fetcher::CacheSetting;
@ -18,7 +19,6 @@ use deno_graph::source::CacheInfo;
use deno_graph::source::LoadFuture; use deno_graph::source::LoadFuture;
use deno_graph::source::LoadResponse; use deno_graph::source::LoadResponse;
use deno_graph::source::Loader; use deno_graph::source::Loader;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_permissions::PermissionsContainer;
use node_resolver::InNpmPackageChecker; use node_resolver::InNpmPackageChecker;
use std::collections::HashMap; use std::collections::HashMap;
@ -58,10 +58,9 @@ pub use parsed_source::ParsedSourceCache;
/// Permissions used to save a file in the disk caches. /// Permissions used to save a file in the disk caches.
pub use deno_cache_dir::CACHE_PERM; pub use deno_cache_dir::CACHE_PERM;
pub type GlobalHttpCache = deno_cache_dir::GlobalHttpCache<FsSysTraitsAdapter>; pub type GlobalHttpCache = deno_cache_dir::GlobalHttpCache<CliSys>;
pub type LocalHttpCache = deno_cache_dir::LocalHttpCache<FsSysTraitsAdapter>; pub type LocalHttpCache = deno_cache_dir::LocalHttpCache<CliSys>;
pub type LocalLspHttpCache = pub type LocalLspHttpCache = deno_cache_dir::LocalLspHttpCache<CliSys>;
deno_cache_dir::LocalLspHttpCache<FsSysTraitsAdapter>;
pub use deno_cache_dir::HttpCache; pub use deno_cache_dir::HttpCache;
pub struct FetchCacherOptions { pub struct FetchCacherOptions {
@ -80,7 +79,7 @@ pub struct FetchCacher {
in_npm_pkg_checker: Arc<dyn InNpmPackageChecker>, in_npm_pkg_checker: Arc<dyn InNpmPackageChecker>,
module_info_cache: Arc<ModuleInfoCache>, module_info_cache: Arc<ModuleInfoCache>,
permissions: PermissionsContainer, permissions: PermissionsContainer,
sys: FsSysTraitsAdapter, sys: CliSys,
is_deno_publish: bool, is_deno_publish: bool,
cache_info_enabled: bool, cache_info_enabled: bool,
} }
@ -91,7 +90,7 @@ impl FetchCacher {
global_http_cache: Arc<GlobalHttpCache>, global_http_cache: Arc<GlobalHttpCache>,
in_npm_pkg_checker: Arc<dyn InNpmPackageChecker>, in_npm_pkg_checker: Arc<dyn InNpmPackageChecker>,
module_info_cache: Arc<ModuleInfoCache>, module_info_cache: Arc<ModuleInfoCache>,
sys: FsSysTraitsAdapter, sys: CliSys,
options: FetchCacherOptions, options: FetchCacherOptions,
) -> Self { ) -> Self {
Self { Self {

View file

@ -4,6 +4,7 @@ disallowed-methods = [
] ]
disallowed-types = [ disallowed-types = [
{ path = "reqwest::Client", reason = "use crate::http_util::HttpClient instead" }, { path = "reqwest::Client", reason = "use crate::http_util::HttpClient instead" },
{ path = "sys_traits::impls::RealSys", reason = "use crate::sys::CliSys instead" },
] ]
ignore-interior-mutability = [ ignore-interior-mutability = [
"lsp_types::Uri", "lsp_types::Uri",

View file

@ -31,6 +31,8 @@ use crate::module_loader::CliModuleLoaderFactory;
use crate::module_loader::ModuleLoadPreparer; use crate::module_loader::ModuleLoadPreparer;
use crate::node::CliCjsCodeAnalyzer; use crate::node::CliCjsCodeAnalyzer;
use crate::node::CliNodeCodeTranslator; use crate::node::CliNodeCodeTranslator;
use crate::node::CliNodeResolver;
use crate::node::CliPackageJsonResolver;
use crate::npm::create_cli_npm_resolver; use crate::npm::create_cli_npm_resolver;
use crate::npm::create_in_npm_pkg_checker; use crate::npm::create_in_npm_pkg_checker;
use crate::npm::CliByonmNpmResolverCreateOptions; use crate::npm::CliByonmNpmResolverCreateOptions;
@ -48,7 +50,8 @@ use crate::resolver::CliResolverOptions;
use crate::resolver::CliSloppyImportsResolver; use crate::resolver::CliSloppyImportsResolver;
use crate::resolver::NpmModuleLoader; use crate::resolver::NpmModuleLoader;
use crate::resolver::SloppyImportsCachedFs; use crate::resolver::SloppyImportsCachedFs;
use crate::standalone::DenoCompileBinaryWriter; use crate::standalone::binary::DenoCompileBinaryWriter;
use crate::sys::CliSys;
use crate::tools::check::TypeChecker; use crate::tools::check::TypeChecker;
use crate::tools::coverage::CoverageCollector; use crate::tools::coverage::CoverageCollector;
use crate::tools::lint::LintRuleProvider; use crate::tools::lint::LintRuleProvider;
@ -74,9 +77,7 @@ use deno_resolver::npm::NpmReqResolverOptions;
use deno_resolver::DenoResolverOptions; use deno_resolver::DenoResolverOptions;
use deno_resolver::NodeAndNpmReqResolver; use deno_resolver::NodeAndNpmReqResolver;
use deno_runtime::deno_fs; use deno_runtime::deno_fs;
use deno_runtime::deno_fs::FsSysTraitsAdapter; use deno_runtime::deno_fs::RealFs;
use deno_runtime::deno_node::NodeResolver;
use deno_runtime::deno_node::PackageJsonResolver;
use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker; use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker;
use deno_runtime::deno_permissions::Permissions; use deno_runtime::deno_permissions::Permissions;
use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_permissions::PermissionsContainer;
@ -198,13 +199,14 @@ struct CliFactoryServices {
module_info_cache: Deferred<Arc<ModuleInfoCache>>, module_info_cache: Deferred<Arc<ModuleInfoCache>>,
module_load_preparer: Deferred<Arc<ModuleLoadPreparer>>, module_load_preparer: Deferred<Arc<ModuleLoadPreparer>>,
node_code_translator: Deferred<Arc<CliNodeCodeTranslator>>, node_code_translator: Deferred<Arc<CliNodeCodeTranslator>>,
node_resolver: Deferred<Arc<NodeResolver>>, node_resolver: Deferred<Arc<CliNodeResolver>>,
npm_cache_dir: Deferred<Arc<NpmCacheDir>>, npm_cache_dir: Deferred<Arc<NpmCacheDir>>,
npm_req_resolver: Deferred<Arc<CliNpmReqResolver>>, npm_req_resolver: Deferred<Arc<CliNpmReqResolver>>,
npm_resolver: Deferred<Arc<dyn CliNpmResolver>>, npm_resolver: Deferred<Arc<dyn CliNpmResolver>>,
parsed_source_cache: Deferred<Arc<ParsedSourceCache>>, parsed_source_cache: Deferred<Arc<ParsedSourceCache>>,
permission_desc_parser: Deferred<Arc<RuntimePermissionDescriptorParser>>, permission_desc_parser:
pkg_json_resolver: Deferred<Arc<PackageJsonResolver>>, Deferred<Arc<RuntimePermissionDescriptorParser<CliSys>>>,
pkg_json_resolver: Deferred<Arc<CliPackageJsonResolver>>,
resolver: Deferred<Arc<CliResolver>>, resolver: Deferred<Arc<CliResolver>>,
root_cert_store_provider: Deferred<Arc<dyn RootCertStoreProvider>>, root_cert_store_provider: Deferred<Arc<dyn RootCertStoreProvider>>,
root_permissions_container: Deferred<PermissionsContainer>, root_permissions_container: Deferred<PermissionsContainer>,
@ -254,7 +256,7 @@ impl CliFactory {
pub fn cli_options(&self) -> Result<&Arc<CliOptions>, AnyError> { pub fn cli_options(&self) -> Result<&Arc<CliOptions>, AnyError> {
self.services.cli_options.get_or_try_init(|| { self.services.cli_options.get_or_try_init(|| {
CliOptions::from_flags(self.flags.clone()).map(Arc::new) CliOptions::from_flags(&self.sys(), self.flags.clone()).map(Arc::new)
}) })
} }
@ -317,7 +319,7 @@ impl CliFactory {
pub fn global_http_cache(&self) -> Result<&Arc<GlobalHttpCache>, AnyError> { pub fn global_http_cache(&self) -> Result<&Arc<GlobalHttpCache>, AnyError> {
self.services.global_http_cache.get_or_try_init(|| { self.services.global_http_cache.get_or_try_init(|| {
Ok(Arc::new(GlobalHttpCache::new( Ok(Arc::new(GlobalHttpCache::new(
FsSysTraitsAdapter(self.fs().clone()), self.sys(),
self.deno_dir()?.remote_folder_path(), self.deno_dir()?.remote_folder_path(),
))) )))
}) })
@ -355,6 +357,7 @@ impl CliFactory {
Ok(Arc::new(CliFileFetcher::new( Ok(Arc::new(CliFileFetcher::new(
self.http_cache()?.clone(), self.http_cache()?.clone(),
self.http_client_provider().clone(), self.http_client_provider().clone(),
self.sys(),
self.blob_store().clone(), self.blob_store().clone(),
Some(self.text_only_progress_bar().clone()), Some(self.text_only_progress_bar().clone()),
!cli_options.no_remote(), !cli_options.no_remote(),
@ -365,7 +368,11 @@ impl CliFactory {
} }
pub fn fs(&self) -> &Arc<dyn deno_fs::FileSystem> { pub fn fs(&self) -> &Arc<dyn deno_fs::FileSystem> {
self.services.fs.get_or_init(|| Arc::new(deno_fs::RealFs)) self.services.fs.get_or_init(|| Arc::new(RealFs))
}
pub fn sys(&self) -> CliSys {
CliSys::default() // very cheap to make
} }
pub fn in_npm_pkg_checker( pub fn in_npm_pkg_checker(
@ -391,11 +398,10 @@ impl CliFactory {
pub fn npm_cache_dir(&self) -> Result<&Arc<NpmCacheDir>, AnyError> { pub fn npm_cache_dir(&self) -> Result<&Arc<NpmCacheDir>, AnyError> {
self.services.npm_cache_dir.get_or_try_init(|| { self.services.npm_cache_dir.get_or_try_init(|| {
let fs = self.fs();
let global_path = self.deno_dir()?.npm_folder_path(); let global_path = self.deno_dir()?.npm_folder_path();
let cli_options = self.cli_options()?; let cli_options = self.cli_options()?;
Ok(Arc::new(NpmCacheDir::new( Ok(Arc::new(NpmCacheDir::new(
&FsSysTraitsAdapter(fs.clone()), &self.sys(),
global_path, global_path,
cli_options.npmrc().get_all_known_registries_urls(), cli_options.npmrc().get_all_known_registries_urls(),
))) )))
@ -410,12 +416,11 @@ impl CliFactory {
.npm_resolver .npm_resolver
.get_or_try_init_async( .get_or_try_init_async(
async { async {
let fs = self.fs();
let cli_options = self.cli_options()?; let cli_options = self.cli_options()?;
create_cli_npm_resolver(if cli_options.use_byonm() { create_cli_npm_resolver(if cli_options.use_byonm() {
CliNpmResolverCreateOptions::Byonm( CliNpmResolverCreateOptions::Byonm(
CliByonmNpmResolverCreateOptions { CliByonmNpmResolverCreateOptions {
sys: FsSysTraitsAdapter(fs.clone()), sys: self.sys(),
pkg_json_resolver: self.pkg_json_resolver().clone(), pkg_json_resolver: self.pkg_json_resolver().clone(),
root_node_modules_dir: Some( root_node_modules_dir: Some(
match cli_options.node_modules_dir_path() { match cli_options.node_modules_dir_path() {
@ -439,7 +444,7 @@ impl CliFactory {
cli_options.workspace(), cli_options.workspace(),
), ),
), ),
sys: FsSysTraitsAdapter(self.fs().clone()), sys: self.sys(),
snapshot: match cli_options.resolve_npm_resolution_snapshot()? { snapshot: match cli_options.resolve_npm_resolution_snapshot()? {
Some(snapshot) => { Some(snapshot) => {
CliNpmResolverManagedSnapshotOption::Specified(Some( CliNpmResolverManagedSnapshotOption::Specified(Some(
@ -486,7 +491,7 @@ impl CliFactory {
.get_or_try_init(|| { .get_or_try_init(|| {
Ok(self.cli_options()?.unstable_sloppy_imports().then(|| { Ok(self.cli_options()?.unstable_sloppy_imports().then(|| {
Arc::new(CliSloppyImportsResolver::new(SloppyImportsCachedFs::new( Arc::new(CliSloppyImportsResolver::new(SloppyImportsCachedFs::new(
FsSysTraitsAdapter(self.fs().clone()), self.sys(),
))) )))
})) }))
}) })
@ -647,13 +652,13 @@ impl CliFactory {
)) ))
} }
pub async fn node_resolver(&self) -> Result<&Arc<NodeResolver>, AnyError> { pub async fn node_resolver(&self) -> Result<&Arc<CliNodeResolver>, AnyError> {
self self
.services .services
.node_resolver .node_resolver
.get_or_try_init_async( .get_or_try_init_async(
async { async {
Ok(Arc::new(NodeResolver::new( Ok(Arc::new(CliNodeResolver::new(
self.in_npm_pkg_checker()?.clone(), self.in_npm_pkg_checker()?.clone(),
RealIsBuiltInNodeModuleChecker, RealIsBuiltInNodeModuleChecker,
self self
@ -662,7 +667,7 @@ impl CliFactory {
.clone() .clone()
.into_npm_pkg_folder_resolver(), .into_npm_pkg_folder_resolver(),
self.pkg_json_resolver().clone(), self.pkg_json_resolver().clone(),
FsSysTraitsAdapter(self.fs().clone()), self.sys(),
))) )))
} }
.boxed_local(), .boxed_local(),
@ -698,7 +703,7 @@ impl CliFactory {
.clone() .clone()
.into_npm_pkg_folder_resolver(), .into_npm_pkg_folder_resolver(),
self.pkg_json_resolver().clone(), self.pkg_json_resolver().clone(),
FsSysTraitsAdapter(self.fs().clone()), self.sys(),
))) )))
}) })
.await .await
@ -714,7 +719,7 @@ impl CliFactory {
let npm_resolver = self.npm_resolver().await?; let npm_resolver = self.npm_resolver().await?;
Ok(Arc::new(CliNpmReqResolver::new(NpmReqResolverOptions { Ok(Arc::new(CliNpmReqResolver::new(NpmReqResolverOptions {
byonm_resolver: (npm_resolver.clone()).into_maybe_byonm(), byonm_resolver: (npm_resolver.clone()).into_maybe_byonm(),
sys: FsSysTraitsAdapter(self.fs().clone()), sys: self.sys(),
in_npm_pkg_checker: self.in_npm_pkg_checker()?.clone(), in_npm_pkg_checker: self.in_npm_pkg_checker()?.clone(),
node_resolver: self.node_resolver().await?.clone(), node_resolver: self.node_resolver().await?.clone(),
npm_req_resolver: npm_resolver.clone().into_npm_req_resolver(), npm_req_resolver: npm_resolver.clone().into_npm_req_resolver(),
@ -723,12 +728,11 @@ impl CliFactory {
.await .await
} }
pub fn pkg_json_resolver(&self) -> &Arc<PackageJsonResolver> { pub fn pkg_json_resolver(&self) -> &Arc<CliPackageJsonResolver> {
self.services.pkg_json_resolver.get_or_init(|| { self
Arc::new(PackageJsonResolver::new(FsSysTraitsAdapter( .services
self.fs().clone(), .pkg_json_resolver
))) .get_or_init(|| Arc::new(CliPackageJsonResolver::new(self.sys())))
})
} }
pub async fn type_checker(&self) -> Result<&Arc<TypeChecker>, AnyError> { pub async fn type_checker(&self) -> Result<&Arc<TypeChecker>, AnyError> {
@ -774,7 +778,7 @@ impl CliFactory {
self.parsed_source_cache().clone(), self.parsed_source_cache().clone(),
self.resolver().await?.clone(), self.resolver().await?.clone(),
self.root_permissions_container()?.clone(), self.root_permissions_container()?.clone(),
FsSysTraitsAdapter(self.fs().clone()), self.sys(),
))) )))
}) })
.await .await
@ -864,10 +868,9 @@ impl CliFactory {
pub fn permission_desc_parser( pub fn permission_desc_parser(
&self, &self,
) -> Result<&Arc<RuntimePermissionDescriptorParser>, AnyError> { ) -> Result<&Arc<RuntimePermissionDescriptorParser<CliSys>>, AnyError> {
self.services.permission_desc_parser.get_or_try_init(|| { self.services.permission_desc_parser.get_or_try_init(|| {
let fs = self.fs().clone(); Ok(Arc::new(RuntimePermissionDescriptorParser::new(self.sys())))
Ok(Arc::new(RuntimePermissionDescriptorParser::new(fs)))
}) })
} }
@ -974,7 +977,7 @@ impl CliFactory {
), ),
self.parsed_source_cache().clone(), self.parsed_source_cache().clone(),
self.resolver().await?.clone(), self.resolver().await?.clone(),
FsSysTraitsAdapter(self.fs().clone()), self.sys(),
)), )),
node_resolver.clone(), node_resolver.clone(),
npm_resolver.clone(), npm_resolver.clone(),
@ -982,6 +985,7 @@ impl CliFactory {
self.root_cert_store_provider().clone(), self.root_cert_store_provider().clone(),
self.root_permissions_container()?.clone(), self.root_permissions_container()?.clone(),
StorageKeyResolver::from_options(cli_options), StorageKeyResolver::from_options(cli_options),
self.sys(),
cli_options.sub_command().clone(), cli_options.sub_command().clone(),
self.create_cli_main_worker_options()?, self.create_cli_main_worker_options()?,
self.cli_options()?.otel_config(), self.cli_options()?.otel_config(),

View file

@ -24,7 +24,6 @@ use deno_core::url::Url;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_error::JsError; use deno_error::JsError;
use deno_graph::source::LoaderChecksum; use deno_graph::source::LoaderChecksum;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_permissions::CheckSpecifierKind; use deno_runtime::deno_permissions::CheckSpecifierKind;
use deno_runtime::deno_permissions::PermissionCheckError; use deno_runtime::deno_permissions::PermissionCheckError;
use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_permissions::PermissionsContainer;
@ -38,6 +37,7 @@ use crate::cache::HttpCache;
use crate::colors; use crate::colors;
use crate::http_util::get_response_body_with_progress; use crate::http_util::get_response_body_with_progress;
use crate::http_util::HttpClientProvider; use crate::http_util::HttpClientProvider;
use crate::sys::CliSys;
use crate::util::progress_bar::ProgressBar; use crate::util::progress_bar::ProgressBar;
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]
@ -267,7 +267,7 @@ pub struct FetchNoFollowOptions<'a> {
type DenoCacheDirFileFetcher = deno_cache_dir::file_fetcher::FileFetcher< type DenoCacheDirFileFetcher = deno_cache_dir::file_fetcher::FileFetcher<
BlobStoreAdapter, BlobStoreAdapter,
FsSysTraitsAdapter, CliSys,
HttpClientAdapter, HttpClientAdapter,
>; >;
@ -279,9 +279,11 @@ pub struct CliFileFetcher {
} }
impl CliFileFetcher { impl CliFileFetcher {
#[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
http_cache: Arc<dyn HttpCache>, http_cache: Arc<dyn HttpCache>,
http_client_provider: Arc<HttpClientProvider>, http_client_provider: Arc<HttpClientProvider>,
sys: CliSys,
blob_store: Arc<BlobStore>, blob_store: Arc<BlobStore>,
progress_bar: Option<ProgressBar>, progress_bar: Option<ProgressBar>,
allow_remote: bool, allow_remote: bool,
@ -289,7 +291,6 @@ impl CliFileFetcher {
download_log_level: log::Level, download_log_level: log::Level,
) -> Self { ) -> Self {
let memory_files = Arc::new(MemoryFiles::default()); let memory_files = Arc::new(MemoryFiles::default());
let sys = FsSysTraitsAdapter::new_real();
let auth_tokens = AuthTokens::new_from_sys(&sys); let auth_tokens = AuthTokens::new_from_sys(&sys);
let file_fetcher = DenoCacheDirFileFetcher::new( let file_fetcher = DenoCacheDirFileFetcher::new(
BlobStoreAdapter(blob_store), BlobStoreAdapter(blob_store),
@ -538,13 +539,11 @@ mod tests {
let temp_dir = maybe_temp_dir.unwrap_or_default(); let temp_dir = maybe_temp_dir.unwrap_or_default();
let location = temp_dir.path().join("remote").to_path_buf(); let location = temp_dir.path().join("remote").to_path_buf();
let blob_store: Arc<BlobStore> = Default::default(); let blob_store: Arc<BlobStore> = Default::default();
let cache = Arc::new(GlobalHttpCache::new( let cache = Arc::new(GlobalHttpCache::new(CliSys::default(), location));
FsSysTraitsAdapter::new_real(),
location,
));
let file_fetcher = CliFileFetcher::new( let file_fetcher = CliFileFetcher::new(
cache.clone(), cache.clone(),
Arc::new(HttpClientProvider::new(None, None)), Arc::new(HttpClientProvider::new(None, None)),
CliSys::default(),
blob_store.clone(), blob_store.clone(),
None, None,
true, true,
@ -754,11 +753,9 @@ mod tests {
// invocation and indicates to "cache bust". // invocation and indicates to "cache bust".
let location = temp_dir.path().join("remote").to_path_buf(); let location = temp_dir.path().join("remote").to_path_buf();
let file_fetcher = CliFileFetcher::new( let file_fetcher = CliFileFetcher::new(
Arc::new(GlobalHttpCache::new( Arc::new(GlobalHttpCache::new(CliSys::default(), location)),
FsSysTraitsAdapter::new_real(),
location,
)),
Arc::new(HttpClientProvider::new(None, None)), Arc::new(HttpClientProvider::new(None, None)),
CliSys::default(),
Default::default(), Default::default(),
None, None,
true, true,
@ -783,14 +780,13 @@ mod tests {
let specifier = let specifier =
resolve_url("http://localhost:4545/subdir/mismatch_ext.ts").unwrap(); resolve_url("http://localhost:4545/subdir/mismatch_ext.ts").unwrap();
let http_cache = Arc::new(GlobalHttpCache::new( let http_cache =
FsSysTraitsAdapter::new_real(), Arc::new(GlobalHttpCache::new(CliSys::default(), location.clone()));
location.clone(),
));
let file_modified_01 = { let file_modified_01 = {
let file_fetcher = CliFileFetcher::new( let file_fetcher = CliFileFetcher::new(
http_cache.clone(), http_cache.clone(),
Arc::new(HttpClientProvider::new(None, None)), Arc::new(HttpClientProvider::new(None, None)),
CliSys::default(),
Default::default(), Default::default(),
None, None,
true, true,
@ -810,11 +806,9 @@ mod tests {
let file_modified_02 = { let file_modified_02 = {
let file_fetcher = CliFileFetcher::new( let file_fetcher = CliFileFetcher::new(
Arc::new(GlobalHttpCache::new( Arc::new(GlobalHttpCache::new(CliSys::default(), location)),
FsSysTraitsAdapter::new_real(),
location,
)),
Arc::new(HttpClientProvider::new(None, None)), Arc::new(HttpClientProvider::new(None, None)),
CliSys::default(),
Default::default(), Default::default(),
None, None,
true, true,
@ -940,15 +934,14 @@ mod tests {
resolve_url("http://localhost:4548/subdir/mismatch_ext.ts").unwrap(); resolve_url("http://localhost:4548/subdir/mismatch_ext.ts").unwrap();
let redirected_specifier = let redirected_specifier =
resolve_url("http://localhost:4546/subdir/mismatch_ext.ts").unwrap(); resolve_url("http://localhost:4546/subdir/mismatch_ext.ts").unwrap();
let http_cache = Arc::new(GlobalHttpCache::new( let http_cache =
FsSysTraitsAdapter::new_real(), Arc::new(GlobalHttpCache::new(CliSys::default(), location.clone()));
location.clone(),
));
let metadata_file_modified_01 = { let metadata_file_modified_01 = {
let file_fetcher = CliFileFetcher::new( let file_fetcher = CliFileFetcher::new(
http_cache.clone(), http_cache.clone(),
Arc::new(HttpClientProvider::new(None, None)), Arc::new(HttpClientProvider::new(None, None)),
CliSys::default(),
Default::default(), Default::default(),
None, None,
true, true,
@ -971,6 +964,7 @@ mod tests {
let file_fetcher = CliFileFetcher::new( let file_fetcher = CliFileFetcher::new(
http_cache.clone(), http_cache.clone(),
Arc::new(HttpClientProvider::new(None, None)), Arc::new(HttpClientProvider::new(None, None)),
CliSys::default(),
Default::default(), Default::default(),
None, None,
true, true,
@ -1075,11 +1069,9 @@ mod tests {
let temp_dir = TempDir::new(); let temp_dir = TempDir::new();
let location = temp_dir.path().join("remote").to_path_buf(); let location = temp_dir.path().join("remote").to_path_buf();
let file_fetcher = CliFileFetcher::new( let file_fetcher = CliFileFetcher::new(
Arc::new(GlobalHttpCache::new( Arc::new(GlobalHttpCache::new(CliSys::default(), location)),
FsSysTraitsAdapter::new_real(),
location,
)),
Arc::new(HttpClientProvider::new(None, None)), Arc::new(HttpClientProvider::new(None, None)),
CliSys::default(),
Default::default(), Default::default(),
None, None,
false, false,
@ -1113,11 +1105,9 @@ mod tests {
let temp_dir = TempDir::new(); let temp_dir = TempDir::new();
let location = temp_dir.path().join("remote").to_path_buf(); let location = temp_dir.path().join("remote").to_path_buf();
let file_fetcher_01 = CliFileFetcher::new( let file_fetcher_01 = CliFileFetcher::new(
Arc::new(GlobalHttpCache::new( Arc::new(GlobalHttpCache::new(CliSys::default(), location.clone())),
FsSysTraitsAdapter::new_real(),
location.clone(),
)),
Arc::new(HttpClientProvider::new(None, None)), Arc::new(HttpClientProvider::new(None, None)),
CliSys::default(),
Default::default(), Default::default(),
None, None,
true, true,
@ -1125,11 +1115,9 @@ mod tests {
log::Level::Info, log::Level::Info,
); );
let file_fetcher_02 = CliFileFetcher::new( let file_fetcher_02 = CliFileFetcher::new(
Arc::new(GlobalHttpCache::new( Arc::new(GlobalHttpCache::new(CliSys::default(), location)),
FsSysTraitsAdapter::new_real(),
location,
)),
Arc::new(HttpClientProvider::new(None, None)), Arc::new(HttpClientProvider::new(None, None)),
CliSys::default(),
Default::default(), Default::default(),
None, None,
true, true,

View file

@ -29,7 +29,6 @@ use deno_graph::SpecifierError;
use deno_graph::WorkspaceFastCheckOption; use deno_graph::WorkspaceFastCheckOption;
use deno_path_util::url_to_file_path; use deno_path_util::url_to_file_path;
use deno_resolver::sloppy_imports::SloppyImportsResolutionKind; use deno_resolver::sloppy_imports::SloppyImportsResolutionKind;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node; use deno_runtime::deno_node;
use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_permissions::PermissionsContainer;
use deno_semver::jsr::JsrDepPackageReq; use deno_semver::jsr::JsrDepPackageReq;
@ -57,6 +56,7 @@ use crate::resolver::CjsTracker;
use crate::resolver::CliResolver; use crate::resolver::CliResolver;
use crate::resolver::CliSloppyImportsResolver; use crate::resolver::CliSloppyImportsResolver;
use crate::resolver::SloppyImportsCachedFs; use crate::resolver::SloppyImportsCachedFs;
use crate::sys::CliSys;
use crate::tools::check; use crate::tools::check;
use crate::tools::check::TypeChecker; use crate::tools::check::TypeChecker;
use crate::util::file_watcher::WatcherCommunicator; use crate::util::file_watcher::WatcherCommunicator;
@ -81,7 +81,7 @@ pub struct GraphValidOptions {
/// for the CLI. /// for the CLI.
pub fn graph_valid( pub fn graph_valid(
graph: &ModuleGraph, graph: &ModuleGraph,
sys: &FsSysTraitsAdapter, sys: &CliSys,
roots: &[ModuleSpecifier], roots: &[ModuleSpecifier],
options: GraphValidOptions, options: GraphValidOptions,
) -> Result<(), AnyError> { ) -> Result<(), AnyError> {
@ -141,7 +141,7 @@ pub struct GraphWalkErrorsOptions {
/// and enhances them with CLI information. /// and enhances them with CLI information.
pub fn graph_walk_errors<'a>( pub fn graph_walk_errors<'a>(
graph: &'a ModuleGraph, graph: &'a ModuleGraph,
sys: &'a FsSysTraitsAdapter, sys: &'a CliSys,
roots: &'a [ModuleSpecifier], roots: &'a [ModuleSpecifier],
options: GraphWalkErrorsOptions, options: GraphWalkErrorsOptions,
) -> impl Iterator<Item = AnyError> + 'a { ) -> impl Iterator<Item = AnyError> + 'a {
@ -443,7 +443,7 @@ pub struct ModuleGraphBuilder {
parsed_source_cache: Arc<ParsedSourceCache>, parsed_source_cache: Arc<ParsedSourceCache>,
resolver: Arc<CliResolver>, resolver: Arc<CliResolver>,
root_permissions_container: PermissionsContainer, root_permissions_container: PermissionsContainer,
sys: FsSysTraitsAdapter, sys: CliSys,
} }
impl ModuleGraphBuilder { impl ModuleGraphBuilder {
@ -462,7 +462,7 @@ impl ModuleGraphBuilder {
parsed_source_cache: Arc<ParsedSourceCache>, parsed_source_cache: Arc<ParsedSourceCache>,
resolver: Arc<CliResolver>, resolver: Arc<CliResolver>,
root_permissions_container: PermissionsContainer, root_permissions_container: PermissionsContainer,
sys: FsSysTraitsAdapter, sys: CliSys,
) -> Self { ) -> Self {
Self { Self {
caches, caches,
@ -836,7 +836,7 @@ pub fn enhanced_resolution_error_message(error: &ResolutionError) -> String {
} }
fn enhanced_sloppy_imports_error_message( fn enhanced_sloppy_imports_error_message(
sys: &FsSysTraitsAdapter, sys: &CliSys,
error: &ModuleError, error: &ModuleError,
) -> Option<String> { ) -> Option<String> {
match error { match error {

View file

@ -7,11 +7,11 @@ use crate::cache::LocalLspHttpCache;
use crate::lsp::config::Config; use crate::lsp::config::Config;
use crate::lsp::logging::lsp_log; use crate::lsp::logging::lsp_log;
use crate::lsp::logging::lsp_warn; use crate::lsp::logging::lsp_warn;
use crate::sys::CliSys;
use deno_core::url::Url; use deno_core::url::Url;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_path_util::url_to_file_path; use deno_path_util::url_to_file_path;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
@ -92,12 +92,11 @@ impl LspCache {
}) })
.ok() .ok()
}); });
let deno_dir = DenoDir::new(global_cache_path) let sys = CliSys::default();
let deno_dir = DenoDir::new(sys.clone(), global_cache_path)
.expect("should be infallible with absolute custom root"); .expect("should be infallible with absolute custom root");
let global = Arc::new(GlobalHttpCache::new( let global =
FsSysTraitsAdapter::new_real(), Arc::new(GlobalHttpCache::new(sys, deno_dir.remote_folder_path()));
deno_dir.remote_folder_path(),
));
Self { Self {
deno_dir, deno_dir,
global, global,

View file

@ -36,7 +36,6 @@ use deno_lint::linter::LintConfig as DenoLintConfig;
use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::npm_rc::ResolvedNpmRc;
use deno_package_json::PackageJsonCache; use deno_package_json::PackageJsonCache;
use deno_path_util::url_to_file_path; use deno_path_util::url_to_file_path;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::PackageJson; use deno_runtime::deno_node::PackageJson;
use indexmap::IndexSet; use indexmap::IndexSet;
use lsp_types::ClientCapabilities; use lsp_types::ClientCapabilities;
@ -65,6 +64,7 @@ use crate::file_fetcher::CliFileFetcher;
use crate::lsp::logging::lsp_warn; use crate::lsp::logging::lsp_warn;
use crate::resolver::CliSloppyImportsResolver; use crate::resolver::CliSloppyImportsResolver;
use crate::resolver::SloppyImportsCachedFs; use crate::resolver::SloppyImportsCachedFs;
use crate::sys::CliSys;
use crate::tools::lint::CliLinter; use crate::tools::lint::CliLinter;
use crate::tools::lint::CliLinterOptions; use crate::tools::lint::CliLinterOptions;
use crate::tools::lint::LintRuleProvider; use crate::tools::lint::LintRuleProvider;
@ -1227,7 +1227,7 @@ impl ConfigData {
Ok(scope_dir_path) => { Ok(scope_dir_path) => {
let paths = [scope_dir_path]; let paths = [scope_dir_path];
WorkspaceDirectory::discover( WorkspaceDirectory::discover(
&FsSysTraitsAdapter::new_real(), &CliSys::default(),
match specified_config { match specified_config {
Some(config_path) => { Some(config_path) => {
deno_config::workspace::WorkspaceDiscoverStart::ConfigFile( deno_config::workspace::WorkspaceDiscoverStart::ConfigFile(
@ -1615,9 +1615,7 @@ impl ConfigData {
|| unstable.contains("sloppy-imports"); || unstable.contains("sloppy-imports");
let sloppy_imports_resolver = unstable_sloppy_imports.then(|| { let sloppy_imports_resolver = unstable_sloppy_imports.then(|| {
Arc::new(CliSloppyImportsResolver::new( Arc::new(CliSloppyImportsResolver::new(
SloppyImportsCachedFs::new_without_stat_cache( SloppyImportsCachedFs::new_without_stat_cache(CliSys::default()),
FsSysTraitsAdapter::new_real(),
),
)) ))
}); });
let resolver = Arc::new(resolver); let resolver = Arc::new(resolver);
@ -1921,17 +1919,20 @@ impl ConfigTree {
#[cfg(test)] #[cfg(test)]
pub async fn inject_config_file(&mut self, config_file: ConfigFile) { pub async fn inject_config_file(&mut self, config_file: ConfigFile) {
use sys_traits::FsCreateDirAll;
use sys_traits::FsWrite;
let scope = config_file.specifier.join(".").unwrap(); let scope = config_file.specifier.join(".").unwrap();
let json_text = serde_json::to_string(&config_file.json).unwrap(); let json_text = serde_json::to_string(&config_file.json).unwrap();
let test_fs = Arc::new(deno_runtime::deno_fs::InMemoryFs::default()); let memory_sys = sys_traits::impls::InMemorySys::default();
let config_path = url_to_file_path(&config_file.specifier).unwrap(); let config_path = url_to_file_path(&config_file.specifier).unwrap();
test_fs.setup_text_files(vec![( memory_sys
config_path.to_string_lossy().to_string(), .fs_create_dir_all(config_path.parent().unwrap())
json_text, .unwrap();
)]); memory_sys.fs_write(&config_path, json_text).unwrap();
let workspace_dir = Arc::new( let workspace_dir = Arc::new(
WorkspaceDirectory::discover( WorkspaceDirectory::discover(
&FsSysTraitsAdapter(test_fs.clone()), &memory_sys,
deno_config::workspace::WorkspaceDiscoverStart::ConfigFile( deno_config::workspace::WorkspaceDiscoverStart::ConfigFile(
&config_path, &config_path,
), ),
@ -2008,11 +2009,14 @@ fn resolve_lockfile_from_path(
lockfile_path: PathBuf, lockfile_path: PathBuf,
frozen: bool, frozen: bool,
) -> Option<CliLockfile> { ) -> Option<CliLockfile> {
match CliLockfile::read_from_path(CliLockfileReadFromPathOptions { match CliLockfile::read_from_path(
file_path: lockfile_path, &CliSys::default(),
frozen, CliLockfileReadFromPathOptions {
skip_write: false, file_path: lockfile_path,
}) { frozen,
skip_write: false,
},
) {
Ok(value) => { Ok(value) => {
if value.filename.exists() { if value.filename.exists() {
if let Ok(specifier) = ModuleSpecifier::from_file_path(&value.filename) if let Ok(specifier) = ModuleSpecifier::from_file_path(&value.filename)

View file

@ -21,6 +21,7 @@ use crate::graph_util::enhanced_resolution_error_message;
use crate::lsp::lsp_custom::DiagnosticBatchNotificationParams; use crate::lsp::lsp_custom::DiagnosticBatchNotificationParams;
use crate::resolver::CliSloppyImportsResolver; use crate::resolver::CliSloppyImportsResolver;
use crate::resolver::SloppyImportsCachedFs; use crate::resolver::SloppyImportsCachedFs;
use crate::sys::CliSys;
use crate::tools::lint::CliLinter; use crate::tools::lint::CliLinter;
use crate::tools::lint::CliLinterOptions; use crate::tools::lint::CliLinterOptions;
use crate::tools::lint::LintRuleProvider; use crate::tools::lint::LintRuleProvider;
@ -48,7 +49,6 @@ use deno_graph::SpecifierError;
use deno_lint::linter::LintConfig as DenoLintConfig; use deno_lint::linter::LintConfig as DenoLintConfig;
use deno_resolver::sloppy_imports::SloppyImportsResolution; use deno_resolver::sloppy_imports::SloppyImportsResolution;
use deno_resolver::sloppy_imports::SloppyImportsResolutionKind; use deno_resolver::sloppy_imports::SloppyImportsResolutionKind;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node; use deno_runtime::deno_node;
use deno_runtime::tokio_util::create_basic_runtime; use deno_runtime::tokio_util::create_basic_runtime;
use deno_semver::jsr::JsrPackageReqReference; use deno_semver::jsr::JsrPackageReqReference;
@ -1281,7 +1281,7 @@ impl DenoDiagnostic {
Self::NotInstalledNpm(pkg_req, specifier) => (lsp::DiagnosticSeverity::ERROR, format!("npm package \"{pkg_req}\" is not installed or doesn't exist."), Some(json!({ "specifier": specifier }))), Self::NotInstalledNpm(pkg_req, specifier) => (lsp::DiagnosticSeverity::ERROR, format!("npm package \"{pkg_req}\" is not installed or doesn't exist."), Some(json!({ "specifier": specifier }))),
Self::NoLocal(specifier) => { Self::NoLocal(specifier) => {
let maybe_sloppy_resolution = CliSloppyImportsResolver::new( let maybe_sloppy_resolution = CliSloppyImportsResolver::new(
SloppyImportsCachedFs::new(FsSysTraitsAdapter::new_real()) SloppyImportsCachedFs::new(CliSys::default())
).resolve(specifier, SloppyImportsResolutionKind::Execution); ).resolve(specifier, SloppyImportsResolutionKind::Execution);
let data = maybe_sloppy_resolution.as_ref().map(|res| { let data = maybe_sloppy_resolution.as_ref().map(|res| {
json!({ json!({

View file

@ -17,7 +17,6 @@ use deno_core::ModuleSpecifier;
use deno_graph::GraphKind; use deno_graph::GraphKind;
use deno_graph::Resolution; use deno_graph::Resolution;
use deno_path_util::url_to_file_path; use deno_path_util::url_to_file_path;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_tls::rustls::RootCertStore; use deno_runtime::deno_tls::rustls::RootCertStore;
use deno_runtime::deno_tls::RootCertStoreProvider; use deno_runtime::deno_tls::RootCertStoreProvider;
use deno_semver::jsr::JsrPackageReqReference; use deno_semver::jsr::JsrPackageReqReference;
@ -109,6 +108,7 @@ use crate::lsp::config::ConfigWatchedFileType;
use crate::lsp::logging::init_log_file; use crate::lsp::logging::init_log_file;
use crate::lsp::tsc::file_text_changes_to_workspace_edit; use crate::lsp::tsc::file_text_changes_to_workspace_edit;
use crate::lsp::urls::LspUrlKind; use crate::lsp::urls::LspUrlKind;
use crate::sys::CliSys;
use crate::tools::fmt::format_file; use crate::tools::fmt::format_file;
use crate::tools::fmt::format_parsed_source; use crate::tools::fmt::format_parsed_source;
use crate::tools::upgrade::check_for_upgrades_for_lsp; use crate::tools::upgrade::check_for_upgrades_for_lsp;
@ -280,7 +280,7 @@ impl LanguageServer {
.await?; .await?;
graph_util::graph_valid( graph_util::graph_valid(
&graph, &graph,
&FsSysTraitsAdapter(factory.fs().clone()), &CliSys::default(),
&roots, &roots,
graph_util::GraphValidOptions { graph_util::GraphValidOptions {
kind: GraphKind::All, kind: GraphKind::All,
@ -962,6 +962,7 @@ impl Inner {
let file_fetcher = CliFileFetcher::new( let file_fetcher = CliFileFetcher::new(
self.cache.global().clone(), self.cache.global().clone(),
self.http_client_provider.clone(), self.http_client_provider.clone(),
CliSys::default(),
Default::default(), Default::default(),
None, None,
true, true,
@ -3613,7 +3614,7 @@ impl Inner {
let workspace = match config_data { let workspace = match config_data {
Some(d) => d.member_dir.clone(), Some(d) => d.member_dir.clone(),
None => Arc::new(WorkspaceDirectory::discover( None => Arc::new(WorkspaceDirectory::discover(
&FsSysTraitsAdapter::new_real(), &CliSys::default(),
deno_config::workspace::WorkspaceDiscoverStart::Paths(&[ deno_config::workspace::WorkspaceDiscoverStart::Paths(&[
initial_cwd.clone() initial_cwd.clone()
]), ]),
@ -3634,6 +3635,7 @@ impl Inner {
)?), )?),
}; };
let cli_options = CliOptions::new( let cli_options = CliOptions::new(
&CliSys::default(),
Arc::new(Flags { Arc::new(Flags {
internal: InternalFlags { internal: InternalFlags {
cache_path: Some(self.cache.deno_dir().root.clone()), cache_path: Some(self.cache.deno_dir().root.clone()),

View file

@ -19,6 +19,7 @@ use crate::file_fetcher::FetchOptions;
use crate::file_fetcher::FetchPermissionsOptionRef; use crate::file_fetcher::FetchPermissionsOptionRef;
use crate::file_fetcher::TextDecodedFile; use crate::file_fetcher::TextDecodedFile;
use crate::http_util::HttpClientProvider; use crate::http_util::HttpClientProvider;
use crate::sys::CliSys;
use deno_cache_dir::file_fetcher::CacheSetting; use deno_cache_dir::file_fetcher::CacheSetting;
use deno_core::anyhow::anyhow; use deno_core::anyhow::anyhow;
@ -32,7 +33,6 @@ use deno_core::url::Position;
use deno_core::url::Url; use deno_core::url::Url;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_graph::Dependency; use deno_graph::Dependency;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use log::error; use log::error;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::borrow::Cow; use std::borrow::Cow;
@ -430,13 +430,12 @@ impl ModuleRegistry {
http_client_provider: Arc<HttpClientProvider>, http_client_provider: Arc<HttpClientProvider>,
) -> Self { ) -> Self {
// the http cache should always be the global one for registry completions // the http cache should always be the global one for registry completions
let http_cache = Arc::new(GlobalHttpCache::new( let http_cache =
FsSysTraitsAdapter::new_real(), Arc::new(GlobalHttpCache::new(CliSys::default(), location.clone()));
location.clone(),
));
let file_fetcher = CliFileFetcher::new( let file_fetcher = CliFileFetcher::new(
http_cache.clone(), http_cache.clone(),
http_client_provider, http_client_provider,
CliSys::default(),
Default::default(), Default::default(),
None, None,
true, true,

View file

@ -19,9 +19,6 @@ use deno_resolver::cjs::IsCjsResolutionMode;
use deno_resolver::npm::NpmReqResolverOptions; use deno_resolver::npm::NpmReqResolverOptions;
use deno_resolver::DenoResolverOptions; use deno_resolver::DenoResolverOptions;
use deno_resolver::NodeAndNpmReqResolver; use deno_resolver::NodeAndNpmReqResolver;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::NodeResolver;
use deno_runtime::deno_node::PackageJsonResolver;
use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker; use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker;
use deno_semver::jsr::JsrPackageReqReference; use deno_semver::jsr::JsrPackageReqReference;
use deno_semver::npm::NpmPackageReqReference; use deno_semver::npm::NpmPackageReqReference;
@ -51,6 +48,8 @@ use crate::http_util::HttpClientProvider;
use crate::lsp::config::Config; use crate::lsp::config::Config;
use crate::lsp::config::ConfigData; use crate::lsp::config::ConfigData;
use crate::lsp::logging::lsp_warn; use crate::lsp::logging::lsp_warn;
use crate::node::CliNodeResolver;
use crate::node::CliPackageJsonResolver;
use crate::npm::create_cli_npm_resolver_for_lsp; use crate::npm::create_cli_npm_resolver_for_lsp;
use crate::npm::CliByonmNpmResolverCreateOptions; use crate::npm::CliByonmNpmResolverCreateOptions;
use crate::npm::CliManagedInNpmPkgCheckerCreateOptions; use crate::npm::CliManagedInNpmPkgCheckerCreateOptions;
@ -66,6 +65,7 @@ use crate::resolver::CliResolver;
use crate::resolver::CliResolverOptions; use crate::resolver::CliResolverOptions;
use crate::resolver::IsCjsResolver; use crate::resolver::IsCjsResolver;
use crate::resolver::WorkerCliNpmGraphResolver; use crate::resolver::WorkerCliNpmGraphResolver;
use crate::sys::CliSys;
use crate::tsc::into_specifier_and_media_type; use crate::tsc::into_specifier_and_media_type;
use crate::util::progress_bar::ProgressBar; use crate::util::progress_bar::ProgressBar;
use crate::util::progress_bar::ProgressBarStyle; use crate::util::progress_bar::ProgressBarStyle;
@ -77,9 +77,9 @@ struct LspScopeResolver {
is_cjs_resolver: Arc<IsCjsResolver>, is_cjs_resolver: Arc<IsCjsResolver>,
jsr_resolver: Option<Arc<JsrCacheResolver>>, jsr_resolver: Option<Arc<JsrCacheResolver>>,
npm_resolver: Option<Arc<dyn CliNpmResolver>>, npm_resolver: Option<Arc<dyn CliNpmResolver>>,
node_resolver: Option<Arc<NodeResolver>>, node_resolver: Option<Arc<CliNodeResolver>>,
npm_pkg_req_resolver: Option<Arc<CliNpmReqResolver>>, npm_pkg_req_resolver: Option<Arc<CliNpmReqResolver>>,
pkg_json_resolver: Arc<PackageJsonResolver>, pkg_json_resolver: Arc<CliPackageJsonResolver>,
redirect_resolver: Option<Arc<RedirectResolver>>, redirect_resolver: Option<Arc<RedirectResolver>>,
graph_imports: Arc<IndexMap<ModuleSpecifier, GraphImport>>, graph_imports: Arc<IndexMap<ModuleSpecifier, GraphImport>>,
dep_info: Arc<Mutex<Arc<ScopeDepInfo>>>, dep_info: Arc<Mutex<Arc<ScopeDepInfo>>>,
@ -383,7 +383,7 @@ impl LspResolver {
pub fn pkg_json_resolver( pub fn pkg_json_resolver(
&self, &self,
referrer: &ModuleSpecifier, referrer: &ModuleSpecifier,
) -> &Arc<PackageJsonResolver> { ) -> &Arc<CliPackageJsonResolver> {
let resolver = self.get_scope_resolver(Some(referrer)); let resolver = self.get_scope_resolver(Some(referrer));
&resolver.pkg_json_resolver &resolver.pkg_json_resolver
} }
@ -591,22 +591,22 @@ struct ResolverFactoryServices {
cli_resolver: Deferred<Arc<CliResolver>>, cli_resolver: Deferred<Arc<CliResolver>>,
in_npm_pkg_checker: Deferred<Arc<dyn InNpmPackageChecker>>, in_npm_pkg_checker: Deferred<Arc<dyn InNpmPackageChecker>>,
is_cjs_resolver: Deferred<Arc<IsCjsResolver>>, is_cjs_resolver: Deferred<Arc<IsCjsResolver>>,
node_resolver: Deferred<Option<Arc<NodeResolver>>>, node_resolver: Deferred<Option<Arc<CliNodeResolver>>>,
npm_pkg_req_resolver: Deferred<Option<Arc<CliNpmReqResolver>>>, npm_pkg_req_resolver: Deferred<Option<Arc<CliNpmReqResolver>>>,
npm_resolver: Option<Arc<dyn CliNpmResolver>>, npm_resolver: Option<Arc<dyn CliNpmResolver>>,
} }
struct ResolverFactory<'a> { struct ResolverFactory<'a> {
config_data: Option<&'a Arc<ConfigData>>, config_data: Option<&'a Arc<ConfigData>>,
pkg_json_resolver: Arc<PackageJsonResolver>, pkg_json_resolver: Arc<CliPackageJsonResolver>,
sys: FsSysTraitsAdapter, sys: CliSys,
services: ResolverFactoryServices, services: ResolverFactoryServices,
} }
impl<'a> ResolverFactory<'a> { impl<'a> ResolverFactory<'a> {
pub fn new(config_data: Option<&'a Arc<ConfigData>>) -> Self { pub fn new(config_data: Option<&'a Arc<ConfigData>>) -> Self {
let sys = FsSysTraitsAdapter::new_real(); let sys = CliSys::default();
let pkg_json_resolver = Arc::new(PackageJsonResolver::new(sys.clone())); let pkg_json_resolver = Arc::new(CliPackageJsonResolver::new(sys.clone()));
Self { Self {
config_data, config_data,
pkg_json_resolver, pkg_json_resolver,
@ -621,7 +621,7 @@ impl<'a> ResolverFactory<'a> {
cache: &LspCache, cache: &LspCache,
) { ) {
let enable_byonm = self.config_data.map(|d| d.byonm).unwrap_or(false); let enable_byonm = self.config_data.map(|d| d.byonm).unwrap_or(false);
let sys = FsSysTraitsAdapter::new_real(); let sys = CliSys::default();
let options = if enable_byonm { let options = if enable_byonm {
CliNpmResolverCreateOptions::Byonm(CliByonmNpmResolverCreateOptions { CliNpmResolverCreateOptions::Byonm(CliByonmNpmResolverCreateOptions {
sys, sys,
@ -656,7 +656,7 @@ impl<'a> ResolverFactory<'a> {
} }
None => CliNpmResolverManagedSnapshotOption::Specified(None), None => CliNpmResolverManagedSnapshotOption::Specified(None),
}, },
sys: FsSysTraitsAdapter::new_real(), sys: CliSys::default(),
npm_cache_dir, npm_cache_dir,
// Use an "only" cache setting in order to make the // Use an "only" cache setting in order to make the
// user do an explicit "cache" command and prevent // user do an explicit "cache" command and prevent
@ -729,7 +729,7 @@ impl<'a> ResolverFactory<'a> {
}) })
} }
pub fn pkg_json_resolver(&self) -> &Arc<PackageJsonResolver> { pub fn pkg_json_resolver(&self) -> &Arc<CliPackageJsonResolver> {
&self.pkg_json_resolver &self.pkg_json_resolver
} }
@ -770,13 +770,13 @@ impl<'a> ResolverFactory<'a> {
}) })
} }
pub fn node_resolver(&self) -> Option<&Arc<NodeResolver>> { pub fn node_resolver(&self) -> Option<&Arc<CliNodeResolver>> {
self self
.services .services
.node_resolver .node_resolver
.get_or_init(|| { .get_or_init(|| {
let npm_resolver = self.services.npm_resolver.as_ref()?; let npm_resolver = self.services.npm_resolver.as_ref()?;
Some(Arc::new(NodeResolver::new( Some(Arc::new(CliNodeResolver::new(
self.in_npm_pkg_checker().clone(), self.in_npm_pkg_checker().clone(),
RealIsBuiltInNodeModuleChecker, RealIsBuiltInNodeModuleChecker,
npm_resolver.clone().into_npm_pkg_folder_resolver(), npm_resolver.clone().into_npm_pkg_folder_resolver(),

View file

@ -20,6 +20,7 @@ mod ops;
mod resolver; mod resolver;
mod shared; mod shared;
mod standalone; mod standalone;
mod sys;
mod task_runner; mod task_runner;
mod tools; mod tools;
mod tsc; mod tsc;

View file

@ -18,6 +18,7 @@ mod node;
mod npm; mod npm;
mod resolver; mod resolver;
mod shared; mod shared;
mod sys;
mod task_runner; mod task_runner;
mod util; mod util;
mod version; mod version;
@ -31,11 +32,13 @@ use deno_runtime::tokio_util::create_and_run_current_thread_with_maybe_metrics;
pub use deno_runtime::UNSTABLE_GRANULAR_FLAGS; pub use deno_runtime::UNSTABLE_GRANULAR_FLAGS;
use deno_terminal::colors; use deno_terminal::colors;
use indexmap::IndexMap; use indexmap::IndexMap;
use standalone::DenoCompileFileSystem;
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::HashMap; use std::collections::HashMap;
use std::env; use std::env;
use std::env::current_exe; use std::env::current_exe;
use std::sync::Arc;
use crate::args::Flags; use crate::args::Flags;
@ -92,7 +95,9 @@ fn main() {
Some(data.metadata.otel_config.clone()), Some(data.metadata.otel_config.clone()),
); );
load_env_vars(&data.metadata.env_vars_from_env_file); load_env_vars(&data.metadata.env_vars_from_env_file);
let exit_code = standalone::run(data).await?; let fs = DenoCompileFileSystem::new(data.vfs.clone());
let sys = crate::sys::CliSys::DenoCompile(fs.clone());
let exit_code = standalone::run(Arc::new(fs), sys, data).await?;
deno_runtime::exit(exit_code); deno_runtime::exit(exit_code);
} }
Ok(None) => Ok(()), Ok(None) => Ok(()),

View file

@ -11,6 +11,8 @@ use std::sync::atomic::AtomicU16;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::sync::Arc; use std::sync::Arc;
use crate::node::CliNodeResolver;
use crate::sys::CliSys;
use deno_ast::MediaType; use deno_ast::MediaType;
use deno_ast::ModuleKind; use deno_ast::ModuleKind;
use deno_core::anyhow::anyhow; use deno_core::anyhow::anyhow;
@ -39,10 +41,8 @@ use deno_graph::ModuleGraph;
use deno_graph::Resolution; use deno_graph::Resolution;
use deno_graph::WasmModule; use deno_graph::WasmModule;
use deno_runtime::code_cache; use deno_runtime::code_cache;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::create_host_defined_options; use deno_runtime::deno_node::create_host_defined_options;
use deno_runtime::deno_node::NodeRequireLoader; use deno_runtime::deno_node::NodeRequireLoader;
use deno_runtime::deno_node::NodeResolver;
use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_permissions::PermissionsContainer;
use deno_semver::npm::NpmPackageReqReference; use deno_semver::npm::NpmPackageReqReference;
use node_resolver::errors::ClosestPkgJsonError; use node_resolver::errors::ClosestPkgJsonError;
@ -220,13 +220,13 @@ struct SharedCliModuleLoaderState {
main_module_graph_container: Arc<MainModuleGraphContainer>, main_module_graph_container: Arc<MainModuleGraphContainer>,
module_load_preparer: Arc<ModuleLoadPreparer>, module_load_preparer: Arc<ModuleLoadPreparer>,
node_code_translator: Arc<CliNodeCodeTranslator>, node_code_translator: Arc<CliNodeCodeTranslator>,
node_resolver: Arc<NodeResolver>, node_resolver: Arc<CliNodeResolver>,
npm_req_resolver: Arc<CliNpmReqResolver>, npm_req_resolver: Arc<CliNpmReqResolver>,
npm_resolver: Arc<dyn CliNpmResolver>, npm_resolver: Arc<dyn CliNpmResolver>,
npm_module_loader: NpmModuleLoader, npm_module_loader: NpmModuleLoader,
parsed_source_cache: Arc<ParsedSourceCache>, parsed_source_cache: Arc<ParsedSourceCache>,
resolver: Arc<CliResolver>, resolver: Arc<CliResolver>,
sys: FsSysTraitsAdapter, sys: CliSys,
in_flight_loads_tracker: InFlightModuleLoadsTracker, in_flight_loads_tracker: InFlightModuleLoadsTracker,
} }
@ -280,13 +280,13 @@ impl CliModuleLoaderFactory {
main_module_graph_container: Arc<MainModuleGraphContainer>, main_module_graph_container: Arc<MainModuleGraphContainer>,
module_load_preparer: Arc<ModuleLoadPreparer>, module_load_preparer: Arc<ModuleLoadPreparer>,
node_code_translator: Arc<CliNodeCodeTranslator>, node_code_translator: Arc<CliNodeCodeTranslator>,
node_resolver: Arc<NodeResolver>, node_resolver: Arc<CliNodeResolver>,
npm_req_resolver: Arc<CliNpmReqResolver>, npm_req_resolver: Arc<CliNpmReqResolver>,
npm_resolver: Arc<dyn CliNpmResolver>, npm_resolver: Arc<dyn CliNpmResolver>,
npm_module_loader: NpmModuleLoader, npm_module_loader: NpmModuleLoader,
parsed_source_cache: Arc<ParsedSourceCache>, parsed_source_cache: Arc<ParsedSourceCache>,
resolver: Arc<CliResolver>, resolver: Arc<CliResolver>,
sys: FsSysTraitsAdapter, sys: CliSys,
) -> Self { ) -> Self {
Self { Self {
shared: Arc::new(SharedCliModuleLoaderState { shared: Arc::new(SharedCliModuleLoaderState {
@ -1092,7 +1092,7 @@ impl ModuleGraphUpdatePermit for WorkerModuleGraphUpdatePermit {
struct CliNodeRequireLoader<TGraphContainer: ModuleGraphContainer> { struct CliNodeRequireLoader<TGraphContainer: ModuleGraphContainer> {
cjs_tracker: Arc<CjsTracker>, cjs_tracker: Arc<CjsTracker>,
emitter: Arc<Emitter>, emitter: Arc<Emitter>,
sys: FsSysTraitsAdapter, sys: CliSys,
graph_container: TGraphContainer, graph_container: TGraphContainer,
in_npm_pkg_checker: Arc<dyn InNpmPackageChecker>, in_npm_pkg_checker: Arc<dyn InNpmPackageChecker>,
npm_resolver: Arc<dyn CliNpmResolver>, npm_resolver: Arc<dyn CliNpmResolver>,

View file

@ -8,7 +8,6 @@ use deno_ast::ModuleSpecifier;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_graph::ParsedSourceStore; use deno_graph::ParsedSourceStore;
use deno_runtime::deno_fs; use deno_runtime::deno_fs;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker; use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker;
use node_resolver::analyze::CjsAnalysis as ExtNodeCjsAnalysis; use node_resolver::analyze::CjsAnalysis as ExtNodeCjsAnalysis;
use node_resolver::analyze::CjsAnalysisExports; use node_resolver::analyze::CjsAnalysisExports;
@ -21,12 +20,15 @@ use crate::cache::CacheDBHash;
use crate::cache::NodeAnalysisCache; use crate::cache::NodeAnalysisCache;
use crate::cache::ParsedSourceCache; use crate::cache::ParsedSourceCache;
use crate::resolver::CjsTracker; use crate::resolver::CjsTracker;
use crate::sys::CliSys;
pub type CliNodeCodeTranslator = NodeCodeTranslator< pub type CliNodeCodeTranslator = NodeCodeTranslator<
CliCjsCodeAnalyzer, CliCjsCodeAnalyzer,
RealIsBuiltInNodeModuleChecker, RealIsBuiltInNodeModuleChecker,
FsSysTraitsAdapter, CliSys,
>; >;
pub type CliNodeResolver = deno_runtime::deno_node::NodeResolver<CliSys>;
pub type CliPackageJsonResolver = node_resolver::PackageJsonResolver<CliSys>;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum CliCjsAnalysis { pub enum CliCjsAnalysis {

View file

@ -4,12 +4,12 @@ use std::borrow::Cow;
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
use crate::sys::CliSys;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::serde_json; use deno_core::serde_json;
use deno_resolver::npm::ByonmNpmResolver; use deno_resolver::npm::ByonmNpmResolver;
use deno_resolver::npm::ByonmNpmResolverCreateOptions; use deno_resolver::npm::ByonmNpmResolverCreateOptions;
use deno_resolver::npm::CliNpmReqResolver; use deno_resolver::npm::CliNpmReqResolver;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodePermissions;
use deno_runtime::ops::process::NpmProcessStateProvider; use deno_runtime::ops::process::NpmProcessStateProvider;
use node_resolver::NpmPackageFolderResolver; use node_resolver::NpmPackageFolderResolver;
@ -21,8 +21,8 @@ use super::CliNpmResolver;
use super::InnerCliNpmResolverRef; use super::InnerCliNpmResolverRef;
pub type CliByonmNpmResolverCreateOptions = pub type CliByonmNpmResolverCreateOptions =
ByonmNpmResolverCreateOptions<FsSysTraitsAdapter>; ByonmNpmResolverCreateOptions<CliSys>;
pub type CliByonmNpmResolver = ByonmNpmResolver<FsSysTraitsAdapter>; pub type CliByonmNpmResolver = ByonmNpmResolver<CliSys>;
// todo(dsherret): the services hanging off `CliNpmResolver` doesn't seem ideal. We should probably decouple. // todo(dsherret): the services hanging off `CliNpmResolver` doesn't seem ideal. We should probably decouple.
#[derive(Debug)] #[derive(Debug)]

View file

@ -5,6 +5,7 @@ use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use crate::sys::CliSys;
use deno_ast::ModuleSpecifier; use deno_ast::ModuleSpecifier;
use deno_cache_dir::npm::NpmCacheDir; use deno_cache_dir::npm::NpmCacheDir;
use deno_core::anyhow::Context; use deno_core::anyhow::Context;
@ -24,7 +25,6 @@ use deno_npm_cache::NpmCacheSetting;
use deno_path_util::fs::canonicalize_path_maybe_not_exists; use deno_path_util::fs::canonicalize_path_maybe_not_exists;
use deno_resolver::npm::CliNpmReqResolver; use deno_resolver::npm::CliNpmReqResolver;
use deno_runtime::colors; use deno_runtime::colors;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodePermissions;
use deno_runtime::ops::process::NpmProcessStateProvider; use deno_runtime::ops::process::NpmProcessStateProvider;
use deno_semver::package::PackageNv; use deno_semver::package::PackageNv;
@ -70,7 +70,7 @@ pub struct CliManagedNpmResolverCreateOptions {
pub maybe_lockfile: Option<Arc<CliLockfile>>, pub maybe_lockfile: Option<Arc<CliLockfile>>,
pub http_client_provider: Arc<crate::http_util::HttpClientProvider>, pub http_client_provider: Arc<crate::http_util::HttpClientProvider>,
pub npm_cache_dir: Arc<NpmCacheDir>, pub npm_cache_dir: Arc<NpmCacheDir>,
pub sys: FsSysTraitsAdapter, pub sys: CliSys,
pub cache_setting: deno_cache_dir::file_fetcher::CacheSetting, pub cache_setting: deno_cache_dir::file_fetcher::CacheSetting,
pub text_only_progress_bar: crate::util::progress_bar::ProgressBar, pub text_only_progress_bar: crate::util::progress_bar::ProgressBar,
pub maybe_node_modules_path: Option<PathBuf>, pub maybe_node_modules_path: Option<PathBuf>,
@ -149,7 +149,7 @@ fn create_inner(
npm_cache: Arc<CliNpmCache>, npm_cache: Arc<CliNpmCache>,
npm_install_deps_provider: Arc<NpmInstallDepsProvider>, npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
registry_info_provider: Arc<CliNpmRegistryInfoProvider>, registry_info_provider: Arc<CliNpmRegistryInfoProvider>,
sys: FsSysTraitsAdapter, sys: CliSys,
text_only_progress_bar: crate::util::progress_bar::ProgressBar, text_only_progress_bar: crate::util::progress_bar::ProgressBar,
maybe_lockfile: Option<Arc<CliLockfile>>, maybe_lockfile: Option<Arc<CliLockfile>>,
npm_rc: Arc<ResolvedNpmRc>, npm_rc: Arc<ResolvedNpmRc>,
@ -307,7 +307,7 @@ pub struct ManagedCliNpmResolver {
registry_info_provider: Arc<CliNpmRegistryInfoProvider>, registry_info_provider: Arc<CliNpmRegistryInfoProvider>,
npm_cache: Arc<CliNpmCache>, npm_cache: Arc<CliNpmCache>,
npm_install_deps_provider: Arc<NpmInstallDepsProvider>, npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
sys: FsSysTraitsAdapter, sys: CliSys,
resolution: Arc<NpmResolution>, resolution: Arc<NpmResolution>,
tarball_cache: Arc<CliNpmTarballCache>, tarball_cache: Arc<CliNpmTarballCache>,
text_only_progress_bar: ProgressBar, text_only_progress_bar: ProgressBar,
@ -333,7 +333,7 @@ impl ManagedCliNpmResolver {
npm_cache: Arc<CliNpmCache>, npm_cache: Arc<CliNpmCache>,
npm_install_deps_provider: Arc<NpmInstallDepsProvider>, npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
resolution: Arc<NpmResolution>, resolution: Arc<NpmResolution>,
sys: FsSysTraitsAdapter, sys: CliSys,
tarball_cache: Arc<CliNpmTarballCache>, tarball_cache: Arc<CliNpmTarballCache>,
text_only_progress_bar: ProgressBar, text_only_progress_bar: ProgressBar,
npm_system_info: NpmSystemInfo, npm_system_info: NpmSystemInfo,

View file

@ -20,13 +20,13 @@ use deno_core::futures::StreamExt;
use deno_npm::NpmPackageCacheFolderId; use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId; use deno_npm::NpmPackageId;
use deno_npm::NpmResolutionPackage; use deno_npm::NpmResolutionPackage;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodePermissions;
use node_resolver::errors::PackageFolderResolveError; use node_resolver::errors::PackageFolderResolveError;
use sys_traits::FsCanonicalize; use sys_traits::FsCanonicalize;
use super::super::PackageCaching; use super::super::PackageCaching;
use crate::npm::CliNpmTarballCache; use crate::npm::CliNpmTarballCache;
use crate::sys::CliSys;
/// Part of the resolution that interacts with the file system. /// Part of the resolution that interacts with the file system.
#[async_trait(?Send)] #[async_trait(?Send)]
@ -74,15 +74,15 @@ pub trait NpmPackageFsResolver: Send + Sync {
#[derive(Debug)] #[derive(Debug)]
pub struct RegistryReadPermissionChecker { pub struct RegistryReadPermissionChecker {
sys: FsSysTraitsAdapter, sys: CliSys,
cache: Mutex<HashMap<PathBuf, PathBuf>>, cache: Mutex<HashMap<PathBuf, PathBuf>>,
registry_path: PathBuf, registry_path: PathBuf,
} }
impl RegistryReadPermissionChecker { impl RegistryReadPermissionChecker {
pub fn new(fs: FsSysTraitsAdapter, registry_path: PathBuf) -> Self { pub fn new(sys: CliSys, registry_path: PathBuf) -> Self {
Self { Self {
sys: fs, sys,
registry_path, registry_path,
cache: Default::default(), cache: Default::default(),
} }

View file

@ -11,6 +11,7 @@ use crate::colors;
use crate::npm::managed::PackageCaching; use crate::npm::managed::PackageCaching;
use crate::npm::CliNpmCache; use crate::npm::CliNpmCache;
use crate::npm::CliNpmTarballCache; use crate::npm::CliNpmTarballCache;
use crate::sys::CliSys;
use async_trait::async_trait; use async_trait::async_trait;
use deno_ast::ModuleSpecifier; use deno_ast::ModuleSpecifier;
use deno_core::error::AnyError; use deno_core::error::AnyError;
@ -18,7 +19,6 @@ use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId; use deno_npm::NpmPackageId;
use deno_npm::NpmResolutionPackage; use deno_npm::NpmResolutionPackage;
use deno_npm::NpmSystemInfo; use deno_npm::NpmSystemInfo;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodePermissions;
use node_resolver::errors::PackageFolderResolveError; use node_resolver::errors::PackageFolderResolveError;
use node_resolver::errors::PackageNotFoundError; use node_resolver::errors::PackageNotFoundError;
@ -49,7 +49,7 @@ impl GlobalNpmPackageResolver {
cache: Arc<CliNpmCache>, cache: Arc<CliNpmCache>,
tarball_cache: Arc<CliNpmTarballCache>, tarball_cache: Arc<CliNpmTarballCache>,
resolution: Arc<NpmResolution>, resolution: Arc<NpmResolution>,
sys: FsSysTraitsAdapter, sys: CliSys,
system_info: NpmSystemInfo, system_info: NpmSystemInfo,
lifecycle_scripts: LifecycleScriptsConfig, lifecycle_scripts: LifecycleScriptsConfig,
) -> Self { ) -> Self {

View file

@ -32,7 +32,6 @@ use deno_npm::NpmSystemInfo;
use deno_path_util::fs::atomic_write_file_with_retries; use deno_path_util::fs::atomic_write_file_with_retries;
use deno_path_util::fs::canonicalize_path_maybe_not_exists; use deno_path_util::fs::canonicalize_path_maybe_not_exists;
use deno_resolver::npm::normalize_pkg_name_for_node_modules_deno_folder; use deno_resolver::npm::normalize_pkg_name_for_node_modules_deno_folder;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodePermissions;
use deno_semver::package::PackageNv; use deno_semver::package::PackageNv;
use deno_semver::StackString; use deno_semver::StackString;
@ -51,6 +50,7 @@ use crate::colors;
use crate::npm::managed::PackageCaching; use crate::npm::managed::PackageCaching;
use crate::npm::CliNpmCache; use crate::npm::CliNpmCache;
use crate::npm::CliNpmTarballCache; use crate::npm::CliNpmTarballCache;
use crate::sys::CliSys;
use crate::util::fs::clone_dir_recursive; use crate::util::fs::clone_dir_recursive;
use crate::util::fs::symlink_dir; use crate::util::fs::symlink_dir;
use crate::util::fs::LaxSingleProcessFsFlag; use crate::util::fs::LaxSingleProcessFsFlag;
@ -70,7 +70,7 @@ pub struct LocalNpmPackageResolver {
npm_install_deps_provider: Arc<NpmInstallDepsProvider>, npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
progress_bar: ProgressBar, progress_bar: ProgressBar,
resolution: Arc<NpmResolution>, resolution: Arc<NpmResolution>,
sys: FsSysTraitsAdapter, sys: CliSys,
tarball_cache: Arc<CliNpmTarballCache>, tarball_cache: Arc<CliNpmTarballCache>,
root_node_modules_path: PathBuf, root_node_modules_path: PathBuf,
root_node_modules_url: Url, root_node_modules_url: Url,
@ -86,7 +86,7 @@ impl LocalNpmPackageResolver {
npm_install_deps_provider: Arc<NpmInstallDepsProvider>, npm_install_deps_provider: Arc<NpmInstallDepsProvider>,
progress_bar: ProgressBar, progress_bar: ProgressBar,
resolution: Arc<NpmResolution>, resolution: Arc<NpmResolution>,
sys: FsSysTraitsAdapter, sys: CliSys,
tarball_cache: Arc<CliNpmTarballCache>, tarball_cache: Arc<CliNpmTarballCache>,
node_modules_folder: PathBuf, node_modules_folder: PathBuf,
system_info: NpmSystemInfo, system_info: NpmSystemInfo,
@ -926,7 +926,7 @@ impl SetupCache {
bincode::serialize(&self.current).ok().and_then(|data| { bincode::serialize(&self.current).ok().and_then(|data| {
atomic_write_file_with_retries( atomic_write_file_with_retries(
&FsSysTraitsAdapter::new_real(), &CliSys::default(),
&self.file_path, &self.file_path,
&data, &data,
CACHE_PERM, CACHE_PERM,

View file

@ -7,8 +7,8 @@ mod local;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use crate::sys::CliSys;
use deno_npm::NpmSystemInfo; use deno_npm::NpmSystemInfo;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use crate::args::LifecycleScriptsConfig; use crate::args::LifecycleScriptsConfig;
use crate::args::NpmInstallDepsProvider; use crate::args::NpmInstallDepsProvider;
@ -29,7 +29,7 @@ pub fn create_npm_fs_resolver(
npm_install_deps_provider: &Arc<NpmInstallDepsProvider>, npm_install_deps_provider: &Arc<NpmInstallDepsProvider>,
progress_bar: &ProgressBar, progress_bar: &ProgressBar,
resolution: Arc<NpmResolution>, resolution: Arc<NpmResolution>,
sys: FsSysTraitsAdapter, sys: CliSys,
tarball_cache: Arc<CliNpmTarballCache>, tarball_cache: Arc<CliNpmTarballCache>,
maybe_node_modules_path: Option<PathBuf>, maybe_node_modules_path: Option<PathBuf>,
system_info: NpmSystemInfo, system_info: NpmSystemInfo,

View file

@ -7,6 +7,7 @@ use std::borrow::Cow;
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
use crate::sys::CliSys;
use dashmap::DashMap; use dashmap::DashMap;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::serde_json; use deno_core::serde_json;
@ -17,7 +18,6 @@ use deno_resolver::npm::ByonmInNpmPackageChecker;
use deno_resolver::npm::ByonmNpmResolver; use deno_resolver::npm::ByonmNpmResolver;
use deno_resolver::npm::CliNpmReqResolver; use deno_resolver::npm::CliNpmReqResolver;
use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; use deno_resolver::npm::ResolvePkgFolderFromDenoReqError;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodePermissions;
use deno_runtime::ops::process::NpmProcessStateProvider; use deno_runtime::ops::process::NpmProcessStateProvider;
use deno_semver::package::PackageNv; use deno_semver::package::PackageNv;
@ -41,12 +41,10 @@ pub use self::managed::ManagedCliNpmResolver;
pub use self::managed::PackageCaching; pub use self::managed::PackageCaching;
pub type CliNpmTarballCache = pub type CliNpmTarballCache =
deno_npm_cache::TarballCache<CliNpmCacheHttpClient, FsSysTraitsAdapter>; deno_npm_cache::TarballCache<CliNpmCacheHttpClient, CliSys>;
pub type CliNpmCache = deno_npm_cache::NpmCache<FsSysTraitsAdapter>; pub type CliNpmCache = deno_npm_cache::NpmCache<CliSys>;
pub type CliNpmRegistryInfoProvider = deno_npm_cache::RegistryInfoProvider< pub type CliNpmRegistryInfoProvider =
CliNpmCacheHttpClient, deno_npm_cache::RegistryInfoProvider<CliNpmCacheHttpClient, CliSys>;
FsSysTraitsAdapter,
>;
#[derive(Debug)] #[derive(Debug)]
pub struct CliNpmCacheHttpClient { pub struct CliNpmCacheHttpClient {

View file

@ -5,6 +5,7 @@ use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use crate::sys::CliSys;
use async_trait::async_trait; use async_trait::async_trait;
use dashmap::DashMap; use dashmap::DashMap;
use dashmap::DashSet; use dashmap::DashSet;
@ -25,7 +26,6 @@ use deno_npm::resolution::NpmResolutionError;
use deno_resolver::sloppy_imports::SloppyImportsResolver; use deno_resolver::sloppy_imports::SloppyImportsResolver;
use deno_runtime::colors; use deno_runtime::colors;
use deno_runtime::deno_fs; use deno_runtime::deno_fs;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::is_builtin_node_module; use deno_runtime::deno_node::is_builtin_node_module;
use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker; use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker;
use deno_semver::package::PackageReq; use deno_semver::package::PackageReq;
@ -43,19 +43,17 @@ use crate::npm::InnerCliNpmResolverRef;
use crate::util::sync::AtomicFlag; use crate::util::sync::AtomicFlag;
use crate::util::text_encoding::from_utf8_lossy_cow; use crate::util::text_encoding::from_utf8_lossy_cow;
pub type CjsTracker = deno_resolver::cjs::CjsTracker<FsSysTraitsAdapter>; pub type CjsTracker = deno_resolver::cjs::CjsTracker<CliSys>;
pub type IsCjsResolver = deno_resolver::cjs::IsCjsResolver<FsSysTraitsAdapter>; pub type IsCjsResolver = deno_resolver::cjs::IsCjsResolver<CliSys>;
pub type CliSloppyImportsResolver = pub type CliSloppyImportsResolver =
SloppyImportsResolver<SloppyImportsCachedFs>; SloppyImportsResolver<SloppyImportsCachedFs>;
pub type CliDenoResolver = deno_resolver::DenoResolver< pub type CliDenoResolver = deno_resolver::DenoResolver<
RealIsBuiltInNodeModuleChecker, RealIsBuiltInNodeModuleChecker,
SloppyImportsCachedFs, SloppyImportsCachedFs,
FsSysTraitsAdapter, CliSys,
>;
pub type CliNpmReqResolver = deno_resolver::npm::NpmReqResolver<
RealIsBuiltInNodeModuleChecker,
FsSysTraitsAdapter,
>; >;
pub type CliNpmReqResolver =
deno_resolver::npm::NpmReqResolver<RealIsBuiltInNodeModuleChecker, CliSys>;
pub struct ModuleCodeStringSource { pub struct ModuleCodeStringSource {
pub code: ModuleSourceCode, pub code: ModuleSourceCode,
@ -397,7 +395,7 @@ impl<'a> deno_graph::source::NpmResolver for WorkerCliNpmGraphResolver<'a> {
#[derive(Debug)] #[derive(Debug)]
pub struct SloppyImportsCachedFs { pub struct SloppyImportsCachedFs {
sys: FsSysTraitsAdapter, sys: CliSys,
cache: Option< cache: Option<
DashMap< DashMap<
PathBuf, PathBuf,
@ -407,14 +405,14 @@ pub struct SloppyImportsCachedFs {
} }
impl SloppyImportsCachedFs { impl SloppyImportsCachedFs {
pub fn new(sys: FsSysTraitsAdapter) -> Self { pub fn new(sys: CliSys) -> Self {
Self { Self {
sys, sys,
cache: Some(Default::default()), cache: Some(Default::default()),
} }
} }
pub fn new_without_stat_cache(fs: FsSysTraitsAdapter) -> Self { pub fn new_without_stat_cache(fs: CliSys) -> Self {
Self { Self {
sys: fs, sys: fs,
cache: None, cache: None,

View file

@ -259,7 +259,6 @@ pub fn is_standalone_binary(exe_path: &Path) -> bool {
} }
pub struct StandaloneData { pub struct StandaloneData {
pub fs: Arc<dyn deno_fs::FileSystem>,
pub metadata: Metadata, pub metadata: Metadata,
pub modules: StandaloneModules, pub modules: StandaloneModules,
pub npm_snapshot: Option<ValidSerializedNpmResolutionSnapshot>, pub npm_snapshot: Option<ValidSerializedNpmResolutionSnapshot>,
@ -382,10 +381,7 @@ pub fn extract_standalone(
}; };
Arc::new(FileBackedVfs::new(Cow::Borrowed(vfs_files_data), fs_root)) Arc::new(FileBackedVfs::new(Cow::Borrowed(vfs_files_data), fs_root))
}; };
let fs: Arc<dyn deno_fs::FileSystem> =
Arc::new(DenoCompileFileSystem::new(vfs.clone()));
Ok(Some(StandaloneData { Ok(Some(StandaloneData {
fs,
metadata, metadata,
modules: StandaloneModules { modules: StandaloneModules {
remote_modules, remote_modules,

View file

@ -18,7 +18,6 @@ use deno_core::unsync::sync::AtomicFlag;
use deno_path_util::get_atomic_path; use deno_path_util::get_atomic_path;
use deno_runtime::code_cache::CodeCache; use deno_runtime::code_cache::CodeCache;
use deno_runtime::code_cache::CodeCacheType; use deno_runtime::code_cache::CodeCacheType;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use crate::cache::FastInsecureHasher; use crate::cache::FastInsecureHasher;
use crate::worker::CliCodeCache; use crate::worker::CliCodeCache;
@ -191,7 +190,7 @@ impl FirstRunCodeCacheStrategy {
) { ) {
let count = cache_data.len(); let count = cache_data.len();
let temp_file = let temp_file =
get_atomic_path(&FsSysTraitsAdapter::new_real(), &self.file_path); get_atomic_path(&sys_traits::impls::RealSys, &self.file_path);
match serialize(&temp_file, self.cache_key, cache_data) { match serialize(&temp_file, self.cache_key, cache_data) {
Ok(()) => { Ok(()) => {
if let Err(err) = std::fs::rename(&temp_file, &self.file_path) { if let Err(err) = std::fs::rename(&temp_file, &self.file_path) {

View file

@ -1,23 +1,34 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use std::borrow::Cow;
use std::io::ErrorKind;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration;
use std::time::SystemTime;
use deno_runtime::deno_fs::AccessCheckCb; use deno_runtime::deno_fs::AccessCheckCb;
use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_fs::FileSystem;
use deno_runtime::deno_fs::FsDirEntry; use deno_runtime::deno_fs::FsDirEntry;
use deno_runtime::deno_fs::FsFileType; use deno_runtime::deno_fs::FsFileType;
use deno_runtime::deno_fs::FsStatSlim;
use deno_runtime::deno_fs::OpenOptions; use deno_runtime::deno_fs::OpenOptions;
use deno_runtime::deno_fs::RealFs; use deno_runtime::deno_fs::RealFs;
use deno_runtime::deno_io::fs::File; use deno_runtime::deno_io::fs::File;
use deno_runtime::deno_io::fs::FsError; use deno_runtime::deno_io::fs::FsError;
use deno_runtime::deno_io::fs::FsResult; use deno_runtime::deno_io::fs::FsResult;
use deno_runtime::deno_io::fs::FsStat; use deno_runtime::deno_io::fs::FsStat;
use sys_traits::boxed::BoxedFsDirEntry;
use sys_traits::boxed::BoxedFsMetadataValue;
use sys_traits::boxed::FsMetadataBoxed;
use sys_traits::boxed::FsReadDirBoxed;
use sys_traits::FsMetadata;
use super::virtual_fs::FileBackedVfs; use super::virtual_fs::FileBackedVfs;
use super::virtual_fs::FileBackedVfsDirEntry;
use super::virtual_fs::FileBackedVfsFile;
use super::virtual_fs::FileBackedVfsMetadata;
use super::virtual_fs::VfsFileSubDataKind; use super::virtual_fs::VfsFileSubDataKind;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -83,7 +94,7 @@ impl FileSystem for DenoCompileFileSystem {
access_check: Option<AccessCheckCb>, access_check: Option<AccessCheckCb>,
) -> FsResult<Rc<dyn File>> { ) -> FsResult<Rc<dyn File>> {
if self.0.is_path_within(path) { if self.0.is_path_within(path) {
Ok(self.0.open_file(path)?) Ok(Rc::new(self.0.open_file(path)?))
} else { } else {
RealFs.open_sync(path, options, access_check) RealFs.open_sync(path, options, access_check)
} }
@ -95,7 +106,7 @@ impl FileSystem for DenoCompileFileSystem {
access_check: Option<AccessCheckCb<'a>>, access_check: Option<AccessCheckCb<'a>>,
) -> FsResult<Rc<dyn File>> { ) -> FsResult<Rc<dyn File>> {
if self.0.is_path_within(&path) { if self.0.is_path_within(&path) {
Ok(self.0.open_file(&path)?) Ok(Rc::new(self.0.open_file(&path)?))
} else { } else {
RealFs.open_async(path, options, access_check).await RealFs.open_async(path, options, access_check).await
} }
@ -215,14 +226,14 @@ impl FileSystem for DenoCompileFileSystem {
fn stat_sync(&self, path: &Path) -> FsResult<FsStat> { fn stat_sync(&self, path: &Path) -> FsResult<FsStat> {
if self.0.is_path_within(path) { if self.0.is_path_within(path) {
Ok(self.0.stat(path)?) Ok(self.0.stat(path)?.as_fs_stat())
} else { } else {
RealFs.stat_sync(path) RealFs.stat_sync(path)
} }
} }
async fn stat_async(&self, path: PathBuf) -> FsResult<FsStat> { async fn stat_async(&self, path: PathBuf) -> FsResult<FsStat> {
if self.0.is_path_within(&path) { if self.0.is_path_within(&path) {
Ok(self.0.stat(&path)?) Ok(self.0.stat(&path)?.as_fs_stat())
} else { } else {
RealFs.stat_async(path).await RealFs.stat_async(path).await
} }
@ -230,14 +241,14 @@ impl FileSystem for DenoCompileFileSystem {
fn lstat_sync(&self, path: &Path) -> FsResult<FsStat> { fn lstat_sync(&self, path: &Path) -> FsResult<FsStat> {
if self.0.is_path_within(path) { if self.0.is_path_within(path) {
Ok(self.0.lstat(path)?) Ok(self.0.lstat(path)?.as_fs_stat())
} else { } else {
RealFs.lstat_sync(path) RealFs.lstat_sync(path)
} }
} }
async fn lstat_async(&self, path: PathBuf) -> FsResult<FsStat> { async fn lstat_async(&self, path: PathBuf) -> FsResult<FsStat> {
if self.0.is_path_within(&path) { if self.0.is_path_within(&path) {
Ok(self.0.lstat(&path)?) Ok(self.0.lstat(&path)?.as_fs_stat())
} else { } else {
RealFs.lstat_async(path).await RealFs.lstat_async(path).await
} }
@ -398,3 +409,428 @@ impl FileSystem for DenoCompileFileSystem {
.await .await
} }
} }
impl sys_traits::BaseFsHardLink for DenoCompileFileSystem {
#[inline]
fn base_fs_hard_link(&self, src: &Path, dst: &Path) -> std::io::Result<()> {
self.link_sync(src, dst).map_err(|err| err.into_io_error())
}
}
impl sys_traits::BaseFsRead for DenoCompileFileSystem {
#[inline]
fn base_fs_read(&self, path: &Path) -> std::io::Result<Cow<'static, [u8]>> {
self
.read_file_sync(path, None)
.map_err(|err| err.into_io_error())
}
}
impl sys_traits::FsMetadataValue for FileBackedVfsMetadata {
fn file_type(&self) -> sys_traits::FileType {
self.file_type
}
fn len(&self) -> u64 {
self.len
}
fn accessed(&self) -> std::io::Result<SystemTime> {
Err(not_supported("accessed time"))
}
fn created(&self) -> std::io::Result<SystemTime> {
Err(not_supported("created time"))
}
fn changed(&self) -> std::io::Result<SystemTime> {
Err(not_supported("changed time"))
}
fn modified(&self) -> std::io::Result<SystemTime> {
Err(not_supported("modified time"))
}
fn dev(&self) -> std::io::Result<u64> {
Ok(0)
}
fn ino(&self) -> std::io::Result<u64> {
Ok(0)
}
fn mode(&self) -> std::io::Result<u32> {
Ok(0)
}
fn nlink(&self) -> std::io::Result<u64> {
Ok(0)
}
fn uid(&self) -> std::io::Result<u32> {
Ok(0)
}
fn gid(&self) -> std::io::Result<u32> {
Ok(0)
}
fn rdev(&self) -> std::io::Result<u64> {
Ok(0)
}
fn blksize(&self) -> std::io::Result<u64> {
Ok(0)
}
fn blocks(&self) -> std::io::Result<u64> {
Ok(0)
}
fn is_block_device(&self) -> std::io::Result<bool> {
Ok(false)
}
fn is_char_device(&self) -> std::io::Result<bool> {
Ok(false)
}
fn is_fifo(&self) -> std::io::Result<bool> {
Ok(false)
}
fn is_socket(&self) -> std::io::Result<bool> {
Ok(false)
}
fn file_attributes(&self) -> std::io::Result<u32> {
Ok(0)
}
}
fn not_supported(name: &str) -> std::io::Error {
std::io::Error::new(
ErrorKind::Unsupported,
format!(
"{} is not supported for an embedded deno compile file",
name
),
)
}
impl sys_traits::FsDirEntry for FileBackedVfsDirEntry {
type Metadata = BoxedFsMetadataValue;
fn file_name(&self) -> Cow<std::ffi::OsStr> {
Cow::Borrowed(self.metadata.name.as_ref())
}
fn file_type(&self) -> std::io::Result<sys_traits::FileType> {
Ok(self.metadata.file_type)
}
fn metadata(&self) -> std::io::Result<Self::Metadata> {
Ok(BoxedFsMetadataValue(Box::new(self.metadata.clone())))
}
fn path(&self) -> Cow<Path> {
Cow::Owned(self.parent_path.join(&self.metadata.name))
}
}
impl sys_traits::BaseFsReadDir for DenoCompileFileSystem {
type ReadDirEntry = BoxedFsDirEntry;
fn base_fs_read_dir(
&self,
path: &Path,
) -> std::io::Result<
Box<dyn Iterator<Item = std::io::Result<Self::ReadDirEntry>> + '_>,
> {
if self.0.is_path_within(path) {
let entries = self.0.read_dir_with_metadata(path)?;
Ok(Box::new(
entries.map(|entry| Ok(BoxedFsDirEntry::new(entry))),
))
} else {
#[allow(clippy::disallowed_types)] // ok because we're implementing the fs
sys_traits::impls::RealSys.fs_read_dir_boxed(path)
}
}
}
impl sys_traits::BaseFsCanonicalize for DenoCompileFileSystem {
#[inline]
fn base_fs_canonicalize(&self, path: &Path) -> std::io::Result<PathBuf> {
self.realpath_sync(path).map_err(|err| err.into_io_error())
}
}
impl sys_traits::BaseFsMetadata for DenoCompileFileSystem {
type Metadata = BoxedFsMetadataValue;
#[inline]
fn base_fs_metadata(&self, path: &Path) -> std::io::Result<Self::Metadata> {
if self.0.is_path_within(path) {
Ok(BoxedFsMetadataValue::new(self.0.stat(path)?))
} else {
#[allow(clippy::disallowed_types)] // ok because we're implementing the fs
sys_traits::impls::RealSys.fs_metadata_boxed(path)
}
}
#[inline]
fn base_fs_symlink_metadata(
&self,
path: &Path,
) -> std::io::Result<Self::Metadata> {
if self.0.is_path_within(path) {
Ok(BoxedFsMetadataValue::new(self.0.lstat(path)?))
} else {
#[allow(clippy::disallowed_types)] // ok because we're implementing the fs
sys_traits::impls::RealSys.fs_symlink_metadata_boxed(path)
}
}
}
impl sys_traits::BaseFsCreateDir for DenoCompileFileSystem {
#[inline]
fn base_fs_create_dir(
&self,
path: &Path,
options: &sys_traits::CreateDirOptions,
) -> std::io::Result<()> {
self
.mkdir_sync(path, options.recursive, options.mode)
.map_err(|err| err.into_io_error())
}
}
impl sys_traits::BaseFsRemoveFile for DenoCompileFileSystem {
#[inline]
fn base_fs_remove_file(&self, path: &Path) -> std::io::Result<()> {
self
.remove_sync(path, false)
.map_err(|err| err.into_io_error())
}
}
impl sys_traits::BaseFsRename for DenoCompileFileSystem {
#[inline]
fn base_fs_rename(&self, from: &Path, to: &Path) -> std::io::Result<()> {
self
.rename_sync(from, to)
.map_err(|err| err.into_io_error())
}
}
pub enum FsFileAdapter {
Real(sys_traits::impls::RealFsFile),
Vfs(FileBackedVfsFile),
}
impl sys_traits::FsFile for FsFileAdapter {}
impl sys_traits::FsFileAsRaw for FsFileAdapter {
#[cfg(windows)]
fn fs_file_as_raw_handle(&self) -> Option<std::os::windows::io::RawHandle> {
match self {
Self::Real(file) => file.fs_file_as_raw_handle(),
Self::Vfs(_) => None,
}
}
#[cfg(unix)]
fn fs_file_as_raw_fd(&self) -> Option<std::os::fd::RawFd> {
match self {
Self::Real(file) => file.fs_file_as_raw_fd(),
Self::Vfs(_) => None,
}
}
}
impl sys_traits::FsFileSyncData for FsFileAdapter {
fn fs_file_sync_data(&mut self) -> std::io::Result<()> {
match self {
Self::Real(file) => file.fs_file_sync_data(),
Self::Vfs(_) => Ok(()),
}
}
}
impl sys_traits::FsFileSyncAll for FsFileAdapter {
fn fs_file_sync_all(&mut self) -> std::io::Result<()> {
match self {
Self::Real(file) => file.fs_file_sync_all(),
Self::Vfs(_) => Ok(()),
}
}
}
impl sys_traits::FsFileSetPermissions for FsFileAdapter {
#[inline]
fn fs_file_set_permissions(&mut self, mode: u32) -> std::io::Result<()> {
match self {
Self::Real(file) => file.fs_file_set_permissions(mode),
Self::Vfs(_) => Ok(()),
}
}
}
impl std::io::Read for FsFileAdapter {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
match self {
Self::Real(file) => file.read(buf),
Self::Vfs(file) => file.read_to_buf(buf),
}
}
}
impl std::io::Seek for FsFileAdapter {
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
match self {
Self::Real(file) => file.seek(pos),
Self::Vfs(file) => file.seek(pos),
}
}
}
impl std::io::Write for FsFileAdapter {
#[inline]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
match self {
Self::Real(file) => file.write(buf),
Self::Vfs(_) => Err(not_supported("writing files")),
}
}
#[inline]
fn flush(&mut self) -> std::io::Result<()> {
match self {
Self::Real(file) => file.flush(),
Self::Vfs(_) => Err(not_supported("writing files")),
}
}
}
impl sys_traits::FsFileSetLen for FsFileAdapter {
#[inline]
fn fs_file_set_len(&mut self, len: u64) -> std::io::Result<()> {
match self {
Self::Real(file) => file.fs_file_set_len(len),
Self::Vfs(_) => Err(not_supported("setting file length")),
}
}
}
impl sys_traits::FsFileSetTimes for FsFileAdapter {
fn fs_file_set_times(
&mut self,
times: sys_traits::FsFileTimes,
) -> std::io::Result<()> {
match self {
Self::Real(file) => file.fs_file_set_times(times),
Self::Vfs(_) => Err(not_supported("setting file times")),
}
}
}
impl sys_traits::FsFileLock for FsFileAdapter {
fn fs_file_lock(
&mut self,
mode: sys_traits::FsFileLockMode,
) -> std::io::Result<()> {
match self {
Self::Real(file) => file.fs_file_lock(mode),
Self::Vfs(_) => Err(not_supported("locking files")),
}
}
fn fs_file_try_lock(
&mut self,
mode: sys_traits::FsFileLockMode,
) -> std::io::Result<()> {
match self {
Self::Real(file) => file.fs_file_try_lock(mode),
Self::Vfs(_) => Err(not_supported("locking files")),
}
}
fn fs_file_unlock(&mut self) -> std::io::Result<()> {
match self {
Self::Real(file) => file.fs_file_unlock(),
Self::Vfs(_) => Err(not_supported("unlocking files")),
}
}
}
impl sys_traits::FsFileIsTerminal for FsFileAdapter {
#[inline]
fn fs_file_is_terminal(&self) -> bool {
match self {
Self::Real(file) => file.fs_file_is_terminal(),
Self::Vfs(_) => false,
}
}
}
impl sys_traits::BaseFsOpen for DenoCompileFileSystem {
type File = FsFileAdapter;
fn base_fs_open(
&self,
path: &Path,
options: &sys_traits::OpenOptions,
) -> std::io::Result<Self::File> {
if self.0.is_path_within(path) {
Ok(FsFileAdapter::Vfs(self.0.open_file(path)?))
} else {
#[allow(clippy::disallowed_types)] // ok because we're implementing the fs
Ok(FsFileAdapter::Real(
sys_traits::impls::RealSys.base_fs_open(path, options)?,
))
}
}
}
impl sys_traits::SystemRandom for DenoCompileFileSystem {
#[inline]
fn sys_random(&self, buf: &mut [u8]) -> std::io::Result<()> {
#[allow(clippy::disallowed_types)] // ok because we're implementing the fs
sys_traits::impls::RealSys.sys_random(buf)
}
}
impl sys_traits::SystemTimeNow for DenoCompileFileSystem {
#[inline]
fn sys_time_now(&self) -> SystemTime {
#[allow(clippy::disallowed_types)] // ok because we're implementing the fs
sys_traits::impls::RealSys.sys_time_now()
}
}
impl sys_traits::ThreadSleep for DenoCompileFileSystem {
#[inline]
fn thread_sleep(&self, dur: Duration) {
#[allow(clippy::disallowed_types)] // ok because we're implementing the fs
sys_traits::impls::RealSys.thread_sleep(dur)
}
}
impl sys_traits::EnvCurrentDir for DenoCompileFileSystem {
fn env_current_dir(&self) -> std::io::Result<PathBuf> {
#[allow(clippy::disallowed_types)] // ok because we're implementing the fs
sys_traits::impls::RealSys.env_current_dir()
}
}
impl sys_traits::BaseEnvVar for DenoCompileFileSystem {
fn base_env_var_os(
&self,
key: &std::ffi::OsStr,
) -> Option<std::ffi::OsString> {
#[allow(clippy::disallowed_types)] // ok because we're implementing the fs
sys_traits::impls::RealSys.base_env_var_os(key)
}
}

View file

@ -36,11 +36,10 @@ use deno_package_json::PackageJsonDepValue;
use deno_resolver::cjs::IsCjsResolutionMode; use deno_resolver::cjs::IsCjsResolutionMode;
use deno_resolver::npm::NpmReqResolverOptions; use deno_resolver::npm::NpmReqResolverOptions;
use deno_runtime::deno_fs; use deno_runtime::deno_fs;
use deno_runtime::deno_fs::FsSysTraitsAdapter; use deno_runtime::deno_fs::FileSystem;
use deno_runtime::deno_node::create_host_defined_options; use deno_runtime::deno_node::create_host_defined_options;
use deno_runtime::deno_node::NodeRequireLoader; use deno_runtime::deno_node::NodeRequireLoader;
use deno_runtime::deno_node::NodeResolver; use deno_runtime::deno_node::NodeResolver;
use deno_runtime::deno_node::PackageJsonResolver;
use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker; use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker;
use deno_runtime::deno_permissions::Permissions; use deno_runtime::deno_permissions::Permissions;
use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_permissions::PermissionsContainer;
@ -77,6 +76,8 @@ use crate::cache::NodeAnalysisCache;
use crate::http_util::HttpClientProvider; use crate::http_util::HttpClientProvider;
use crate::node::CliCjsCodeAnalyzer; use crate::node::CliCjsCodeAnalyzer;
use crate::node::CliNodeCodeTranslator; use crate::node::CliNodeCodeTranslator;
use crate::node::CliNodeResolver;
use crate::node::CliPackageJsonResolver;
use crate::npm::create_cli_npm_resolver; use crate::npm::create_cli_npm_resolver;
use crate::npm::create_in_npm_pkg_checker; use crate::npm::create_in_npm_pkg_checker;
use crate::npm::CliByonmNpmResolverCreateOptions; use crate::npm::CliByonmNpmResolverCreateOptions;
@ -89,6 +90,7 @@ use crate::npm::CreateInNpmPkgCheckerOptions;
use crate::resolver::CjsTracker; use crate::resolver::CjsTracker;
use crate::resolver::CliNpmReqResolver; use crate::resolver::CliNpmReqResolver;
use crate::resolver::NpmModuleLoader; use crate::resolver::NpmModuleLoader;
use crate::sys::CliSys;
use crate::util::progress_bar::ProgressBar; use crate::util::progress_bar::ProgressBar;
use crate::util::progress_bar::ProgressBarStyle; use crate::util::progress_bar::ProgressBarStyle;
use crate::util::text_encoding::from_utf8_lossy_cow; use crate::util::text_encoding::from_utf8_lossy_cow;
@ -105,12 +107,12 @@ mod file_system;
mod serialization; mod serialization;
mod virtual_fs; mod virtual_fs;
pub use self::file_system::DenoCompileFileSystem;
pub use binary::extract_standalone; pub use binary::extract_standalone;
pub use binary::is_standalone_binary; pub use binary::is_standalone_binary;
pub use binary::DenoCompileBinaryWriter; pub use binary::DenoCompileBinaryWriter;
use self::binary::Metadata; use self::binary::Metadata;
use self::file_system::DenoCompileFileSystem;
struct SharedModuleLoaderState { struct SharedModuleLoaderState {
cjs_tracker: Arc<CjsTracker>, cjs_tracker: Arc<CjsTracker>,
@ -118,7 +120,7 @@ struct SharedModuleLoaderState {
fs: Arc<dyn deno_fs::FileSystem>, fs: Arc<dyn deno_fs::FileSystem>,
modules: StandaloneModules, modules: StandaloneModules,
node_code_translator: Arc<CliNodeCodeTranslator>, node_code_translator: Arc<CliNodeCodeTranslator>,
node_resolver: Arc<NodeResolver>, node_resolver: Arc<CliNodeResolver>,
npm_module_loader: Arc<NpmModuleLoader>, npm_module_loader: Arc<NpmModuleLoader>,
npm_req_resolver: Arc<CliNpmReqResolver>, npm_req_resolver: Arc<CliNpmReqResolver>,
npm_resolver: Arc<dyn CliNpmResolver>, npm_resolver: Arc<dyn CliNpmResolver>,
@ -627,9 +629,12 @@ impl RootCertStoreProvider for StandaloneRootCertStoreProvider {
} }
} }
pub async fn run(data: StandaloneData) -> Result<i32, AnyError> { pub async fn run(
fs: Arc<dyn FileSystem>,
sys: CliSys,
data: StandaloneData,
) -> Result<i32, AnyError> {
let StandaloneData { let StandaloneData {
fs,
metadata, metadata,
modules, modules,
npm_snapshot, npm_snapshot,
@ -637,7 +642,7 @@ pub async fn run(data: StandaloneData) -> Result<i32, AnyError> {
source_maps, source_maps,
vfs, vfs,
} = data; } = data;
let deno_dir_provider = Arc::new(DenoDirProvider::new(None)); let deno_dir_provider = Arc::new(DenoDirProvider::new(sys.clone(), None));
let root_cert_store_provider = Arc::new(StandaloneRootCertStoreProvider { let root_cert_store_provider = Arc::new(StandaloneRootCertStoreProvider {
ca_stores: metadata.ca_stores, ca_stores: metadata.ca_stores,
ca_data: metadata.ca_data.map(CaData::Bytes), ca_data: metadata.ca_data.map(CaData::Bytes),
@ -655,8 +660,7 @@ pub async fn run(data: StandaloneData) -> Result<i32, AnyError> {
let main_module = root_dir_url.join(&metadata.entrypoint_key).unwrap(); let main_module = root_dir_url.join(&metadata.entrypoint_key).unwrap();
let npm_global_cache_dir = root_path.join(".deno_compile_node_modules"); let npm_global_cache_dir = root_path.join(".deno_compile_node_modules");
let cache_setting = CacheSetting::Only; let cache_setting = CacheSetting::Only;
let sys = FsSysTraitsAdapter(fs.clone()); let pkg_json_resolver = Arc::new(CliPackageJsonResolver::new(sys.clone()));
let pkg_json_resolver = Arc::new(PackageJsonResolver::new(sys.clone()));
let (in_npm_pkg_checker, npm_resolver) = match metadata.node_modules { let (in_npm_pkg_checker, npm_resolver) = match metadata.node_modules {
Some(binary::NodeModules::Managed { node_modules_dir }) => { Some(binary::NodeModules::Managed { node_modules_dir }) => {
// create an npmrc that uses the fake npm_registry_url to resolve packages // create an npmrc that uses the fake npm_registry_url to resolve packages
@ -807,7 +811,7 @@ pub async fn run(data: StandaloneData) -> Result<i32, AnyError> {
node_resolver.clone(), node_resolver.clone(),
npm_resolver.clone().into_npm_pkg_folder_resolver(), npm_resolver.clone().into_npm_pkg_folder_resolver(),
pkg_json_resolver.clone(), pkg_json_resolver.clone(),
sys, sys.clone(),
)); ));
let workspace_resolver = { let workspace_resolver = {
let import_map = match metadata.workspace_resolver.import_map { let import_map = match metadata.workspace_resolver.import_map {
@ -910,7 +914,7 @@ pub async fn run(data: StandaloneData) -> Result<i32, AnyError> {
} }
let desc_parser = let desc_parser =
Arc::new(RuntimePermissionDescriptorParser::new(fs.clone())); Arc::new(RuntimePermissionDescriptorParser::new(sys.clone()));
let permissions = let permissions =
Permissions::from_options(desc_parser.as_ref(), &permissions)?; Permissions::from_options(desc_parser.as_ref(), &permissions)?;
PermissionsContainer::new(desc_parser, permissions) PermissionsContainer::new(desc_parser, permissions)
@ -940,6 +944,7 @@ pub async fn run(data: StandaloneData) -> Result<i32, AnyError> {
root_cert_store_provider, root_cert_store_provider,
permissions, permissions,
StorageKeyResolver::empty(), StorageKeyResolver::empty(),
sys,
crate::args::DenoSubcommand::Run(Default::default()), crate::args::DenoSubcommand::Run(Default::default()),
CliMainWorkerOptions { CliMainWorkerOptions {
argv: metadata.argv, argv: metadata.argv,

View file

@ -51,8 +51,16 @@ pub enum WindowsSystemRootablePath {
impl WindowsSystemRootablePath { impl WindowsSystemRootablePath {
pub fn join(&self, name_component: &str) -> PathBuf { pub fn join(&self, name_component: &str) -> PathBuf {
// this method doesn't handle multiple components // this method doesn't handle multiple components
debug_assert!(!name_component.contains('\\')); debug_assert!(
debug_assert!(!name_component.contains('/')); !name_component.contains('\\'),
"Invalid component: {}",
name_component
);
debug_assert!(
!name_component.contains('/'),
"Invalid component: {}",
name_component
);
match self { match self {
WindowsSystemRootablePath::WindowSystemRoot => { WindowsSystemRootablePath::WindowSystemRoot => {
@ -847,78 +855,28 @@ enum VfsEntryRef<'a> {
Symlink(&'a VirtualSymlink), Symlink(&'a VirtualSymlink),
} }
impl<'a> VfsEntryRef<'a> { impl VfsEntryRef<'_> {
pub fn as_fs_stat(&self) -> FsStat { pub fn as_metadata(&self) -> FileBackedVfsMetadata {
FileBackedVfsMetadata {
file_type: match self {
Self::Dir(_) => sys_traits::FileType::Dir,
Self::File(_) => sys_traits::FileType::File,
Self::Symlink(_) => sys_traits::FileType::Symlink,
},
name: self.name().to_string(),
len: match self {
Self::Dir(_) => 0,
Self::File(file) => file.offset.len,
Self::Symlink(_) => 0,
},
}
}
pub fn name(&self) -> &str {
match self { match self {
VfsEntryRef::Dir(_) => FsStat { Self::Dir(dir) => &dir.name,
is_directory: true, Self::File(file) => &file.name,
is_file: false, Self::Symlink(symlink) => &symlink.name,
is_symlink: false,
atime: None,
birthtime: None,
mtime: None,
ctime: None,
blksize: 0,
size: 0,
dev: 0,
ino: 0,
mode: 0,
nlink: 0,
uid: 0,
gid: 0,
rdev: 0,
blocks: 0,
is_block_device: false,
is_char_device: false,
is_fifo: false,
is_socket: false,
},
VfsEntryRef::File(file) => FsStat {
is_directory: false,
is_file: true,
is_symlink: false,
atime: None,
birthtime: None,
mtime: None,
ctime: None,
blksize: 0,
size: file.offset.len,
dev: 0,
ino: 0,
mode: 0,
nlink: 0,
uid: 0,
gid: 0,
rdev: 0,
blocks: 0,
is_block_device: false,
is_char_device: false,
is_fifo: false,
is_socket: false,
},
VfsEntryRef::Symlink(_) => FsStat {
is_directory: false,
is_file: false,
is_symlink: true,
atime: None,
birthtime: None,
mtime: None,
ctime: None,
blksize: 0,
size: 0,
dev: 0,
ino: 0,
mode: 0,
nlink: 0,
uid: 0,
gid: 0,
rdev: 0,
blocks: 0,
is_block_device: false,
is_char_device: false,
is_fifo: false,
is_socket: false,
},
} }
} }
} }
@ -934,9 +892,9 @@ pub enum VfsEntry {
impl VfsEntry { impl VfsEntry {
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
match self { match self {
VfsEntry::Dir(dir) => &dir.name, Self::Dir(dir) => &dir.name,
VfsEntry::File(file) => &file.name, Self::File(file) => &file.name,
VfsEntry::Symlink(symlink) => &symlink.name, Self::Symlink(symlink) => &symlink.name,
} }
} }
@ -1180,14 +1138,14 @@ impl VfsRoot {
} }
} }
struct FileBackedVfsFile { pub struct FileBackedVfsFile {
file: VirtualFile, file: VirtualFile,
pos: RefCell<u64>, pos: RefCell<u64>,
vfs: Arc<FileBackedVfs>, vfs: Arc<FileBackedVfs>,
} }
impl FileBackedVfsFile { impl FileBackedVfsFile {
fn seek(&self, pos: SeekFrom) -> FsResult<u64> { pub fn seek(&self, pos: SeekFrom) -> std::io::Result<u64> {
match pos { match pos {
SeekFrom::Start(pos) => { SeekFrom::Start(pos) => {
*self.pos.borrow_mut() = pos; *self.pos.borrow_mut() = pos;
@ -1196,10 +1154,10 @@ impl FileBackedVfsFile {
SeekFrom::End(offset) => { SeekFrom::End(offset) => {
if offset < 0 && -offset as u64 > self.file.offset.len { if offset < 0 && -offset as u64 > self.file.offset.len {
let msg = "An attempt was made to move the file pointer before the beginning of the file."; let msg = "An attempt was made to move the file pointer before the beginning of the file.";
Err( Err(std::io::Error::new(
std::io::Error::new(std::io::ErrorKind::PermissionDenied, msg) std::io::ErrorKind::PermissionDenied,
.into(), msg,
) ))
} else { } else {
let mut current_pos = self.pos.borrow_mut(); let mut current_pos = self.pos.borrow_mut();
*current_pos = if offset >= 0 { *current_pos = if offset >= 0 {
@ -1215,7 +1173,7 @@ impl FileBackedVfsFile {
if offset >= 0 { if offset >= 0 {
*current_pos += offset as u64; *current_pos += offset as u64;
} else if -offset as u64 > *current_pos { } else if -offset as u64 > *current_pos {
return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "An attempt was made to move the file pointer before the beginning of the file.").into()); return Err(std::io::Error::new(std::io::ErrorKind::PermissionDenied, "An attempt was made to move the file pointer before the beginning of the file."));
} else { } else {
*current_pos -= -offset as u64; *current_pos -= -offset as u64;
} }
@ -1224,7 +1182,7 @@ impl FileBackedVfsFile {
} }
} }
fn read_to_buf(&self, buf: &mut [u8]) -> FsResult<usize> { pub fn read_to_buf(&self, buf: &mut [u8]) -> std::io::Result<usize> {
let read_pos = { let read_pos = {
let mut pos = self.pos.borrow_mut(); let mut pos = self.pos.borrow_mut();
let read_pos = *pos; let read_pos = *pos;
@ -1232,10 +1190,7 @@ impl FileBackedVfsFile {
*pos = std::cmp::min(self.file.offset.len, *pos + buf.len() as u64); *pos = std::cmp::min(self.file.offset.len, *pos + buf.len() as u64);
read_pos read_pos
}; };
self self.vfs.read_file(&self.file, read_pos, buf)
.vfs
.read_file(&self.file, read_pos, buf)
.map_err(|err| err.into())
} }
fn read_to_end(&self) -> FsResult<Cow<'static, [u8]>> { fn read_to_end(&self) -> FsResult<Cow<'static, [u8]>> {
@ -1270,7 +1225,7 @@ impl FileBackedVfsFile {
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
impl deno_io::fs::File for FileBackedVfsFile { impl deno_io::fs::File for FileBackedVfsFile {
fn read_sync(self: Rc<Self>, buf: &mut [u8]) -> FsResult<usize> { fn read_sync(self: Rc<Self>, buf: &mut [u8]) -> FsResult<usize> {
self.read_to_buf(buf) self.read_to_buf(buf).map_err(Into::into)
} }
async fn read_byob( async fn read_byob(
self: Rc<Self>, self: Rc<Self>,
@ -1314,10 +1269,10 @@ impl deno_io::fs::File for FileBackedVfsFile {
} }
fn seek_sync(self: Rc<Self>, pos: SeekFrom) -> FsResult<u64> { fn seek_sync(self: Rc<Self>, pos: SeekFrom) -> FsResult<u64> {
self.seek(pos) self.seek(pos).map_err(|err| err.into())
} }
async fn seek_async(self: Rc<Self>, pos: SeekFrom) -> FsResult<u64> { async fn seek_async(self: Rc<Self>, pos: SeekFrom) -> FsResult<u64> {
self.seek(pos) self.seek(pos).map_err(|err| err.into())
} }
fn datasync_sync(self: Rc<Self>) -> FsResult<()> { fn datasync_sync(self: Rc<Self>) -> FsResult<()> {
@ -1393,6 +1348,47 @@ impl deno_io::fs::File for FileBackedVfsFile {
} }
} }
#[derive(Debug, Clone)]
pub struct FileBackedVfsDirEntry {
pub parent_path: PathBuf,
pub metadata: FileBackedVfsMetadata,
}
#[derive(Debug, Clone)]
pub struct FileBackedVfsMetadata {
pub name: String,
pub file_type: sys_traits::FileType,
pub len: u64,
}
impl FileBackedVfsMetadata {
pub fn as_fs_stat(&self) -> FsStat {
FsStat {
is_directory: self.file_type == sys_traits::FileType::Dir,
is_file: self.file_type == sys_traits::FileType::File,
is_symlink: self.file_type == sys_traits::FileType::Symlink,
atime: None,
birthtime: None,
mtime: None,
ctime: None,
blksize: 0,
size: self.len,
dev: 0,
ino: 0,
mode: 0,
nlink: 0,
uid: 0,
gid: 0,
rdev: 0,
blocks: 0,
is_block_device: false,
is_char_device: false,
is_fifo: false,
is_socket: false,
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct FileBackedVfs { pub struct FileBackedVfs {
vfs_data: Cow<'static, [u8]>, vfs_data: Cow<'static, [u8]>,
@ -1418,13 +1414,13 @@ impl FileBackedVfs {
pub fn open_file( pub fn open_file(
self: &Arc<Self>, self: &Arc<Self>,
path: &Path, path: &Path,
) -> std::io::Result<Rc<dyn deno_io::fs::File>> { ) -> std::io::Result<FileBackedVfsFile> {
let file = self.file_entry(path)?; let file = self.file_entry(path)?;
Ok(Rc::new(FileBackedVfsFile { Ok(FileBackedVfsFile {
file: file.clone(), file: file.clone(),
vfs: self.clone(), vfs: self.clone(),
pos: Default::default(), pos: Default::default(),
})) })
} }
pub fn read_dir(&self, path: &Path) -> std::io::Result<Vec<FsDirEntry>> { pub fn read_dir(&self, path: &Path) -> std::io::Result<Vec<FsDirEntry>> {
@ -1443,6 +1439,18 @@ impl FileBackedVfs {
) )
} }
pub fn read_dir_with_metadata<'a>(
&'a self,
path: &Path,
) -> std::io::Result<impl Iterator<Item = FileBackedVfsDirEntry> + 'a> {
let dir = self.dir_entry(path)?;
let path = path.to_path_buf();
Ok(dir.entries.iter().map(move |entry| FileBackedVfsDirEntry {
parent_path: path.to_path_buf(),
metadata: entry.as_ref().as_metadata(),
}))
}
pub fn read_link(&self, path: &Path) -> std::io::Result<PathBuf> { pub fn read_link(&self, path: &Path) -> std::io::Result<PathBuf> {
let (_, entry) = self.fs_root.find_entry_no_follow(path)?; let (_, entry) = self.fs_root.find_entry_no_follow(path)?;
match entry { match entry {
@ -1456,14 +1464,14 @@ impl FileBackedVfs {
} }
} }
pub fn lstat(&self, path: &Path) -> std::io::Result<FsStat> { pub fn lstat(&self, path: &Path) -> std::io::Result<FileBackedVfsMetadata> {
let (_, entry) = self.fs_root.find_entry_no_follow(path)?; let (_, entry) = self.fs_root.find_entry_no_follow(path)?;
Ok(entry.as_fs_stat()) Ok(entry.as_metadata())
} }
pub fn stat(&self, path: &Path) -> std::io::Result<FsStat> { pub fn stat(&self, path: &Path) -> std::io::Result<FileBackedVfsMetadata> {
let (_, entry) = self.fs_root.find_entry(path)?; let (_, entry) = self.fs_root.find_entry(path)?;
Ok(entry.as_fs_stat()) Ok(entry.as_metadata())
} }
pub fn canonicalize(&self, path: &Path) -> std::io::Result<PathBuf> { pub fn canonicalize(&self, path: &Path) -> std::io::Result<PathBuf> {
@ -1556,6 +1564,7 @@ impl FileBackedVfs {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use console_static_text::ansi::strip_ansi_codes; use console_static_text::ansi::strip_ansi_codes;
use deno_io::fs::File;
use std::io::Write; use std::io::Write;
use test_util::assert_contains; use test_util::assert_contains;
use test_util::TempDir; use test_util::TempDir;
@ -1641,25 +1650,31 @@ mod test {
); );
// metadata // metadata
assert!( assert_eq!(
virtual_fs virtual_fs
.lstat(&dest_path.join("sub_dir").join("e.txt")) .lstat(&dest_path.join("sub_dir").join("e.txt"))
.unwrap() .unwrap()
.is_symlink .file_type,
sys_traits::FileType::Symlink,
); );
assert!( assert_eq!(
virtual_fs virtual_fs
.stat(&dest_path.join("sub_dir").join("e.txt")) .stat(&dest_path.join("sub_dir").join("e.txt"))
.unwrap() .unwrap()
.is_file .file_type,
sys_traits::FileType::File,
); );
assert!( assert_eq!(
virtual_fs virtual_fs
.stat(&dest_path.join("sub_dir")) .stat(&dest_path.join("sub_dir"))
.unwrap() .unwrap()
.is_directory, .file_type,
sys_traits::FileType::Dir,
);
assert_eq!(
virtual_fs.stat(&dest_path.join("e.txt")).unwrap().file_type,
sys_traits::FileType::File
); );
assert!(virtual_fs.stat(&dest_path.join("e.txt")).unwrap().is_file,);
} }
#[test] #[test]
@ -1696,11 +1711,12 @@ mod test {
read_file(&virtual_fs, &dest_path.join("sub_dir_link").join("c.txt")), read_file(&virtual_fs, &dest_path.join("sub_dir_link").join("c.txt")),
"c", "c",
); );
assert!( assert_eq!(
virtual_fs virtual_fs
.lstat(&dest_path.join("sub_dir_link")) .lstat(&dest_path.join("sub_dir_link"))
.unwrap() .unwrap()
.is_symlink .file_type,
sys_traits::FileType::Symlink,
); );
assert_eq!( assert_eq!(
@ -1772,37 +1788,35 @@ mod test {
let (dest_path, virtual_fs) = into_virtual_fs(builder, &temp_dir); let (dest_path, virtual_fs) = into_virtual_fs(builder, &temp_dir);
let virtual_fs = Arc::new(virtual_fs); let virtual_fs = Arc::new(virtual_fs);
let file = virtual_fs.open_file(&dest_path.join("a.txt")).unwrap(); let file = virtual_fs.open_file(&dest_path.join("a.txt")).unwrap();
file.clone().seek_sync(SeekFrom::Current(2)).unwrap(); file.seek(SeekFrom::Current(2)).unwrap();
let mut buf = vec![0; 2]; let mut buf = vec![0; 2];
file.clone().read_sync(&mut buf).unwrap(); file.read_to_buf(&mut buf).unwrap();
assert_eq!(buf, b"23"); assert_eq!(buf, b"23");
file.clone().read_sync(&mut buf).unwrap(); file.read_to_buf(&mut buf).unwrap();
assert_eq!(buf, b"45"); assert_eq!(buf, b"45");
file.clone().seek_sync(SeekFrom::Current(-4)).unwrap(); file.seek(SeekFrom::Current(-4)).unwrap();
file.clone().read_sync(&mut buf).unwrap(); file.read_to_buf(&mut buf).unwrap();
assert_eq!(buf, b"23"); assert_eq!(buf, b"23");
file.clone().seek_sync(SeekFrom::Start(2)).unwrap(); file.seek(SeekFrom::Start(2)).unwrap();
file.clone().read_sync(&mut buf).unwrap(); file.read_to_buf(&mut buf).unwrap();
assert_eq!(buf, b"23"); assert_eq!(buf, b"23");
file.clone().seek_sync(SeekFrom::End(2)).unwrap(); file.seek(SeekFrom::End(2)).unwrap();
file.clone().read_sync(&mut buf).unwrap(); file.read_to_buf(&mut buf).unwrap();
assert_eq!(buf, b"89"); assert_eq!(buf, b"89");
file.clone().seek_sync(SeekFrom::Current(-8)).unwrap(); file.seek(SeekFrom::Current(-8)).unwrap();
file.clone().read_sync(&mut buf).unwrap(); file.read_to_buf(&mut buf).unwrap();
assert_eq!(buf, b"23"); assert_eq!(buf, b"23");
assert_eq!( assert_eq!(
file file
.clone() .seek(SeekFrom::Current(-5))
.seek_sync(SeekFrom::Current(-5)) .unwrap_err()
.err()
.unwrap()
.into_io_error()
.to_string(), .to_string(),
"An attempt was made to move the file pointer before the beginning of the file." "An attempt was made to move the file pointer before the beginning of the file."
); );
// go beyond the file length, then back // go beyond the file length, then back
file.clone().seek_sync(SeekFrom::Current(40)).unwrap(); file.seek(SeekFrom::Current(40)).unwrap();
file.clone().seek_sync(SeekFrom::Current(-38)).unwrap(); file.seek(SeekFrom::Current(-38)).unwrap();
let file = Rc::new(file);
let read_buf = file.clone().read(2).await.unwrap(); let read_buf = file.clone().read(2).await.unwrap();
assert_eq!(read_buf.to_vec(), b"67"); assert_eq!(read_buf.to_vec(), b"67");
file.clone().seek_sync(SeekFrom::Current(-2)).unwrap(); file.clone().seek_sync(SeekFrom::Current(-2)).unwrap();

218
cli/sys.rs Normal file
View file

@ -0,0 +1,218 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// todo(dsherret): this should instead use conditional compilation and directly
// surface the underlying implementation.
//
// The problem atm is that there's no way to have conditional compilation for
// denort or the deno binary. We should extract out denort to a separate binary.
use std::borrow::Cow;
use sys_traits::boxed::BoxedFsDirEntry;
use sys_traits::boxed::BoxedFsFile;
use sys_traits::boxed::BoxedFsMetadataValue;
use sys_traits::boxed::FsMetadataBoxed;
use sys_traits::boxed::FsOpenBoxed;
use sys_traits::boxed::FsReadDirBoxed;
use sys_traits::CreateDirOptions;
use crate::standalone::DenoCompileFileSystem;
#[derive(Debug, Clone)]
pub enum CliSys {
#[allow(dead_code)] // will be dead code for denort
#[allow(clippy::disallowed_types)] // ok because sys impl
Real(sys_traits::impls::RealSys),
#[allow(dead_code)] // will be dead code for deno
DenoCompile(DenoCompileFileSystem),
}
impl Default for CliSys {
fn default() -> Self {
Self::Real(sys_traits::impls::RealSys)
}
}
impl deno_runtime::deno_node::ExtNodeSys for CliSys {}
impl sys_traits::BaseFsHardLink for CliSys {
fn base_fs_hard_link(
&self,
src: &std::path::Path,
dst: &std::path::Path,
) -> std::io::Result<()> {
match self {
Self::Real(sys) => sys.base_fs_hard_link(src, dst),
Self::DenoCompile(sys) => sys.base_fs_hard_link(src, dst),
}
}
}
impl sys_traits::BaseFsRead for CliSys {
fn base_fs_read(
&self,
p: &std::path::Path,
) -> std::io::Result<Cow<'static, [u8]>> {
match self {
Self::Real(sys) => sys.base_fs_read(p),
Self::DenoCompile(sys) => sys.base_fs_read(p),
}
}
}
impl sys_traits::BaseFsReadDir for CliSys {
type ReadDirEntry = BoxedFsDirEntry;
fn base_fs_read_dir(
&self,
p: &std::path::Path,
) -> std::io::Result<
Box<dyn Iterator<Item = std::io::Result<Self::ReadDirEntry>> + '_>,
> {
match self {
Self::Real(sys) => sys.fs_read_dir_boxed(p),
Self::DenoCompile(sys) => sys.fs_read_dir_boxed(p),
}
}
}
impl sys_traits::BaseFsCanonicalize for CliSys {
fn base_fs_canonicalize(
&self,
p: &std::path::Path,
) -> std::io::Result<std::path::PathBuf> {
match self {
Self::Real(sys) => sys.base_fs_canonicalize(p),
Self::DenoCompile(sys) => sys.base_fs_canonicalize(p),
}
}
}
impl sys_traits::BaseFsMetadata for CliSys {
type Metadata = BoxedFsMetadataValue;
fn base_fs_metadata(
&self,
path: &std::path::Path,
) -> std::io::Result<Self::Metadata> {
match self {
Self::Real(sys) => sys.fs_metadata_boxed(path),
Self::DenoCompile(sys) => sys.fs_metadata_boxed(path),
}
}
fn base_fs_symlink_metadata(
&self,
path: &std::path::Path,
) -> std::io::Result<Self::Metadata> {
match self {
Self::Real(sys) => sys.fs_symlink_metadata_boxed(path),
Self::DenoCompile(sys) => sys.fs_symlink_metadata_boxed(path),
}
}
}
impl sys_traits::BaseFsCreateDir for CliSys {
fn base_fs_create_dir(
&self,
p: &std::path::Path,
options: &CreateDirOptions,
) -> std::io::Result<()> {
match self {
Self::Real(sys) => sys.base_fs_create_dir(p, options),
Self::DenoCompile(sys) => sys.base_fs_create_dir(p, options),
}
}
}
impl sys_traits::BaseFsOpen for CliSys {
type File = BoxedFsFile;
fn base_fs_open(
&self,
path: &std::path::Path,
options: &sys_traits::OpenOptions,
) -> std::io::Result<Self::File> {
match self {
Self::Real(sys) => sys.fs_open_boxed(path, options),
Self::DenoCompile(sys) => sys.fs_open_boxed(path, options),
}
}
}
impl sys_traits::BaseFsRemoveFile for CliSys {
fn base_fs_remove_file(&self, p: &std::path::Path) -> std::io::Result<()> {
match self {
Self::Real(sys) => sys.base_fs_remove_file(p),
Self::DenoCompile(sys) => sys.base_fs_remove_file(p),
}
}
}
impl sys_traits::BaseFsRename for CliSys {
fn base_fs_rename(
&self,
old: &std::path::Path,
new: &std::path::Path,
) -> std::io::Result<()> {
match self {
Self::Real(sys) => sys.base_fs_rename(old, new),
Self::DenoCompile(sys) => sys.base_fs_rename(old, new),
}
}
}
impl sys_traits::SystemRandom for CliSys {
fn sys_random(&self, buf: &mut [u8]) -> std::io::Result<()> {
match self {
Self::Real(sys) => sys.sys_random(buf),
Self::DenoCompile(sys) => sys.sys_random(buf),
}
}
}
impl sys_traits::SystemTimeNow for CliSys {
fn sys_time_now(&self) -> std::time::SystemTime {
match self {
Self::Real(sys) => sys.sys_time_now(),
Self::DenoCompile(sys) => sys.sys_time_now(),
}
}
}
impl sys_traits::ThreadSleep for CliSys {
fn thread_sleep(&self, dur: std::time::Duration) {
match self {
Self::Real(sys) => sys.thread_sleep(dur),
Self::DenoCompile(sys) => sys.thread_sleep(dur),
}
}
}
impl sys_traits::EnvCurrentDir for CliSys {
fn env_current_dir(&self) -> std::io::Result<std::path::PathBuf> {
match self {
Self::Real(sys) => sys.env_current_dir(),
Self::DenoCompile(sys) => sys.env_current_dir(),
}
}
}
impl sys_traits::BaseEnvVar for CliSys {
fn base_env_var_os(
&self,
key: &std::ffi::OsStr,
) -> Option<std::ffi::OsString> {
match self {
Self::Real(sys) => sys.base_env_var_os(key),
Self::DenoCompile(sys) => sys.base_env_var_os(key),
}
}
}
impl sys_traits::EnvHomeDir for CliSys {
fn env_home_dir(&self) -> Option<std::path::PathBuf> {
#[allow(clippy::disallowed_types)] // ok because sys impl
sys_traits::impls::RealSys.env_home_dir()
}
}

View file

@ -10,7 +10,6 @@ use deno_core::anyhow::Context;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::futures; use deno_core::futures;
use deno_core::futures::future::LocalBoxFuture; use deno_core::futures::future::LocalBoxFuture;
use deno_runtime::deno_node::NodeResolver;
use deno_semver::package::PackageNv; use deno_semver::package::PackageNv;
use deno_task_shell::ExecutableCommand; use deno_task_shell::ExecutableCommand;
use deno_task_shell::ExecuteResult; use deno_task_shell::ExecuteResult;
@ -25,6 +24,7 @@ use tokio::task::JoinHandle;
use tokio::task::LocalSet; use tokio::task::LocalSet;
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
use crate::node::CliNodeResolver;
use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolver;
use crate::npm::InnerCliNpmResolverRef; use crate::npm::InnerCliNpmResolverRef;
use crate::npm::ManagedCliNpmResolver; use crate::npm::ManagedCliNpmResolver;
@ -415,7 +415,7 @@ impl ShellCommand for NodeModulesFileRunCommand {
pub fn resolve_custom_commands( pub fn resolve_custom_commands(
npm_resolver: &dyn CliNpmResolver, npm_resolver: &dyn CliNpmResolver,
node_resolver: &NodeResolver, node_resolver: &CliNodeResolver,
) -> Result<HashMap<String, Rc<dyn ShellCommand>>, AnyError> { ) -> Result<HashMap<String, Rc<dyn ShellCommand>>, AnyError> {
let mut commands = match npm_resolver.as_inner() { let mut commands = match npm_resolver.as_inner() {
InnerCliNpmResolverRef::Byonm(npm_resolver) => { InnerCliNpmResolverRef::Byonm(npm_resolver) => {
@ -522,7 +522,7 @@ fn resolve_execution_path_from_npx_shim(
fn resolve_managed_npm_commands( fn resolve_managed_npm_commands(
npm_resolver: &ManagedCliNpmResolver, npm_resolver: &ManagedCliNpmResolver,
node_resolver: &NodeResolver, node_resolver: &CliNodeResolver,
) -> Result<HashMap<String, Rc<dyn ShellCommand>>, AnyError> { ) -> Result<HashMap<String, Rc<dyn ShellCommand>>, AnyError> {
let mut result = HashMap::new(); let mut result = HashMap::new();
let snapshot = npm_resolver.snapshot(); let snapshot = npm_resolver.snapshot();

View file

@ -7,6 +7,7 @@ use crate::display::write_json_to_stdout;
use crate::factory::CliFactory; use crate::factory::CliFactory;
use crate::graph_util::has_graph_root_local_dependent_changed; use crate::graph_util::has_graph_root_local_dependent_changed;
use crate::ops; use crate::ops;
use crate::sys::CliSys;
use crate::tools::test::format_test_error; use crate::tools::test::format_test_error;
use crate::tools::test::TestFilter; use crate::tools::test::TestFilter;
use crate::util::file_watcher; use crate::util::file_watcher;
@ -265,7 +266,7 @@ async fn bench_specifier_inner(
async fn bench_specifiers( async fn bench_specifiers(
worker_factory: Arc<CliMainWorkerFactory>, worker_factory: Arc<CliMainWorkerFactory>,
permissions: &Permissions, permissions: &Permissions,
permissions_desc_parser: &Arc<RuntimePermissionDescriptorParser>, permissions_desc_parser: &Arc<RuntimePermissionDescriptorParser<CliSys>>,
specifiers: Vec<ModuleSpecifier>, specifiers: Vec<ModuleSpecifier>,
options: BenchSpecifierOptions, options: BenchSpecifierOptions,
) -> Result<(), AnyError> { ) -> Result<(), AnyError> {

View file

@ -9,7 +9,6 @@ use deno_ast::ModuleSpecifier;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_graph::Module; use deno_graph::Module;
use deno_graph::ModuleGraph; use deno_graph::ModuleGraph;
use deno_runtime::deno_node::NodeResolver;
use deno_terminal::colors; use deno_terminal::colors;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use regex::Regex; use regex::Regex;
@ -29,6 +28,7 @@ use crate::cache::TypeCheckCache;
use crate::factory::CliFactory; use crate::factory::CliFactory;
use crate::graph_util::BuildFastCheckGraphOptions; use crate::graph_util::BuildFastCheckGraphOptions;
use crate::graph_util::ModuleGraphBuilder; use crate::graph_util::ModuleGraphBuilder;
use crate::node::CliNodeResolver;
use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolver;
use crate::tsc; use crate::tsc;
use crate::tsc::Diagnostics; use crate::tsc::Diagnostics;
@ -103,7 +103,7 @@ pub struct TypeChecker {
cjs_tracker: Arc<TypeCheckingCjsTracker>, cjs_tracker: Arc<TypeCheckingCjsTracker>,
cli_options: Arc<CliOptions>, cli_options: Arc<CliOptions>,
module_graph_builder: Arc<ModuleGraphBuilder>, module_graph_builder: Arc<ModuleGraphBuilder>,
node_resolver: Arc<NodeResolver>, node_resolver: Arc<CliNodeResolver>,
npm_resolver: Arc<dyn CliNpmResolver>, npm_resolver: Arc<dyn CliNpmResolver>,
} }
@ -113,7 +113,7 @@ impl TypeChecker {
cjs_tracker: Arc<TypeCheckingCjsTracker>, cjs_tracker: Arc<TypeCheckingCjsTracker>,
cli_options: Arc<CliOptions>, cli_options: Arc<CliOptions>,
module_graph_builder: Arc<ModuleGraphBuilder>, module_graph_builder: Arc<ModuleGraphBuilder>,
node_resolver: Arc<NodeResolver>, node_resolver: Arc<CliNodeResolver>,
npm_resolver: Arc<dyn CliNpmResolver>, npm_resolver: Arc<dyn CliNpmResolver>,
) -> Self { ) -> Self {
Self { Self {

View file

@ -7,6 +7,7 @@ use std::path::Path;
use crate::cache::DenoDir; use crate::cache::DenoDir;
use crate::colors; use crate::colors;
use crate::display; use crate::display;
use crate::sys::CliSys;
use crate::util::progress_bar::ProgressBar; use crate::util::progress_bar::ProgressBar;
use crate::util::progress_bar::ProgressBarStyle; use crate::util::progress_bar::ProgressBarStyle;
use crate::util::progress_bar::ProgressMessagePrompt; use crate::util::progress_bar::ProgressMessagePrompt;
@ -28,7 +29,7 @@ impl CleanState {
} }
pub fn clean() -> Result<(), AnyError> { pub fn clean() -> Result<(), AnyError> {
let deno_dir = DenoDir::new(None)?; let deno_dir = DenoDir::new(CliSys::default(), None)?;
if deno_dir.root.exists() { if deno_dir.root.exists() {
let no_of_files = walkdir::WalkDir::new(&deno_dir.root).into_iter().count(); let no_of_files = walkdir::WalkDir::new(&deno_dir.root).into_iter().count();
let progress_bar = ProgressBar::new(ProgressBarStyle::ProgressBars); let progress_bar = ProgressBar::new(ProgressBarStyle::ProgressBars);

View file

@ -5,8 +5,8 @@ use crate::args::CompileFlags;
use crate::args::Flags; use crate::args::Flags;
use crate::factory::CliFactory; use crate::factory::CliFactory;
use crate::http_util::HttpClientProvider; use crate::http_util::HttpClientProvider;
use crate::standalone::binary::is_standalone_binary;
use crate::standalone::binary::WriteBinOptions; use crate::standalone::binary::WriteBinOptions;
use crate::standalone::is_standalone_binary;
use deno_ast::MediaType; use deno_ast::MediaType;
use deno_ast::ModuleSpecifier; use deno_ast::ModuleSpecifier;
use deno_core::anyhow::bail; use deno_core::anyhow::bail;

View file

@ -7,6 +7,7 @@ use crate::args::Flags;
use crate::cdp; use crate::cdp;
use crate::factory::CliFactory; use crate::factory::CliFactory;
use crate::file_fetcher::TextDecodedFile; use crate::file_fetcher::TextDecodedFile;
use crate::sys::CliSys;
use crate::tools::fmt::format_json; use crate::tools::fmt::format_json;
use crate::tools::test::is_supported_test_path; use crate::tools::test::is_supported_test_path;
use crate::util::text_encoding::source_map_from_code; use crate::util::text_encoding::source_map_from_code;
@ -26,7 +27,6 @@ use deno_core::serde_json;
use deno_core::sourcemap::SourceMap; use deno_core::sourcemap::SourceMap;
use deno_core::url::Url; use deno_core::url::Url;
use deno_core::LocalInspectorSession; use deno_core::LocalInspectorSession;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use node_resolver::InNpmPackageChecker; use node_resolver::InNpmPackageChecker;
use regex::Regex; use regex::Regex;
use std::fs; use std::fs;
@ -429,7 +429,7 @@ fn collect_coverages(
.ignore_git_folder() .ignore_git_folder()
.ignore_node_modules() .ignore_node_modules()
.set_vendor_folder(cli_options.vendor_dir_path().map(ToOwned::to_owned)) .set_vendor_folder(cli_options.vendor_dir_path().map(ToOwned::to_owned))
.collect_file_patterns(&FsSysTraitsAdapter::new_real(), file_patterns)?; .collect_file_patterns(&CliSys::default(), file_patterns)?;
let coverage_patterns = FilePatterns { let coverage_patterns = FilePatterns {
base: initial_cwd.to_path_buf(), base: initial_cwd.to_path_buf(),

View file

@ -10,6 +10,7 @@ use crate::factory::CliFactory;
use crate::graph_util::graph_exit_integrity_errors; use crate::graph_util::graph_exit_integrity_errors;
use crate::graph_util::graph_walk_errors; use crate::graph_util::graph_walk_errors;
use crate::graph_util::GraphWalkErrorsOptions; use crate::graph_util::GraphWalkErrorsOptions;
use crate::sys::CliSys;
use crate::tsc::get_types_declaration_file_text; use crate::tsc::get_types_declaration_file_text;
use crate::util::fs::collect_specifiers; use crate::util::fs::collect_specifiers;
use deno_ast::diagnostics::Diagnostic; use deno_ast::diagnostics::Diagnostic;
@ -28,7 +29,6 @@ use deno_graph::EsParser;
use deno_graph::GraphKind; use deno_graph::GraphKind;
use deno_graph::ModuleAnalyzer; use deno_graph::ModuleAnalyzer;
use deno_graph::ModuleSpecifier; use deno_graph::ModuleSpecifier;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use doc::html::ShortPath; use doc::html::ShortPath;
use doc::DocDiagnostic; use doc::DocDiagnostic;
use indexmap::IndexMap; use indexmap::IndexMap;
@ -115,7 +115,7 @@ pub async fn doc(
} }
DocSourceFileFlag::Paths(ref source_files) => { DocSourceFileFlag::Paths(ref source_files) => {
let module_graph_creator = factory.module_graph_creator().await?; let module_graph_creator = factory.module_graph_creator().await?;
let fs = FsSysTraitsAdapter(factory.fs().clone()); let sys = CliSys::default();
let module_specifiers = collect_specifiers( let module_specifiers = collect_specifiers(
FilePatterns { FilePatterns {
@ -142,7 +142,7 @@ pub async fn doc(
graph_exit_integrity_errors(&graph); graph_exit_integrity_errors(&graph);
let errors = graph_walk_errors( let errors = graph_walk_errors(
&graph, &graph,
&fs, &sys,
&module_specifiers, &module_specifiers,
GraphWalkErrorsOptions { GraphWalkErrorsOptions {
check_js: false, check_js: false,

View file

@ -17,6 +17,7 @@ use crate::args::UnstableFmtOptions;
use crate::cache::Caches; use crate::cache::Caches;
use crate::colors; use crate::colors;
use crate::factory::CliFactory; use crate::factory::CliFactory;
use crate::sys::CliSys;
use crate::util::diff::diff; use crate::util::diff::diff;
use crate::util::file_watcher; use crate::util::file_watcher;
use crate::util::fs::canonicalize_path; use crate::util::fs::canonicalize_path;
@ -34,7 +35,6 @@ use deno_core::futures;
use deno_core::parking_lot::Mutex; use deno_core::parking_lot::Mutex;
use deno_core::unsync::spawn_blocking; use deno_core::unsync::spawn_blocking;
use deno_core::url::Url; use deno_core::url::Url;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use log::debug; use log::debug;
use log::info; use log::info;
use log::warn; use log::warn;
@ -58,7 +58,7 @@ pub async fn format(
fmt_flags: FmtFlags, fmt_flags: FmtFlags,
) -> Result<(), AnyError> { ) -> Result<(), AnyError> {
if fmt_flags.is_stdin() { if fmt_flags.is_stdin() {
let cli_options = CliOptions::from_flags(flags)?; let cli_options = CliOptions::from_flags(&CliSys::default(), flags)?;
let start_dir = &cli_options.start_dir; let start_dir = &cli_options.start_dir;
let fmt_config = start_dir let fmt_config = start_dir
.to_fmt_config(FilePatterns::new_with_base(start_dir.dir_path()))?; .to_fmt_config(FilePatterns::new_with_base(start_dir.dir_path()))?;
@ -231,7 +231,7 @@ fn collect_fmt_files(
.ignore_node_modules() .ignore_node_modules()
.use_gitignore() .use_gitignore()
.set_vendor_folder(cli_options.vendor_dir_path().map(ToOwned::to_owned)) .set_vendor_folder(cli_options.vendor_dir_path().map(ToOwned::to_owned))
.collect_file_patterns(&FsSysTraitsAdapter::new_real(), files) .collect_file_patterns(&CliSys::default(), files)
} }
/// Formats markdown (using <https://github.com/dprint/dprint-plugin-markdown>) and its code blocks /// Formats markdown (using <https://github.com/dprint/dprint-plugin-markdown>) and its code blocks

View file

@ -363,6 +363,7 @@ async fn install_global(
let deps_file_fetcher = CliFileFetcher::new( let deps_file_fetcher = CliFileFetcher::new(
deps_http_cache.clone(), deps_http_cache.clone(),
http_client.clone(), http_client.clone(),
factory.sys(),
Default::default(), Default::default(),
None, None,
true, true,

View file

@ -16,8 +16,8 @@ use deno_lint::linter::LintFileOptions;
use deno_lint::linter::Linter as DenoLintLinter; use deno_lint::linter::Linter as DenoLintLinter;
use deno_lint::linter::LinterOptions; use deno_lint::linter::LinterOptions;
use deno_path_util::fs::atomic_write_file_with_retries; use deno_path_util::fs::atomic_write_file_with_retries;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use crate::sys::CliSys;
use crate::util::fs::specifier_from_file_path; use crate::util::fs::specifier_from_file_path;
use super::rules::FileOrPackageLintRule; use super::rules::FileOrPackageLintRule;
@ -177,7 +177,7 @@ impl CliLinter {
if fix_iterations > 0 { if fix_iterations > 0 {
// everything looks good and the file still parses, so write it out // everything looks good and the file still parses, so write it out
atomic_write_file_with_retries( atomic_write_file_with_retries(
&FsSysTraitsAdapter::new_real(), &CliSys::default(),
file_path, file_path,
source.text().as_bytes(), source.text().as_bytes(),
crate::cache::CACHE_PERM, crate::cache::CACHE_PERM,

View file

@ -21,7 +21,6 @@ use deno_core::unsync::future::SharedLocal;
use deno_graph::ModuleGraph; use deno_graph::ModuleGraph;
use deno_lint::diagnostic::LintDiagnostic; use deno_lint::diagnostic::LintDiagnostic;
use deno_lint::linter::LintConfig as DenoLintConfig; use deno_lint::linter::LintConfig as DenoLintConfig;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use log::debug; use log::debug;
use reporters::create_reporter; use reporters::create_reporter;
use reporters::LintReporter; use reporters::LintReporter;
@ -44,6 +43,7 @@ use crate::cache::IncrementalCache;
use crate::colors; use crate::colors;
use crate::factory::CliFactory; use crate::factory::CliFactory;
use crate::graph_util::ModuleGraphCreator; use crate::graph_util::ModuleGraphCreator;
use crate::sys::CliSys;
use crate::tools::fmt::run_parallelized; use crate::tools::fmt::run_parallelized;
use crate::util::display; use crate::util::display;
use crate::util::file_watcher; use crate::util::file_watcher;
@ -453,7 +453,7 @@ fn collect_lint_files(
.ignore_node_modules() .ignore_node_modules()
.use_gitignore() .use_gitignore()
.set_vendor_folder(cli_options.vendor_dir_path().map(ToOwned::to_owned)) .set_vendor_folder(cli_options.vendor_dir_path().map(ToOwned::to_owned))
.collect_file_patterns(&FsSysTraitsAdapter::new_real(), files) .collect_file_patterns(&CliSys::default(), files)
} }
#[allow(clippy::print_stdout)] #[allow(clippy::print_stdout)]

View file

@ -6,12 +6,12 @@ use std::collections::HashSet;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use crate::sys::CliSys;
use deno_ast::MediaType; use deno_ast::MediaType;
use deno_ast::ModuleSpecifier; use deno_ast::ModuleSpecifier;
use deno_config::glob::FileCollector; use deno_config::glob::FileCollector;
use deno_config::glob::FilePatterns; use deno_config::glob::FilePatterns;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use thiserror::Error; use thiserror::Error;
use crate::args::CliOptions; use crate::args::CliOptions;
@ -346,5 +346,5 @@ fn collect_paths(
.ignore_node_modules() .ignore_node_modules()
.set_vendor_folder(cli_options.vendor_dir_path().map(ToOwned::to_owned)) .set_vendor_folder(cli_options.vendor_dir_path().map(ToOwned::to_owned))
.use_gitignore() .use_gitignore()
.collect_file_patterns(&FsSysTraitsAdapter::new_real(), file_patterns) .collect_file_patterns(&CliSys::default(), file_patterns)
} }

View file

@ -415,6 +415,7 @@ pub async fn add(
let deps_file_fetcher = CliFileFetcher::new( let deps_file_fetcher = CliFileFetcher::new(
deps_http_cache.clone(), deps_http_cache.clone(),
http_client.clone(), http_client.clone(),
cli_factory.sys(),
Default::default(), Default::default(),
None, None,
true, true,

View file

@ -185,6 +185,7 @@ pub async fn outdated(
let file_fetcher = CliFileFetcher::new( let file_fetcher = CliFileFetcher::new(
deps_http_cache.clone(), deps_http_cache.clone(),
http_client.clone(), http_client.clone(),
factory.sys(),
Default::default(), Default::default(),
None, None,
true, true,

View file

@ -658,13 +658,12 @@ mod tests {
use crate::resolver::SloppyImportsCachedFs; use crate::resolver::SloppyImportsCachedFs;
use super::*; use super::*;
use crate::sys::CliSys;
use deno_ast::MediaType; use deno_ast::MediaType;
use deno_ast::ModuleSpecifier; use deno_ast::ModuleSpecifier;
use deno_config::workspace::ResolverWorkspaceJsrPackage; use deno_config::workspace::ResolverWorkspaceJsrPackage;
use deno_core::serde_json::json; use deno_core::serde_json::json;
use deno_core::url::Url; use deno_core::url::Url;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_fs::RealFs;
use deno_runtime::deno_node::PackageJson; use deno_runtime::deno_node::PackageJson;
use deno_semver::Version; use deno_semver::Version;
use import_map::ImportMapWithDiagnostics; use import_map::ImportMapWithDiagnostics;
@ -725,7 +724,7 @@ mod tests {
); );
let unfurler = SpecifierUnfurler::new( let unfurler = SpecifierUnfurler::new(
Some(Arc::new(CliSloppyImportsResolver::new( Some(Arc::new(CliSloppyImportsResolver::new(
SloppyImportsCachedFs::new(FsSysTraitsAdapter::new_real()), SloppyImportsCachedFs::new(CliSys::default()),
))), ))),
Arc::new(workspace_resolver), Arc::new(workspace_resolver),
true, true,
@ -863,10 +862,10 @@ const warn2 = await import(`${expr}`);
], ],
deno_config::workspace::PackageJsonDepResolution::Enabled, deno_config::workspace::PackageJsonDepResolution::Enabled,
); );
let fs = FsSysTraitsAdapter(Arc::new(RealFs)); let sys = CliSys::default();
let unfurler = SpecifierUnfurler::new( let unfurler = SpecifierUnfurler::new(
Some(Arc::new(CliSloppyImportsResolver::new( Some(Arc::new(CliSloppyImportsResolver::new(
SloppyImportsCachedFs::new(fs), SloppyImportsCachedFs::new(sys),
))), ))),
Arc::new(workspace_resolver), Arc::new(workspace_resolver),
true, true,

View file

@ -25,7 +25,6 @@ use deno_core::futures::FutureExt;
use deno_core::futures::StreamExt; use deno_core::futures::StreamExt;
use deno_core::url::Url; use deno_core::url::Url;
use deno_path_util::normalize_path; use deno_path_util::normalize_path;
use deno_runtime::deno_node::NodeResolver;
use deno_task_shell::KillSignal; use deno_task_shell::KillSignal;
use deno_task_shell::ShellCommand; use deno_task_shell::ShellCommand;
use indexmap::IndexMap; use indexmap::IndexMap;
@ -36,6 +35,7 @@ use crate::args::Flags;
use crate::args::TaskFlags; use crate::args::TaskFlags;
use crate::colors; use crate::colors;
use crate::factory::CliFactory; use crate::factory::CliFactory;
use crate::node::CliNodeResolver;
use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolver;
use crate::task_runner; use crate::task_runner;
use crate::task_runner::run_future_forwarding_signals; use crate::task_runner::run_future_forwarding_signals;
@ -267,7 +267,7 @@ struct RunSingleOptions<'a> {
struct TaskRunner<'a> { struct TaskRunner<'a> {
task_flags: &'a TaskFlags, task_flags: &'a TaskFlags,
npm_resolver: &'a dyn CliNpmResolver, npm_resolver: &'a dyn CliNpmResolver,
node_resolver: &'a NodeResolver, node_resolver: &'a CliNodeResolver,
env_vars: HashMap<String, String>, env_vars: HashMap<String, String>,
cli_options: &'a CliOptions, cli_options: &'a CliOptions,
concurrency: usize, concurrency: usize,

View file

@ -10,6 +10,7 @@ use crate::factory::CliFactory;
use crate::file_fetcher::CliFileFetcher; use crate::file_fetcher::CliFileFetcher;
use crate::graph_util::has_graph_root_local_dependent_changed; use crate::graph_util::has_graph_root_local_dependent_changed;
use crate::ops; use crate::ops;
use crate::sys::CliSys;
use crate::util::extract::extract_doc_tests; use crate::util::extract::extract_doc_tests;
use crate::util::file_watcher; use crate::util::file_watcher;
use crate::util::fs::collect_specifiers; use crate::util::fs::collect_specifiers;
@ -1194,7 +1195,7 @@ static HAS_TEST_RUN_SIGINT_HANDLER: AtomicBool = AtomicBool::new(false);
async fn test_specifiers( async fn test_specifiers(
worker_factory: Arc<CliMainWorkerFactory>, worker_factory: Arc<CliMainWorkerFactory>,
permissions: &Permissions, permissions: &Permissions,
permission_desc_parser: &Arc<RuntimePermissionDescriptorParser>, permission_desc_parser: &Arc<RuntimePermissionDescriptorParser<CliSys>>,
specifiers: Vec<ModuleSpecifier>, specifiers: Vec<ModuleSpecifier>,
options: TestSpecifiersOptions, options: TestSpecifiersOptions,
) -> Result<(), AnyError> { ) -> Result<(), AnyError> {

View file

@ -4,8 +4,10 @@ use crate::args::TsConfig;
use crate::args::TypeCheckMode; use crate::args::TypeCheckMode;
use crate::cache::FastInsecureHasher; use crate::cache::FastInsecureHasher;
use crate::cache::ModuleInfoCache; use crate::cache::ModuleInfoCache;
use crate::node::CliNodeResolver;
use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolver;
use crate::resolver::CjsTracker; use crate::resolver::CjsTracker;
use crate::sys::CliSys;
use crate::util::checksum; use crate::util::checksum;
use crate::util::path::mapped_specifier_for_tsc; use crate::util::path::mapped_specifier_for_tsc;
use crate::worker::create_isolate_create_params; use crate::worker::create_isolate_create_params;
@ -34,8 +36,6 @@ use deno_graph::Module;
use deno_graph::ModuleGraph; use deno_graph::ModuleGraph;
use deno_graph::ResolutionResolved; use deno_graph::ResolutionResolved;
use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; use deno_resolver::npm::ResolvePkgFolderFromDenoReqError;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use deno_runtime::deno_node::NodeResolver;
use deno_semver::npm::NpmPackageReqReference; use deno_semver::npm::NpmPackageReqReference;
use node_resolver::errors::NodeJsErrorCode; use node_resolver::errors::NodeJsErrorCode;
use node_resolver::errors::NodeJsErrorCoded; use node_resolver::errors::NodeJsErrorCoded;
@ -380,7 +380,7 @@ impl TypeCheckingCjsTracker {
#[derive(Debug)] #[derive(Debug)]
pub struct RequestNpmState { pub struct RequestNpmState {
pub cjs_tracker: Arc<TypeCheckingCjsTracker>, pub cjs_tracker: Arc<TypeCheckingCjsTracker>,
pub node_resolver: Arc<NodeResolver>, pub node_resolver: Arc<CliNodeResolver>,
pub npm_resolver: Arc<dyn CliNpmResolver>, pub npm_resolver: Arc<dyn CliNpmResolver>,
} }
@ -661,7 +661,7 @@ fn op_load_inner(
} else { } else {
// means it's Deno code importing an npm module // means it's Deno code importing an npm module
let specifier = resolve_specifier_into_node_modules( let specifier = resolve_specifier_into_node_modules(
&FsSysTraitsAdapter::new_real(), &CliSys::default(),
&module.specifier, &module.specifier,
); );
Some(Cow::Owned(load_from_node_modules( Some(Cow::Owned(load_from_node_modules(
@ -925,7 +925,7 @@ fn resolve_graph_specifier_types(
// we currently only use "External" for when the module is in an npm package // we currently only use "External" for when the module is in an npm package
Ok(state.maybe_npm.as_ref().map(|_| { Ok(state.maybe_npm.as_ref().map(|_| {
let specifier = resolve_specifier_into_node_modules( let specifier = resolve_specifier_into_node_modules(
&FsSysTraitsAdapter::new_real(), &CliSys::default(),
&module.specifier, &module.specifier,
); );
into_specifier_and_media_type(Some(specifier)) into_specifier_and_media_type(Some(specifier))

View file

@ -17,8 +17,8 @@ use deno_core::anyhow::Context;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::unsync::spawn_blocking; use deno_core::unsync::spawn_blocking;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_runtime::deno_fs::FsSysTraitsAdapter;
use crate::sys::CliSys;
use crate::util::progress_bar::ProgressBar; use crate::util::progress_bar::ProgressBar;
use crate::util::progress_bar::ProgressBarStyle; use crate::util::progress_bar::ProgressBarStyle;
use crate::util::progress_bar::ProgressMessagePrompt; use crate::util::progress_bar::ProgressMessagePrompt;
@ -76,7 +76,7 @@ pub fn canonicalize_path_maybe_not_exists(
path: &Path, path: &Path,
) -> Result<PathBuf, Error> { ) -> Result<PathBuf, Error> {
deno_path_util::fs::canonicalize_path_maybe_not_exists( deno_path_util::fs::canonicalize_path_maybe_not_exists(
&FsSysTraitsAdapter::new_real(), &CliSys::default(),
path, path,
) )
} }
@ -126,7 +126,7 @@ pub fn collect_specifiers(
.ignore_git_folder() .ignore_git_folder()
.ignore_node_modules() .ignore_node_modules()
.set_vendor_folder(vendor_folder) .set_vendor_folder(vendor_folder)
.collect_file_patterns(&FsSysTraitsAdapter::new_real(), files)?; .collect_file_patterns(&CliSys::default(), files)?;
let mut collected_files_as_urls = collected_files let mut collected_files_as_urls = collected_files
.iter() .iter()
.map(|f| specifier_from_file_path(f).unwrap()) .map(|f| specifier_from_file_path(f).unwrap())
@ -198,13 +198,11 @@ mod clone_dir_imp {
from: &std::path::Path, from: &std::path::Path,
to: &std::path::Path, to: &std::path::Path,
) -> Result<(), deno_core::error::AnyError> { ) -> Result<(), deno_core::error::AnyError> {
use deno_runtime::deno_fs::FsSysTraitsAdapter; use crate::sys::CliSys;
if let Err(e) = deno_npm_cache::hard_link_dir_recursive( if let Err(e) =
&FsSysTraitsAdapter::new_real(), deno_npm_cache::hard_link_dir_recursive(&CliSys::default(), from, to)
from, {
to,
) {
log::debug!("Failed to hard link dir {:?} to {:?}: {}", from, to, e); log::debug!("Failed to hard link dir {:?} to {:?}: {}", from, to, e);
super::copy_dir_recursive(from, to)?; super::copy_dir_recursive(from, to)?;
} }

View file

@ -23,8 +23,6 @@ use deno_runtime::deno_fs;
use deno_runtime::deno_node::NodeExtInitServices; use deno_runtime::deno_node::NodeExtInitServices;
use deno_runtime::deno_node::NodeRequireLoader; use deno_runtime::deno_node::NodeRequireLoader;
use deno_runtime::deno_node::NodeRequireLoaderRc; use deno_runtime::deno_node::NodeRequireLoaderRc;
use deno_runtime::deno_node::NodeResolver;
use deno_runtime::deno_node::PackageJsonResolver;
use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_permissions::PermissionsContainer;
use deno_runtime::deno_tls::RootCertStoreProvider; use deno_runtime::deno_tls::RootCertStoreProvider;
use deno_runtime::deno_web::BlobStore; use deno_runtime::deno_web::BlobStore;
@ -53,7 +51,10 @@ use crate::args::DenoSubcommand;
use crate::args::NpmCachingStrategy; use crate::args::NpmCachingStrategy;
use crate::args::StorageKeyResolver; use crate::args::StorageKeyResolver;
use crate::errors; use crate::errors;
use crate::node::CliNodeResolver;
use crate::node::CliPackageJsonResolver;
use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolver;
use crate::sys::CliSys;
use crate::util::checksum; use crate::util::checksum;
use crate::util::file_watcher::WatcherCommunicator; use crate::util::file_watcher::WatcherCommunicator;
use crate::util::file_watcher::WatcherRestartMode; use crate::util::file_watcher::WatcherRestartMode;
@ -145,13 +146,14 @@ struct SharedWorkerState {
maybe_inspector_server: Option<Arc<InspectorServer>>, maybe_inspector_server: Option<Arc<InspectorServer>>,
maybe_lockfile: Option<Arc<CliLockfile>>, maybe_lockfile: Option<Arc<CliLockfile>>,
module_loader_factory: Box<dyn ModuleLoaderFactory>, module_loader_factory: Box<dyn ModuleLoaderFactory>,
node_resolver: Arc<NodeResolver>, node_resolver: Arc<CliNodeResolver>,
npm_resolver: Arc<dyn CliNpmResolver>, npm_resolver: Arc<dyn CliNpmResolver>,
pkg_json_resolver: Arc<PackageJsonResolver>, pkg_json_resolver: Arc<CliPackageJsonResolver>,
root_cert_store_provider: Arc<dyn RootCertStoreProvider>, root_cert_store_provider: Arc<dyn RootCertStoreProvider>,
root_permissions: PermissionsContainer, root_permissions: PermissionsContainer,
shared_array_buffer_store: SharedArrayBufferStore, shared_array_buffer_store: SharedArrayBufferStore,
storage_key_resolver: StorageKeyResolver, storage_key_resolver: StorageKeyResolver,
sys: CliSys,
options: CliMainWorkerOptions, options: CliMainWorkerOptions,
subcommand: DenoSubcommand, subcommand: DenoSubcommand,
otel_config: OtelConfig, otel_config: OtelConfig,
@ -162,12 +164,13 @@ impl SharedWorkerState {
pub fn create_node_init_services( pub fn create_node_init_services(
&self, &self,
node_require_loader: NodeRequireLoaderRc, node_require_loader: NodeRequireLoaderRc,
) -> NodeExtInitServices { ) -> NodeExtInitServices<CliSys> {
NodeExtInitServices { NodeExtInitServices {
node_require_loader, node_require_loader,
node_resolver: self.node_resolver.clone(), node_resolver: self.node_resolver.clone(),
npm_resolver: self.npm_resolver.clone().into_npm_pkg_folder_resolver(), npm_resolver: self.npm_resolver.clone().into_npm_pkg_folder_resolver(),
pkg_json_resolver: self.pkg_json_resolver.clone(), pkg_json_resolver: self.pkg_json_resolver.clone(),
sys: self.sys.clone(),
} }
} }
@ -418,12 +421,13 @@ impl CliMainWorkerFactory {
maybe_inspector_server: Option<Arc<InspectorServer>>, maybe_inspector_server: Option<Arc<InspectorServer>>,
maybe_lockfile: Option<Arc<CliLockfile>>, maybe_lockfile: Option<Arc<CliLockfile>>,
module_loader_factory: Box<dyn ModuleLoaderFactory>, module_loader_factory: Box<dyn ModuleLoaderFactory>,
node_resolver: Arc<NodeResolver>, node_resolver: Arc<CliNodeResolver>,
npm_resolver: Arc<dyn CliNpmResolver>, npm_resolver: Arc<dyn CliNpmResolver>,
pkg_json_resolver: Arc<PackageJsonResolver>, pkg_json_resolver: Arc<CliPackageJsonResolver>,
root_cert_store_provider: Arc<dyn RootCertStoreProvider>, root_cert_store_provider: Arc<dyn RootCertStoreProvider>,
root_permissions: PermissionsContainer, root_permissions: PermissionsContainer,
storage_key_resolver: StorageKeyResolver, storage_key_resolver: StorageKeyResolver,
sys: CliSys,
subcommand: DenoSubcommand, subcommand: DenoSubcommand,
options: CliMainWorkerOptions, options: CliMainWorkerOptions,
otel_config: OtelConfig, otel_config: OtelConfig,
@ -448,6 +452,7 @@ impl CliMainWorkerFactory {
root_permissions, root_permissions,
shared_array_buffer_store: Default::default(), shared_array_buffer_store: Default::default(),
storage_key_resolver, storage_key_resolver,
sys,
options, options,
subcommand, subcommand,
otel_config, otel_config,
@ -869,14 +874,15 @@ mod tests {
let main_module = let main_module =
resolve_path("./hello.js", &std::env::current_dir().unwrap()).unwrap(); resolve_path("./hello.js", &std::env::current_dir().unwrap()).unwrap();
let fs = Arc::new(RealFs); let fs = Arc::new(RealFs);
let permission_desc_parser = let permission_desc_parser = Arc::new(
Arc::new(RuntimePermissionDescriptorParser::new(fs.clone())); RuntimePermissionDescriptorParser::new(crate::sys::CliSys::default()),
);
let options = WorkerOptions { let options = WorkerOptions {
startup_snapshot: crate::js::deno_isolate_init(), startup_snapshot: crate::js::deno_isolate_init(),
..Default::default() ..Default::default()
}; };
MainWorker::bootstrap_from_options( MainWorker::bootstrap_from_options::<CliSys>(
main_module, main_module,
WorkerServiceOptions { WorkerServiceOptions {
module_loader: Rc::new(FsModuleLoader), module_loader: Rc::new(FsModuleLoader),

View file

@ -25,12 +25,10 @@ deno_io.workspace = true
deno_path_util.workspace = true deno_path_util.workspace = true
deno_permissions.workspace = true deno_permissions.workspace = true
filetime.workspace = true filetime.workspace = true
getrandom = "0.2"
libc.workspace = true libc.workspace = true
rand.workspace = true rand.workspace = true
rayon = "1.8.0" rayon = "1.8.0"
serde.workspace = true serde.workspace = true
sys_traits.workspace = true
thiserror.workspace = true thiserror.workspace = true
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]

View file

@ -1,481 +0,0 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Allow using Arc for this module.
#![allow(clippy::disallowed_types)]
use std::borrow::Cow;
use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::io::Error;
use std::io::ErrorKind;
use std::path::Path;
use std::path::PathBuf;
use std::rc::Rc;
use std::sync::Arc;
use deno_core::parking_lot::Mutex;
use deno_io::fs::File;
use deno_io::fs::FsError;
use deno_io::fs::FsResult;
use deno_io::fs::FsStat;
use deno_path_util::normalize_path;
use crate::interface::AccessCheckCb;
use crate::interface::FsDirEntry;
use crate::interface::FsFileType;
use crate::FileSystem;
use crate::OpenOptions;
#[derive(Debug)]
enum PathEntry {
Dir,
File(Vec<u8>),
}
/// A very basic in-memory file system useful for swapping out in
/// the place of a RealFs for testing purposes.
///
/// Please develop this out as you need functionality.
#[derive(Debug, Default)]
pub struct InMemoryFs {
entries: Mutex<HashMap<PathBuf, Arc<PathEntry>>>,
}
impl InMemoryFs {
pub fn setup_text_files(&self, files: Vec<(String, String)>) {
for (path, text) in files {
let path = PathBuf::from(path);
self.mkdir_sync(path.parent().unwrap(), true, None).unwrap();
self
.write_file_sync(
&path,
OpenOptions::write(true, false, false, None),
None,
&text.into_bytes(),
)
.unwrap();
}
}
fn get_entry(&self, path: &Path) -> Option<Arc<PathEntry>> {
let path = normalize_path(path);
self.entries.lock().get(&path).cloned()
}
}
#[async_trait::async_trait(?Send)]
impl FileSystem for InMemoryFs {
fn cwd(&self) -> FsResult<PathBuf> {
Err(FsError::NotSupported)
}
fn tmp_dir(&self) -> FsResult<PathBuf> {
Err(FsError::NotSupported)
}
fn chdir(&self, _path: &Path) -> FsResult<()> {
Err(FsError::NotSupported)
}
fn umask(&self, _mask: Option<u32>) -> FsResult<u32> {
Err(FsError::NotSupported)
}
fn open_sync(
&self,
_path: &Path,
_options: OpenOptions,
_access_check: Option<AccessCheckCb>,
) -> FsResult<Rc<dyn File>> {
Err(FsError::NotSupported)
}
async fn open_async<'a>(
&'a self,
path: PathBuf,
options: OpenOptions,
access_check: Option<AccessCheckCb<'a>>,
) -> FsResult<Rc<dyn File>> {
self.open_sync(&path, options, access_check)
}
fn mkdir_sync(
&self,
path: &Path,
recursive: bool,
_mode: Option<u32>,
) -> FsResult<()> {
let path = normalize_path(path);
if let Some(parent) = path.parent() {
let entry = self.entries.lock().get(parent).cloned();
match entry {
Some(entry) => match &*entry {
PathEntry::File(_) => {
return Err(FsError::Io(Error::new(
ErrorKind::InvalidInput,
"Parent is a file",
)))
}
PathEntry::Dir => {}
},
None => {
if recursive {
self.mkdir_sync(parent, true, None)?;
} else {
return Err(FsError::Io(Error::new(
ErrorKind::NotFound,
"Not found",
)));
}
}
}
}
let entry = self.entries.lock().get(&path).cloned();
match entry {
Some(entry) => match &*entry {
PathEntry::File(_) => Err(FsError::Io(Error::new(
ErrorKind::InvalidInput,
"Is a file",
))),
PathEntry::Dir => Ok(()),
},
None => {
self.entries.lock().insert(path, Arc::new(PathEntry::Dir));
Ok(())
}
}
}
async fn mkdir_async(
&self,
path: PathBuf,
recursive: bool,
mode: Option<u32>,
) -> FsResult<()> {
self.mkdir_sync(&path, recursive, mode)
}
fn chmod_sync(&self, _path: &Path, _mode: u32) -> FsResult<()> {
Err(FsError::NotSupported)
}
async fn chmod_async(&self, path: PathBuf, mode: u32) -> FsResult<()> {
self.chmod_sync(&path, mode)
}
fn chown_sync(
&self,
_path: &Path,
_uid: Option<u32>,
_gid: Option<u32>,
) -> FsResult<()> {
Err(FsError::NotSupported)
}
async fn chown_async(
&self,
path: PathBuf,
uid: Option<u32>,
gid: Option<u32>,
) -> FsResult<()> {
self.chown_sync(&path, uid, gid)
}
fn lchown_sync(
&self,
_path: &Path,
_uid: Option<u32>,
_gid: Option<u32>,
) -> FsResult<()> {
Err(FsError::NotSupported)
}
async fn lchown_async(
&self,
path: PathBuf,
uid: Option<u32>,
gid: Option<u32>,
) -> FsResult<()> {
self.lchown_sync(&path, uid, gid)
}
fn remove_sync(&self, _path: &Path, _recursive: bool) -> FsResult<()> {
Err(FsError::NotSupported)
}
async fn remove_async(&self, path: PathBuf, recursive: bool) -> FsResult<()> {
self.remove_sync(&path, recursive)
}
fn copy_file_sync(&self, _from: &Path, _to: &Path) -> FsResult<()> {
Err(FsError::NotSupported)
}
async fn copy_file_async(&self, from: PathBuf, to: PathBuf) -> FsResult<()> {
self.copy_file_sync(&from, &to)
}
fn cp_sync(&self, _from: &Path, _to: &Path) -> FsResult<()> {
Err(FsError::NotSupported)
}
async fn cp_async(&self, from: PathBuf, to: PathBuf) -> FsResult<()> {
self.cp_sync(&from, &to)
}
fn stat_sync(&self, path: &Path) -> FsResult<FsStat> {
let entry = self.get_entry(path);
match entry {
Some(entry) => match &*entry {
PathEntry::Dir => Ok(FsStat {
is_file: false,
is_directory: true,
is_symlink: false,
size: 0,
mtime: None,
atime: None,
birthtime: None,
ctime: None,
dev: 0,
ino: 0,
mode: 0,
nlink: 0,
uid: 0,
gid: 0,
rdev: 0,
blksize: 0,
blocks: 0,
is_block_device: false,
is_char_device: false,
is_fifo: false,
is_socket: false,
}),
PathEntry::File(data) => Ok(FsStat {
is_file: true,
is_directory: false,
is_symlink: false,
size: data.len() as u64,
mtime: None,
atime: None,
birthtime: None,
ctime: None,
dev: 0,
ino: 0,
mode: 0,
nlink: 0,
uid: 0,
gid: 0,
rdev: 0,
blksize: 0,
blocks: 0,
is_block_device: false,
is_char_device: false,
is_fifo: false,
is_socket: false,
}),
},
None => Err(FsError::Io(Error::new(ErrorKind::NotFound, "Not found"))),
}
}
async fn stat_async(&self, path: PathBuf) -> FsResult<FsStat> {
self.stat_sync(&path)
}
fn lstat_sync(&self, _path: &Path) -> FsResult<FsStat> {
Err(FsError::NotSupported)
}
async fn lstat_async(&self, path: PathBuf) -> FsResult<FsStat> {
self.lstat_sync(&path)
}
fn realpath_sync(&self, _path: &Path) -> FsResult<PathBuf> {
Err(FsError::NotSupported)
}
async fn realpath_async(&self, path: PathBuf) -> FsResult<PathBuf> {
self.realpath_sync(&path)
}
fn read_dir_sync(&self, _path: &Path) -> FsResult<Vec<FsDirEntry>> {
Err(FsError::NotSupported)
}
async fn read_dir_async(&self, path: PathBuf) -> FsResult<Vec<FsDirEntry>> {
self.read_dir_sync(&path)
}
fn rename_sync(&self, _oldpath: &Path, _newpath: &Path) -> FsResult<()> {
Err(FsError::NotSupported)
}
async fn rename_async(
&self,
oldpath: PathBuf,
newpath: PathBuf,
) -> FsResult<()> {
self.rename_sync(&oldpath, &newpath)
}
fn link_sync(&self, _oldpath: &Path, _newpath: &Path) -> FsResult<()> {
Err(FsError::NotSupported)
}
async fn link_async(
&self,
oldpath: PathBuf,
newpath: PathBuf,
) -> FsResult<()> {
self.link_sync(&oldpath, &newpath)
}
fn symlink_sync(
&self,
_oldpath: &Path,
_newpath: &Path,
_file_type: Option<FsFileType>,
) -> FsResult<()> {
Err(FsError::NotSupported)
}
async fn symlink_async(
&self,
oldpath: PathBuf,
newpath: PathBuf,
file_type: Option<FsFileType>,
) -> FsResult<()> {
self.symlink_sync(&oldpath, &newpath, file_type)
}
fn read_link_sync(&self, _path: &Path) -> FsResult<PathBuf> {
Err(FsError::NotSupported)
}
async fn read_link_async(&self, path: PathBuf) -> FsResult<PathBuf> {
self.read_link_sync(&path)
}
fn truncate_sync(&self, _path: &Path, _len: u64) -> FsResult<()> {
Err(FsError::NotSupported)
}
async fn truncate_async(&self, path: PathBuf, len: u64) -> FsResult<()> {
self.truncate_sync(&path, len)
}
fn utime_sync(
&self,
_path: &Path,
_atime_secs: i64,
_atime_nanos: u32,
_mtime_secs: i64,
_mtime_nanos: u32,
) -> FsResult<()> {
Err(FsError::NotSupported)
}
async fn utime_async(
&self,
path: PathBuf,
atime_secs: i64,
atime_nanos: u32,
mtime_secs: i64,
mtime_nanos: u32,
) -> FsResult<()> {
self.utime_sync(&path, atime_secs, atime_nanos, mtime_secs, mtime_nanos)
}
fn lutime_sync(
&self,
_path: &Path,
_atime_secs: i64,
_atime_nanos: u32,
_mtime_secs: i64,
_mtime_nanos: u32,
) -> FsResult<()> {
Err(FsError::NotSupported)
}
async fn lutime_async(
&self,
path: PathBuf,
atime_secs: i64,
atime_nanos: u32,
mtime_secs: i64,
mtime_nanos: u32,
) -> FsResult<()> {
self.lutime_sync(&path, atime_secs, atime_nanos, mtime_secs, mtime_nanos)
}
fn write_file_sync(
&self,
path: &Path,
options: OpenOptions,
_access_check: Option<AccessCheckCb>,
data: &[u8],
) -> FsResult<()> {
let path = normalize_path(path);
let has_parent_dir = path
.parent()
.and_then(|parent| self.get_entry(parent))
.map(|e| matches!(*e, PathEntry::Dir))
.unwrap_or(false);
if !has_parent_dir {
return Err(FsError::Io(Error::new(
ErrorKind::NotFound,
"Parent directory does not exist",
)));
}
let mut entries = self.entries.lock();
let entry = entries.entry(path.clone());
match entry {
Entry::Occupied(mut entry) => {
if let PathEntry::File(existing_data) = &**entry.get() {
if options.create_new {
return Err(FsError::Io(Error::new(
ErrorKind::AlreadyExists,
"File already exists",
)));
}
if options.append {
let mut new_data = existing_data.clone();
new_data.extend_from_slice(data);
entry.insert(Arc::new(PathEntry::File(new_data)));
} else {
entry.insert(Arc::new(PathEntry::File(data.to_vec())));
}
Ok(())
} else {
Err(FsError::Io(Error::new(
ErrorKind::InvalidInput,
"Not a file",
)))
}
}
Entry::Vacant(entry) => {
entry.insert(Arc::new(PathEntry::File(data.to_vec())));
Ok(())
}
}
}
async fn write_file_async<'a>(
&'a self,
path: PathBuf,
options: OpenOptions,
access_check: Option<AccessCheckCb<'a>>,
data: Vec<u8>,
) -> FsResult<()> {
self.write_file_sync(&path, options, access_check, &data)
}
fn read_file_sync(
&self,
path: &Path,
_access_check: Option<AccessCheckCb>,
) -> FsResult<Cow<'static, [u8]>> {
let entry = self.get_entry(path);
match entry {
Some(entry) => match &*entry {
PathEntry::File(data) => Ok(Cow::Owned(data.clone())),
PathEntry::Dir => Err(FsError::Io(Error::new(
ErrorKind::InvalidInput,
"Is a directory",
))),
},
None => Err(FsError::Io(Error::new(ErrorKind::NotFound, "Not found"))),
}
}
async fn read_file_async<'a>(
&'a self,
path: PathBuf,
access_check: Option<AccessCheckCb<'a>>,
) -> FsResult<Cow<'static, [u8]>> {
self.read_file_sync(&path, access_check)
}
}

View file

@ -5,8 +5,6 @@ use std::borrow::Cow;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
use std::time::Duration;
use std::time::SystemTime;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
@ -14,8 +12,6 @@ use serde::Serialize;
use deno_io::fs::File; use deno_io::fs::File;
use deno_io::fs::FsResult; use deno_io::fs::FsResult;
use deno_io::fs::FsStat; use deno_io::fs::FsStat;
use sys_traits::FsFile;
use sys_traits::FsFileSetPermissions;
use crate::sync::MaybeSend; use crate::sync::MaybeSend;
use crate::sync::MaybeSync; use crate::sync::MaybeSync;
@ -75,7 +71,7 @@ pub enum FsFileType {
} }
/// WARNING: This is part of the public JS Deno API. /// WARNING: This is part of the public JS Deno API.
#[derive(Debug, Serialize)] #[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct FsDirEntry { pub struct FsDirEntry {
pub name: String, pub name: String,
@ -104,56 +100,6 @@ impl<T> AccessCheckFn for T where
{ {
} }
#[derive(Debug)]
pub struct FsStatSlim {
file_type: sys_traits::FileType,
modified: Result<SystemTime, std::io::Error>,
}
impl FsStatSlim {
pub fn from_std(metadata: &std::fs::Metadata) -> Self {
Self {
file_type: metadata.file_type().into(),
modified: metadata.modified(),
}
}
pub fn from_deno_fs_stat(data: &FsStat) -> Self {
FsStatSlim {
file_type: if data.is_file {
sys_traits::FileType::File
} else if data.is_directory {
sys_traits::FileType::Dir
} else if data.is_symlink {
sys_traits::FileType::Symlink
} else {
sys_traits::FileType::Unknown
},
modified: data
.mtime
.map(|ms| SystemTime::UNIX_EPOCH + Duration::from_millis(ms))
.ok_or_else(|| {
std::io::Error::new(std::io::ErrorKind::InvalidData, "No mtime")
}),
}
}
}
impl sys_traits::FsMetadataValue for FsStatSlim {
#[inline]
fn file_type(&self) -> sys_traits::FileType {
self.file_type
}
fn modified(&self) -> Result<SystemTime, std::io::Error> {
self
.modified
.as_ref()
.copied()
.map_err(|err| std::io::Error::new(err.kind(), err.to_string()))
}
}
pub type AccessCheckCb<'a> = &'a mut (dyn AccessCheckFn + 'a); pub type AccessCheckCb<'a> = &'a mut (dyn AccessCheckFn + 'a);
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
@ -415,289 +361,3 @@ fn string_from_utf8_lossy(buf: Vec<u8>) -> String {
Cow::Borrowed(_) => unsafe { String::from_utf8_unchecked(buf) }, Cow::Borrowed(_) => unsafe { String::from_utf8_unchecked(buf) },
} }
} }
// todo(dsherret): this is temporary. Instead of using the `FileSystem` trait implementation
// in the CLI, the CLI should instead create it's own file system using `sys_traits` traits
// then that can implement the `FileSystem` trait. Then this `FileSystem` trait can stay here
// for use only for `ext/fs` and not the entire CLI.
#[derive(Debug, Clone)]
pub struct FsSysTraitsAdapter(pub FileSystemRc);
impl FsSysTraitsAdapter {
pub fn new_real() -> Self {
Self(crate::sync::new_rc(crate::RealFs))
}
}
impl sys_traits::BaseFsHardLink for FsSysTraitsAdapter {
#[inline]
fn base_fs_hard_link(&self, src: &Path, dst: &Path) -> std::io::Result<()> {
self
.0
.link_sync(src, dst)
.map_err(|err| err.into_io_error())
}
}
impl sys_traits::BaseFsRead for FsSysTraitsAdapter {
#[inline]
fn base_fs_read(&self, path: &Path) -> std::io::Result<Cow<'static, [u8]>> {
self
.0
.read_file_sync(path, None)
.map_err(|err| err.into_io_error())
}
}
#[derive(Debug)]
pub struct FsSysTraitsAdapterReadDirEntry {
path: PathBuf,
entry: FsDirEntry,
}
impl sys_traits::FsDirEntry for FsSysTraitsAdapterReadDirEntry {
type Metadata = FsStatSlim;
fn file_name(&self) -> Cow<std::ffi::OsStr> {
Cow::Borrowed(self.entry.name.as_ref())
}
fn file_type(&self) -> std::io::Result<sys_traits::FileType> {
if self.entry.is_file {
Ok(sys_traits::FileType::File)
} else if self.entry.is_directory {
Ok(sys_traits::FileType::Dir)
} else if self.entry.is_symlink {
Ok(sys_traits::FileType::Symlink)
} else {
Ok(sys_traits::FileType::Unknown)
}
}
fn metadata(&self) -> std::io::Result<Self::Metadata> {
Ok(FsStatSlim {
file_type: self.file_type().unwrap(),
modified: Err(std::io::Error::new(
std::io::ErrorKind::Other,
"not supported",
)),
})
}
fn path(&self) -> Cow<Path> {
Cow::Borrowed(&self.path)
}
}
impl sys_traits::BaseFsReadDir for FsSysTraitsAdapter {
type ReadDirEntry = FsSysTraitsAdapterReadDirEntry;
fn base_fs_read_dir(
&self,
path: &Path,
) -> std::io::Result<
Box<dyn Iterator<Item = std::io::Result<Self::ReadDirEntry>>>,
> {
// todo(dsherret): needs to actually be iterable and not allocate a vector
let entries = self
.0
.read_dir_sync(path)
.map_err(|err| err.into_io_error())?;
let parent_dir = path.to_path_buf();
Ok(Box::new(entries.into_iter().map(move |entry| {
Ok(FsSysTraitsAdapterReadDirEntry {
path: parent_dir.join(&entry.name),
entry,
})
})))
}
}
impl sys_traits::BaseFsCanonicalize for FsSysTraitsAdapter {
#[inline]
fn base_fs_canonicalize(&self, path: &Path) -> std::io::Result<PathBuf> {
self
.0
.realpath_sync(path)
.map_err(|err| err.into_io_error())
}
}
impl sys_traits::BaseFsMetadata for FsSysTraitsAdapter {
type Metadata = FsStatSlim;
#[inline]
fn base_fs_metadata(&self, path: &Path) -> std::io::Result<Self::Metadata> {
self
.0
.stat_sync(path)
.map(|data| FsStatSlim::from_deno_fs_stat(&data))
.map_err(|err| err.into_io_error())
}
#[inline]
fn base_fs_symlink_metadata(
&self,
path: &Path,
) -> std::io::Result<Self::Metadata> {
self
.0
.lstat_sync(path)
.map(|data| FsStatSlim::from_deno_fs_stat(&data))
.map_err(|err| err.into_io_error())
}
}
impl sys_traits::BaseFsCreateDir for FsSysTraitsAdapter {
#[inline]
fn base_fs_create_dir(
&self,
path: &Path,
options: &sys_traits::CreateDirOptions,
) -> std::io::Result<()> {
self
.0
.mkdir_sync(path, options.recursive, options.mode)
.map_err(|err| err.into_io_error())
}
}
impl sys_traits::BaseFsRemoveFile for FsSysTraitsAdapter {
#[inline]
fn base_fs_remove_file(&self, path: &Path) -> std::io::Result<()> {
self
.0
.remove_sync(path, false)
.map_err(|err| err.into_io_error())
}
}
impl sys_traits::BaseFsRename for FsSysTraitsAdapter {
#[inline]
fn base_fs_rename(&self, from: &Path, to: &Path) -> std::io::Result<()> {
self
.0
.rename_sync(from, to)
.map_err(|err| err.into_io_error())
}
}
pub struct FsFileAdapter(pub Rc<dyn File>);
impl FsFile for FsFileAdapter {}
impl FsFileSetPermissions for FsFileAdapter {
#[inline]
fn fs_file_set_permissions(&mut self, mode: u32) -> std::io::Result<()> {
if cfg!(windows) {
Ok(()) // ignore
} else {
self
.0
.clone()
.chmod_sync(mode)
.map_err(|err| err.into_io_error())
}
}
}
impl std::io::Read for FsFileAdapter {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self
.0
.clone()
.read_sync(buf)
.map_err(|err| err.into_io_error())
}
}
impl std::io::Seek for FsFileAdapter {
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
self
.0
.clone()
.seek_sync(pos)
.map_err(|err| err.into_io_error())
}
}
impl std::io::Write for FsFileAdapter {
#[inline]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self
.0
.clone()
.write_sync(buf)
.map_err(|err| err.into_io_error())
}
#[inline]
fn flush(&mut self) -> std::io::Result<()> {
self
.0
.clone()
.sync_sync()
.map_err(|err| err.into_io_error())
}
}
impl sys_traits::BaseFsOpen for FsSysTraitsAdapter {
type File = FsFileAdapter;
fn base_fs_open(
&self,
path: &Path,
options: &sys_traits::OpenOptions,
) -> std::io::Result<Self::File> {
self
.0
.open_sync(
path,
OpenOptions {
read: options.read,
write: options.write,
create: options.create,
truncate: options.truncate,
append: options.append,
create_new: options.create_new,
mode: options.mode,
},
None,
)
.map(FsFileAdapter)
.map_err(|err| err.into_io_error())
}
}
impl sys_traits::SystemRandom for FsSysTraitsAdapter {
#[inline]
fn sys_random(&self, buf: &mut [u8]) -> std::io::Result<()> {
getrandom::getrandom(buf).map_err(|err| {
std::io::Error::new(std::io::ErrorKind::Other, err.to_string())
})
}
}
impl sys_traits::SystemTimeNow for FsSysTraitsAdapter {
#[inline]
fn sys_time_now(&self) -> SystemTime {
SystemTime::now()
}
}
impl sys_traits::ThreadSleep for FsSysTraitsAdapter {
#[inline]
fn thread_sleep(&self, dur: Duration) {
std::thread::sleep(dur);
}
}
impl sys_traits::BaseEnvVar for FsSysTraitsAdapter {
fn base_env_var_os(
&self,
key: &std::ffi::OsStr,
) -> Option<std::ffi::OsString> {
std::env::var_os(key)
}
}

View file

@ -1,25 +1,20 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
mod in_memory_fs;
mod interface; mod interface;
mod ops; mod ops;
mod std_fs; mod std_fs;
pub mod sync; pub mod sync;
pub use crate::in_memory_fs::InMemoryFs;
pub use crate::interface::AccessCheckCb; pub use crate::interface::AccessCheckCb;
pub use crate::interface::AccessCheckFn; pub use crate::interface::AccessCheckFn;
pub use crate::interface::FileSystem; pub use crate::interface::FileSystem;
pub use crate::interface::FileSystemRc; pub use crate::interface::FileSystemRc;
pub use crate::interface::FsDirEntry; pub use crate::interface::FsDirEntry;
pub use crate::interface::FsFileType; pub use crate::interface::FsFileType;
pub use crate::interface::FsStatSlim;
pub use crate::interface::FsSysTraitsAdapter;
pub use crate::interface::OpenOptions; pub use crate::interface::OpenOptions;
pub use crate::ops::FsOpsError; pub use crate::ops::FsOpsError;
pub use crate::ops::FsOpsErrorKind; pub use crate::ops::FsOpsErrorKind;
pub use crate::ops::OperationError; pub use crate::ops::OperationError;
pub use crate::ops::V8MaybeStaticStr;
pub use crate::std_fs::RealFs; pub use crate::std_fs::RealFs;
pub use crate::sync::MaybeSend; pub use crate::sync::MaybeSend;
pub use crate::sync::MaybeSync; pub use crate::sync::MaybeSync;

View file

@ -19,7 +19,6 @@ use crate::FsPermissions;
use crate::OpenOptions; use crate::OpenOptions;
use boxed_error::Boxed; use boxed_error::Boxed;
use deno_core::op2; use deno_core::op2;
use deno_core::v8;
use deno_core::CancelFuture; use deno_core::CancelFuture;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::FastString; use deno_core::FastString;
@ -27,7 +26,6 @@ use deno_core::JsBuffer;
use deno_core::OpState; use deno_core::OpState;
use deno_core::ResourceId; use deno_core::ResourceId;
use deno_core::ToJsBuffer; use deno_core::ToJsBuffer;
use deno_core::ToV8;
use deno_io::fs::FileResource; use deno_io::fs::FileResource;
use deno_io::fs::FsError; use deno_io::fs::FsError;
use deno_io::fs::FsStat; use deno_io::fs::FsStat;
@ -1384,51 +1382,12 @@ where
Ok(buf.into_owned().into_boxed_slice().into()) Ok(buf.into_owned().into_boxed_slice().into())
} }
// todo(https://github.com/denoland/deno_core/pull/986): remove
// when upgrading deno_core
#[derive(Debug)]
pub struct FastStringV8AllocationError;
impl std::error::Error for FastStringV8AllocationError {}
impl std::fmt::Display for FastStringV8AllocationError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"failed to allocate string; buffer exceeds maximum length"
)
}
}
/// Maintains a static reference to the string if possible.
pub struct V8MaybeStaticStr(pub Cow<'static, str>);
impl<'s> ToV8<'s> for V8MaybeStaticStr {
type Error = FastStringV8AllocationError;
#[inline]
fn to_v8(
self,
scope: &mut v8::HandleScope<'s>,
) -> Result<v8::Local<'s, v8::Value>, Self::Error> {
Ok(
match self.0 {
Cow::Borrowed(text) => FastString::from_static(text),
Cow::Owned(value) => value.into(),
}
.v8_string(scope)
.map_err(|_| FastStringV8AllocationError)?
.into(),
)
}
}
#[op2(stack_trace)] #[op2(stack_trace)]
#[to_v8] #[to_v8]
pub fn op_fs_read_file_text_sync<P>( pub fn op_fs_read_file_text_sync<P>(
state: &mut OpState, state: &mut OpState,
#[string] path: String, #[string] path: String,
) -> Result<V8MaybeStaticStr, FsOpsError> ) -> Result<FastString, FsOpsError>
where where
P: FsPermissions + 'static, P: FsPermissions + 'static,
{ {
@ -1440,7 +1399,10 @@ where
let str = fs let str = fs
.read_text_file_lossy_sync(&path, Some(&mut access_check)) .read_text_file_lossy_sync(&path, Some(&mut access_check))
.map_err(|error| map_permission_error("readfile", error, &path))?; .map_err(|error| map_permission_error("readfile", error, &path))?;
Ok(V8MaybeStaticStr(str)) Ok(match str {
Cow::Borrowed(text) => FastString::from_static(text),
Cow::Owned(value) => value.into(),
})
} }
#[op2(async, stack_trace)] #[op2(async, stack_trace)]
@ -1449,7 +1411,7 @@ pub async fn op_fs_read_file_text_async<P>(
state: Rc<RefCell<OpState>>, state: Rc<RefCell<OpState>>,
#[string] path: String, #[string] path: String,
#[smi] cancel_rid: Option<ResourceId>, #[smi] cancel_rid: Option<ResourceId>,
) -> Result<V8MaybeStaticStr, FsOpsError> ) -> Result<FastString, FsOpsError>
where where
P: FsPermissions + 'static, P: FsPermissions + 'static,
{ {
@ -1483,7 +1445,10 @@ where
.map_err(|error| map_permission_error("readfile", error, &path))? .map_err(|error| map_permission_error("readfile", error, &path))?
}; };
Ok(V8MaybeStaticStr(str)) Ok(match str {
Cow::Borrowed(text) => FastString::from_static(text),
Cow::Owned(value) => value.into(),
})
} }
fn to_seek_from(offset: i64, whence: i32) -> Result<SeekFrom, FsOpsError> { fn to_seek_from(offset: i64, whence: i32) -> Result<SeekFrom, FsOpsError> {

View file

@ -26,7 +26,7 @@ use crate::interface::FsFileType;
use crate::FileSystem; use crate::FileSystem;
use crate::OpenOptions; use crate::OpenOptions;
#[derive(Debug, Clone)] #[derive(Debug, Default, Clone)]
pub struct RealFs; pub struct RealFs;
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]

View file

@ -14,7 +14,7 @@ description = "Node compatibility for Deno"
path = "lib.rs" path = "lib.rs"
[features] [features]
sync_fs = ["deno_package_json/sync", "node_resolver/sync"] sync_fs = ["deno_fs/sync_fs", "deno_package_json/sync", "node_resolver/sync"]
[dependencies] [dependencies]
aead-gcm-stream = "0.4" aead-gcm-stream = "0.4"
@ -93,6 +93,7 @@ simd-json = "0.14.0"
sm3 = "0.4.2" sm3 = "0.4.2"
spki.workspace = true spki.workspace = true
stable_deref_trait = "1.2.0" stable_deref_trait = "1.2.0"
sys_traits = { workspace = true, features = ["real"] }
thiserror.workspace = true thiserror.workspace = true
tokio.workspace = true tokio.workspace = true
tokio-eld = "0.2" tokio-eld = "0.2"

View file

@ -14,10 +14,10 @@ use deno_core::url::Url;
#[allow(unused_imports)] #[allow(unused_imports)]
use deno_core::v8; use deno_core::v8;
use deno_core::v8::ExternalReference; use deno_core::v8::ExternalReference;
use deno_fs::FsSysTraitsAdapter;
use node_resolver::errors::ClosestPkgJsonError; use node_resolver::errors::ClosestPkgJsonError;
use node_resolver::IsBuiltInNodeModuleChecker; use node_resolver::IsBuiltInNodeModuleChecker;
use node_resolver::NpmPackageFolderResolverRc; use node_resolver::NpmPackageFolderResolverRc;
use node_resolver::PackageJsonResolverRc;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
extern crate libz_sys as zlib; extern crate libz_sys as zlib;
@ -185,16 +185,17 @@ fn op_node_build_os() -> String {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct NodeExtInitServices { pub struct NodeExtInitServices<TSys: ExtNodeSys> {
pub node_require_loader: NodeRequireLoaderRc, pub node_require_loader: NodeRequireLoaderRc,
pub node_resolver: NodeResolverRc, pub node_resolver: NodeResolverRc<TSys>,
pub npm_resolver: NpmPackageFolderResolverRc, pub npm_resolver: NpmPackageFolderResolverRc,
pub pkg_json_resolver: PackageJsonResolverRc, pub pkg_json_resolver: PackageJsonResolverRc<TSys>,
pub sys: TSys,
} }
deno_core::extension!(deno_node, deno_core::extension!(deno_node,
deps = [ deno_io, deno_fs ], deps = [ deno_io, deno_fs ],
parameters = [P: NodePermissions], parameters = [P: NodePermissions, TSys: ExtNodeSys],
ops = [ ops = [
ops::blocklist::op_socket_address_parse, ops::blocklist::op_socket_address_parse,
ops::blocklist::op_socket_address_get_serialization, ops::blocklist::op_socket_address_get_serialization,
@ -392,29 +393,29 @@ deno_core::extension!(deno_node,
op_node_build_os, op_node_build_os,
ops::require::op_require_can_parse_as_esm, ops::require::op_require_can_parse_as_esm,
ops::require::op_require_init_paths, ops::require::op_require_init_paths,
ops::require::op_require_node_module_paths<P>, ops::require::op_require_node_module_paths<P, TSys>,
ops::require::op_require_proxy_path, ops::require::op_require_proxy_path,
ops::require::op_require_is_deno_dir_package, ops::require::op_require_is_deno_dir_package<TSys>,
ops::require::op_require_resolve_deno_dir, ops::require::op_require_resolve_deno_dir,
ops::require::op_require_is_maybe_cjs, ops::require::op_require_is_maybe_cjs,
ops::require::op_require_is_request_relative, ops::require::op_require_is_request_relative,
ops::require::op_require_resolve_lookup_paths, ops::require::op_require_resolve_lookup_paths,
ops::require::op_require_try_self_parent_path<P>, ops::require::op_require_try_self_parent_path<P, TSys>,
ops::require::op_require_try_self<P>, ops::require::op_require_try_self<P, TSys>,
ops::require::op_require_real_path<P>, ops::require::op_require_real_path<P, TSys>,
ops::require::op_require_path_is_absolute, ops::require::op_require_path_is_absolute,
ops::require::op_require_path_dirname, ops::require::op_require_path_dirname,
ops::require::op_require_stat<P>, ops::require::op_require_stat<P, TSys>,
ops::require::op_require_path_resolve, ops::require::op_require_path_resolve,
ops::require::op_require_path_basename, ops::require::op_require_path_basename,
ops::require::op_require_read_file<P>, ops::require::op_require_read_file<P>,
ops::require::op_require_as_file_path, ops::require::op_require_as_file_path,
ops::require::op_require_resolve_exports<P>, ops::require::op_require_resolve_exports<P, TSys>,
ops::require::op_require_read_package_scope<P>, ops::require::op_require_read_package_scope<P, TSys>,
ops::require::op_require_package_imports_resolve<P>, ops::require::op_require_package_imports_resolve<P, TSys>,
ops::require::op_require_break_on_next_statement, ops::require::op_require_break_on_next_statement,
ops::util::op_node_guess_handle_type, ops::util::op_node_guess_handle_type,
ops::worker_threads::op_worker_threads_filename<P>, ops::worker_threads::op_worker_threads_filename<P, TSys>,
ops::ipc::op_node_child_ipc_pipe, ops::ipc::op_node_child_ipc_pipe,
ops::ipc::op_node_ipc_write, ops::ipc::op_node_ipc_write,
ops::ipc::op_node_ipc_read, ops::ipc::op_node_ipc_read,
@ -680,13 +681,14 @@ deno_core::extension!(deno_node,
"node:zlib" = "zlib.ts", "node:zlib" = "zlib.ts",
], ],
options = { options = {
maybe_init: Option<NodeExtInitServices>, maybe_init: Option<NodeExtInitServices<TSys>>,
fs: deno_fs::FileSystemRc, fs: deno_fs::FileSystemRc,
}, },
state = |state, options| { state = |state, options| {
state.put(options.fs.clone()); state.put(options.fs.clone());
if let Some(init) = &options.maybe_init { if let Some(init) = &options.maybe_init {
state.put(init.sys.clone());
state.put(init.node_require_loader.clone()); state.put(init.node_require_loader.clone());
state.put(init.node_resolver.clone()); state.put(init.node_resolver.clone());
state.put(init.npm_resolver.clone()); state.put(init.npm_resolver.clone());
@ -820,18 +822,22 @@ impl IsBuiltInNodeModuleChecker for RealIsBuiltInNodeModuleChecker {
} }
} }
pub type NodeResolver = node_resolver::NodeResolver< pub trait ExtNodeSys:
RealIsBuiltInNodeModuleChecker, sys_traits::BaseFsCanonicalize
FsSysTraitsAdapter, + sys_traits::BaseFsMetadata
>; + sys_traits::BaseFsRead
+ sys_traits::EnvCurrentDir
+ Clone
{
}
impl ExtNodeSys for sys_traits::impls::RealSys {}
pub type NodeResolver<TSys> =
node_resolver::NodeResolver<RealIsBuiltInNodeModuleChecker, TSys>;
#[allow(clippy::disallowed_types)] #[allow(clippy::disallowed_types)]
pub type NodeResolverRc = deno_fs::sync::MaybeArc<NodeResolver>; pub type NodeResolverRc<TSys> = deno_fs::sync::MaybeArc<NodeResolver<TSys>>;
pub type PackageJsonResolver =
node_resolver::PackageJsonResolver<FsSysTraitsAdapter>;
#[allow(clippy::disallowed_types)] #[allow(clippy::disallowed_types)]
pub type PackageJsonResolverRc = deno_fs::sync::MaybeArc<
node_resolver::PackageJsonResolver<FsSysTraitsAdapter>,
>;
pub fn create_host_defined_options<'s>( pub fn create_host_defined_options<'s>(
scope: &mut v8::HandleScope<'s>, scope: &mut v8::HandleScope<'s>,

View file

@ -1,14 +1,19 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use std::borrow::Cow;
use std::cell::RefCell;
use std::path::Path;
use std::path::PathBuf;
use std::rc::Rc;
use boxed_error::Boxed; use boxed_error::Boxed;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op2; use deno_core::op2;
use deno_core::url::Url; use deno_core::url::Url;
use deno_core::v8; use deno_core::v8;
use deno_core::FastString;
use deno_core::JsRuntimeInspector; use deno_core::JsRuntimeInspector;
use deno_core::OpState; use deno_core::OpState;
use deno_fs::FileSystemRc;
use deno_fs::V8MaybeStaticStr;
use deno_package_json::PackageJsonRc; use deno_package_json::PackageJsonRc;
use deno_path_util::normalize_path; use deno_path_util::normalize_path;
use deno_path_util::url_from_file_path; use deno_path_util::url_from_file_path;
@ -17,12 +22,11 @@ use node_resolver::errors::ClosestPkgJsonError;
use node_resolver::NodeResolutionKind; use node_resolver::NodeResolutionKind;
use node_resolver::ResolutionMode; use node_resolver::ResolutionMode;
use node_resolver::REQUIRE_CONDITIONS; use node_resolver::REQUIRE_CONDITIONS;
use std::borrow::Cow; use sys_traits::FsCanonicalize;
use std::cell::RefCell; use sys_traits::FsMetadata;
use std::path::Path; use sys_traits::FsMetadataValue;
use std::path::PathBuf;
use std::rc::Rc;
use crate::ExtNodeSys;
use crate::NodePermissions; use crate::NodePermissions;
use crate::NodeRequireLoaderRc; use crate::NodeRequireLoaderRc;
use crate::NodeResolverRc; use crate::NodeResolverRc;
@ -68,11 +72,11 @@ pub enum RequireErrorKind {
#[error(transparent)] #[error(transparent)]
UrlConversion(#[from] deno_path_util::PathToUrlError), UrlConversion(#[from] deno_path_util::PathToUrlError),
#[error(transparent)] #[error(transparent)]
Fs(#[from] deno_io::fs::FsError), Fs(#[from] std::io::Error),
#[error(transparent)] #[error(transparent)]
ReadModule(deno_core::error::AnyError), ReadModule(deno_core::error::AnyError),
#[error("Unable to get CWD: {0}")] #[error("Unable to get CWD: {0}")]
UnableToGetCwd(deno_io::fs::FsError), UnableToGetCwd(std::io::Error),
} }
#[op2] #[op2]
@ -128,19 +132,21 @@ pub fn op_require_init_paths() -> Vec<String> {
#[op2(stack_trace)] #[op2(stack_trace)]
#[serde] #[serde]
pub fn op_require_node_module_paths<P>( pub fn op_require_node_module_paths<
P: NodePermissions + 'static,
TSys: ExtNodeSys + 'static,
>(
state: &mut OpState, state: &mut OpState,
#[string] from: String, #[string] from: String,
) -> Result<Vec<String>, RequireError> ) -> Result<Vec<String>, RequireError> {
where let sys = state.borrow::<TSys>();
P: NodePermissions + 'static,
{
let fs = state.borrow::<FileSystemRc>();
// Guarantee that "from" is absolute. // Guarantee that "from" is absolute.
let from = if from.starts_with("file:///") { let from = if from.starts_with("file:///") {
url_to_file_path(&Url::parse(&from)?)? url_to_file_path(&Url::parse(&from)?)?
} else { } else {
let current_dir = &fs.cwd().map_err(RequireErrorKind::UnableToGetCwd)?; let current_dir = &sys
.env_current_dir()
.map_err(RequireErrorKind::UnableToGetCwd)?;
normalize_path(current_dir.join(from)) normalize_path(current_dir.join(from))
}; };
@ -238,11 +244,11 @@ pub fn op_require_resolve_deno_dir(
} }
#[op2(fast)] #[op2(fast)]
pub fn op_require_is_deno_dir_package( pub fn op_require_is_deno_dir_package<TSys: ExtNodeSys + 'static>(
state: &mut OpState, state: &mut OpState,
#[string] path: String, #[string] path: String,
) -> bool { ) -> bool {
let resolver = state.borrow::<NodeResolverRc>(); let resolver = state.borrow::<NodeResolverRc<TSys>>();
match deno_path_util::url_from_file_path(&PathBuf::from(path)) { match deno_path_util::url_from_file_path(&PathBuf::from(path)) {
Ok(specifier) => resolver.in_npm_package(&specifier), Ok(specifier) => resolver.in_npm_package(&specifier),
Err(_) => false, Err(_) => false,
@ -297,18 +303,18 @@ pub fn op_require_path_is_absolute(#[string] p: String) -> bool {
} }
#[op2(fast, stack_trace)] #[op2(fast, stack_trace)]
pub fn op_require_stat<P>( pub fn op_require_stat<
P: NodePermissions + 'static,
TSys: ExtNodeSys + 'static,
>(
state: &mut OpState, state: &mut OpState,
#[string] path: String, #[string] path: String,
) -> Result<i32, deno_core::error::AnyError> ) -> Result<i32, deno_core::error::AnyError> {
where
P: NodePermissions + 'static,
{
let path = PathBuf::from(path); let path = PathBuf::from(path);
let path = ensure_read_permission::<P>(state, &path)?; let path = ensure_read_permission::<P>(state, &path)?;
let fs = state.borrow::<FileSystemRc>(); let sys = state.borrow::<TSys>();
if let Ok(metadata) = fs.stat_sync(&path) { if let Ok(metadata) = sys.fs_metadata(&path) {
if metadata.is_file { if metadata.file_type().is_file() {
return Ok(0); return Ok(0);
} else { } else {
return Ok(1); return Ok(1);
@ -320,19 +326,19 @@ where
#[op2(stack_trace)] #[op2(stack_trace)]
#[string] #[string]
pub fn op_require_real_path<P>( pub fn op_require_real_path<
P: NodePermissions + 'static,
TSys: ExtNodeSys + 'static,
>(
state: &mut OpState, state: &mut OpState,
#[string] request: String, #[string] request: String,
) -> Result<String, RequireError> ) -> Result<String, RequireError> {
where
P: NodePermissions + 'static,
{
let path = PathBuf::from(request); let path = PathBuf::from(request);
let path = ensure_read_permission::<P>(state, &path) let path = ensure_read_permission::<P>(state, &path)
.map_err(RequireErrorKind::Permission)?; .map_err(RequireErrorKind::Permission)?;
let fs = state.borrow::<FileSystemRc>(); let sys = state.borrow::<TSys>();
let canonicalized_path = let canonicalized_path =
deno_path_util::strip_unc_prefix(fs.realpath_sync(&path)?); deno_path_util::strip_unc_prefix(sys.fs_canonicalize(&path)?);
Ok(canonicalized_path.to_string_lossy().into_owned()) Ok(canonicalized_path.to_string_lossy().into_owned())
} }
@ -384,15 +390,15 @@ pub fn op_require_path_basename(
#[op2(stack_trace)] #[op2(stack_trace)]
#[string] #[string]
pub fn op_require_try_self_parent_path<P>( pub fn op_require_try_self_parent_path<
P: NodePermissions + 'static,
TSys: ExtNodeSys + 'static,
>(
state: &mut OpState, state: &mut OpState,
has_parent: bool, has_parent: bool,
#[string] maybe_parent_filename: Option<String>, #[string] maybe_parent_filename: Option<String>,
#[string] maybe_parent_id: Option<String>, #[string] maybe_parent_id: Option<String>,
) -> Result<Option<String>, deno_core::error::AnyError> ) -> Result<Option<String>, deno_core::error::AnyError> {
where
P: NodePermissions + 'static,
{
if !has_parent { if !has_parent {
return Ok(None); return Ok(None);
} }
@ -403,8 +409,8 @@ where
if let Some(parent_id) = maybe_parent_id { if let Some(parent_id) = maybe_parent_id {
if parent_id == "<repl>" || parent_id == "internal/preload" { if parent_id == "<repl>" || parent_id == "internal/preload" {
let fs = state.borrow::<FileSystemRc>(); let sys = state.borrow::<TSys>();
if let Ok(cwd) = fs.cwd() { if let Ok(cwd) = sys.env_current_dir() {
let cwd = ensure_read_permission::<P>(state, &cwd)?; let cwd = ensure_read_permission::<P>(state, &cwd)?;
return Ok(Some(cwd.to_string_lossy().into_owned())); return Ok(Some(cwd.to_string_lossy().into_owned()));
} }
@ -415,19 +421,19 @@ where
#[op2(stack_trace)] #[op2(stack_trace)]
#[string] #[string]
pub fn op_require_try_self<P>( pub fn op_require_try_self<
P: NodePermissions + 'static,
TSys: ExtNodeSys + 'static,
>(
state: &mut OpState, state: &mut OpState,
#[string] parent_path: Option<String>, #[string] parent_path: Option<String>,
#[string] request: String, #[string] request: String,
) -> Result<Option<String>, RequireError> ) -> Result<Option<String>, RequireError> {
where
P: NodePermissions + 'static,
{
if parent_path.is_none() { if parent_path.is_none() {
return Ok(None); return Ok(None);
} }
let pkg_json_resolver = state.borrow::<PackageJsonResolverRc>(); let pkg_json_resolver = state.borrow::<PackageJsonResolverRc<TSys>>();
let pkg = pkg_json_resolver let pkg = pkg_json_resolver
.get_closest_package_json_from_file_path(&PathBuf::from( .get_closest_package_json_from_file_path(&PathBuf::from(
parent_path.unwrap(), parent_path.unwrap(),
@ -459,7 +465,7 @@ where
let referrer = deno_core::url::Url::from_file_path(&pkg.path).unwrap(); let referrer = deno_core::url::Url::from_file_path(&pkg.path).unwrap();
if let Some(exports) = &pkg.exports { if let Some(exports) = &pkg.exports {
let node_resolver = state.borrow::<NodeResolverRc>(); let node_resolver = state.borrow::<NodeResolverRc<TSys>>();
let r = node_resolver.package_exports_resolve( let r = node_resolver.package_exports_resolve(
&pkg.path, &pkg.path,
&expansion, &expansion,
@ -484,7 +490,7 @@ where
pub fn op_require_read_file<P>( pub fn op_require_read_file<P>(
state: &mut OpState, state: &mut OpState,
#[string] file_path: String, #[string] file_path: String,
) -> Result<V8MaybeStaticStr, RequireError> ) -> Result<FastString, RequireError>
where where
P: NodePermissions + 'static, P: NodePermissions + 'static,
{ {
@ -495,7 +501,10 @@ where
let loader = state.borrow::<NodeRequireLoaderRc>(); let loader = state.borrow::<NodeRequireLoaderRc>();
loader loader
.load_text_file_lossy(&file_path) .load_text_file_lossy(&file_path)
.map(V8MaybeStaticStr) .map(|s| match s {
Cow::Borrowed(s) => FastString::from_static(s),
Cow::Owned(s) => s.into(),
})
.map_err(|e| RequireErrorKind::ReadModule(e).into_box()) .map_err(|e| RequireErrorKind::ReadModule(e).into_box())
} }
@ -513,7 +522,10 @@ pub fn op_require_as_file_path(#[string] file_or_url: String) -> String {
#[op2(stack_trace)] #[op2(stack_trace)]
#[string] #[string]
pub fn op_require_resolve_exports<P>( pub fn op_require_resolve_exports<
P: NodePermissions + 'static,
TSys: ExtNodeSys + 'static,
>(
state: &mut OpState, state: &mut OpState,
uses_local_node_modules_dir: bool, uses_local_node_modules_dir: bool,
#[string] modules_path_str: String, #[string] modules_path_str: String,
@ -521,13 +533,10 @@ pub fn op_require_resolve_exports<P>(
#[string] name: String, #[string] name: String,
#[string] expansion: String, #[string] expansion: String,
#[string] parent_path: String, #[string] parent_path: String,
) -> Result<Option<String>, RequireError> ) -> Result<Option<String>, RequireError> {
where let sys = state.borrow::<TSys>();
P: NodePermissions + 'static, let node_resolver = state.borrow::<NodeResolverRc<TSys>>();
{ let pkg_json_resolver = state.borrow::<PackageJsonResolverRc<TSys>>();
let fs = state.borrow::<FileSystemRc>();
let node_resolver = state.borrow::<NodeResolverRc>();
let pkg_json_resolver = state.borrow::<PackageJsonResolverRc>();
let modules_path = PathBuf::from(&modules_path_str); let modules_path = PathBuf::from(&modules_path_str);
let modules_specifier = deno_path_util::url_from_file_path(&modules_path)?; let modules_specifier = deno_path_util::url_from_file_path(&modules_path)?;
@ -538,7 +547,7 @@ where
} else { } else {
let mod_dir = let mod_dir =
path_resolve([modules_path_str.as_str(), name.as_str()].into_iter()); path_resolve([modules_path_str.as_str(), name.as_str()].into_iter());
if fs.is_dir_sync(&mod_dir) { if sys.fs_is_dir_no_err(&mod_dir) {
mod_dir mod_dir
} else { } else {
modules_path modules_path
@ -589,14 +598,14 @@ pub fn op_require_is_maybe_cjs(
#[op2(stack_trace)] #[op2(stack_trace)]
#[serde] #[serde]
pub fn op_require_read_package_scope<P>( pub fn op_require_read_package_scope<
P: NodePermissions + 'static,
TSys: ExtNodeSys + 'static,
>(
state: &mut OpState, state: &mut OpState,
#[string] package_json_path: String, #[string] package_json_path: String,
) -> Option<PackageJsonRc> ) -> Option<PackageJsonRc> {
where let pkg_json_resolver = state.borrow::<PackageJsonResolverRc<TSys>>();
P: NodePermissions + 'static,
{
let pkg_json_resolver = state.borrow::<PackageJsonResolverRc>();
let package_json_path = PathBuf::from(package_json_path); let package_json_path = PathBuf::from(package_json_path);
if package_json_path.file_name() != Some("package.json".as_ref()) { if package_json_path.file_name() != Some("package.json".as_ref()) {
// permissions: do not allow reading a non-package.json file // permissions: do not allow reading a non-package.json file
@ -610,18 +619,18 @@ where
#[op2(stack_trace)] #[op2(stack_trace)]
#[string] #[string]
pub fn op_require_package_imports_resolve<P>( pub fn op_require_package_imports_resolve<
P: NodePermissions + 'static,
TSys: ExtNodeSys + 'static,
>(
state: &mut OpState, state: &mut OpState,
#[string] referrer_filename: String, #[string] referrer_filename: String,
#[string] request: String, #[string] request: String,
) -> Result<Option<String>, RequireError> ) -> Result<Option<String>, RequireError> {
where
P: NodePermissions + 'static,
{
let referrer_path = PathBuf::from(&referrer_filename); let referrer_path = PathBuf::from(&referrer_filename);
let referrer_path = ensure_read_permission::<P>(state, &referrer_path) let referrer_path = ensure_read_permission::<P>(state, &referrer_path)
.map_err(RequireErrorKind::Permission)?; .map_err(RequireErrorKind::Permission)?;
let pkg_json_resolver = state.borrow::<PackageJsonResolverRc>(); let pkg_json_resolver = state.borrow::<PackageJsonResolverRc<TSys>>();
let Some(pkg) = pkg_json_resolver let Some(pkg) = pkg_json_resolver
.get_closest_package_json_from_file_path(&referrer_path)? .get_closest_package_json_from_file_path(&referrer_path)?
else { else {
@ -629,7 +638,7 @@ where
}; };
if pkg.imports.is_some() { if pkg.imports.is_some() {
let node_resolver = state.borrow::<NodeResolverRc>(); let node_resolver = state.borrow::<NodeResolverRc<TSys>>();
let referrer_url = Url::from_file_path(&referrer_filename).unwrap(); let referrer_url = Url::from_file_path(&referrer_filename).unwrap();
let url = node_resolver.package_imports_resolve( let url = node_resolver.package_imports_resolve(
&request, &request,

View file

@ -1,13 +1,16 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::op2;
use deno_core::url::Url;
use deno_core::OpState;
use deno_fs::FileSystemRc;
use std::borrow::Cow; use std::borrow::Cow;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use deno_core::op2;
use deno_core::url::Url;
use deno_core::OpState;
use sys_traits::FsCanonicalize;
use sys_traits::FsMetadata;
use crate::ExtNodeSys;
use crate::NodePermissions; use crate::NodePermissions;
use crate::NodeRequireLoaderRc; use crate::NodeRequireLoaderRc;
@ -41,19 +44,19 @@ pub enum WorkerThreadsFilenameError {
#[error("File not found [{0:?}]")] #[error("File not found [{0:?}]")]
FileNotFound(PathBuf), FileNotFound(PathBuf),
#[error(transparent)] #[error(transparent)]
Fs(#[from] deno_io::fs::FsError), Fs(#[from] std::io::Error),
} }
// todo(dsherret): we should remove this and do all this work inside op_create_worker // todo(dsherret): we should remove this and do all this work inside op_create_worker
#[op2(stack_trace)] #[op2(stack_trace)]
#[string] #[string]
pub fn op_worker_threads_filename<P>( pub fn op_worker_threads_filename<
P: NodePermissions + 'static,
TSys: ExtNodeSys + 'static,
>(
state: &mut OpState, state: &mut OpState,
#[string] specifier: String, #[string] specifier: String,
) -> Result<String, WorkerThreadsFilenameError> ) -> Result<String, WorkerThreadsFilenameError> {
where
P: NodePermissions + 'static,
{
if specifier.starts_with("data:") { if specifier.starts_with("data:") {
return Ok(specifier); return Ok(specifier);
} }
@ -66,9 +69,9 @@ where
} }
let path = ensure_read_permission::<P>(state, &path) let path = ensure_read_permission::<P>(state, &path)
.map_err(WorkerThreadsFilenameError::Permission)?; .map_err(WorkerThreadsFilenameError::Permission)?;
let fs = state.borrow::<FileSystemRc>(); let sys = state.borrow::<TSys>();
let canonicalized_path = let canonicalized_path =
deno_path_util::strip_unc_prefix(fs.realpath_sync(&path)?); deno_path_util::strip_unc_prefix(sys.fs_canonicalize(&path)?);
Url::from_file_path(canonicalized_path) Url::from_file_path(canonicalized_path)
.map_err(|_| WorkerThreadsFilenameError::UrlFromPathString)? .map_err(|_| WorkerThreadsFilenameError::UrlFromPathString)?
}; };
@ -77,8 +80,8 @@ where
.map_err(|_| WorkerThreadsFilenameError::UrlToPathString)?; .map_err(|_| WorkerThreadsFilenameError::UrlToPathString)?;
let url_path = ensure_read_permission::<P>(state, &url_path) let url_path = ensure_read_permission::<P>(state, &url_path)
.map_err(WorkerThreadsFilenameError::Permission)?; .map_err(WorkerThreadsFilenameError::Permission)?;
let fs = state.borrow::<FileSystemRc>(); let sys = state.borrow::<TSys>();
if !fs.exists_sync(&url_path) { if !sys.fs_exists_no_err(&url_path) {
return Err(WorkerThreadsFilenameError::FileNotFound( return Err(WorkerThreadsFilenameError::FileNotFound(
url_path.to_path_buf(), url_path.to_path_buf(),
)); ));

View file

@ -122,6 +122,7 @@ same-file = "1.0.6"
serde.workspace = true serde.workspace = true
signal-hook = "0.3.17" signal-hook = "0.3.17"
signal-hook-registry = "1.4.0" signal-hook-registry = "1.4.0"
sys_traits.workspace = true
tempfile.workspace = true tempfile.workspace = true
thiserror.workspace = true thiserror.workspace = true
tokio.workspace = true tokio.workspace = true

View file

@ -1157,7 +1157,7 @@ mod node {
WorkerThreadsFilenameError::UrlToPathString => "Error", WorkerThreadsFilenameError::UrlToPathString => "Error",
WorkerThreadsFilenameError::UrlToPath => "Error", WorkerThreadsFilenameError::UrlToPath => "Error",
WorkerThreadsFilenameError::FileNotFound(_) => "Error", WorkerThreadsFilenameError::FileNotFound(_) => "Error",
WorkerThreadsFilenameError::Fs(e) => super::get_fs_error(e), WorkerThreadsFilenameError::Fs(e) => super::get_io_error_class(e),
} }
} }
@ -1173,7 +1173,7 @@ mod node {
| UrlConversion(_) | UrlConversion(_)
| ReadModule(_) | ReadModule(_)
| PackageImportsResolve(_) => "Error", | PackageImportsResolve(_) => "Error",
Fs(e) | UnableToGetCwd(e) => super::get_fs_error(e), Fs(e) | UnableToGetCwd(e) => super::get_io_error_class(e),
} }
} }

View file

@ -37,11 +37,12 @@ async fn main() -> Result<(), AnyError> {
let main_module = ModuleSpecifier::from_file_path(js_path).unwrap(); let main_module = ModuleSpecifier::from_file_path(js_path).unwrap();
eprintln!("Running {main_module}..."); eprintln!("Running {main_module}...");
let fs = Arc::new(RealFs); let fs = Arc::new(RealFs);
let permission_desc_parser = let permission_desc_parser = Arc::new(
Arc::new(RuntimePermissionDescriptorParser::new(fs.clone())); RuntimePermissionDescriptorParser::new(sys_traits::impls::RealSys),
);
let mut worker = MainWorker::bootstrap_from_options( let mut worker = MainWorker::bootstrap_from_options(
main_module.clone(), main_module.clone(),
WorkerServiceOptions { WorkerServiceOptions::<sys_traits::impls::RealSys> {
module_loader: Rc::new(FsModuleLoader), module_loader: Rc::new(FsModuleLoader),
permissions: PermissionsContainer::allow_all(permission_desc_parser), permissions: PermissionsContainer::allow_all(permission_desc_parser),
blob_store: Default::default(), blob_store: Default::default(),

View file

@ -21,13 +21,17 @@ use deno_permissions::SysDescriptorParseError;
use deno_permissions::WriteDescriptor; use deno_permissions::WriteDescriptor;
#[derive(Debug)] #[derive(Debug)]
pub struct RuntimePermissionDescriptorParser { pub struct RuntimePermissionDescriptorParser<
fs: deno_fs::FileSystemRc, TSys: sys_traits::EnvCurrentDir + Send + Sync,
> {
sys: TSys,
} }
impl RuntimePermissionDescriptorParser { impl<TSys: sys_traits::EnvCurrentDir + Send + Sync>
pub fn new(fs: deno_fs::FileSystemRc) -> Self { RuntimePermissionDescriptorParser<TSys>
Self { fs } {
pub fn new(sys: TSys) -> Self {
Self { sys }
} }
fn resolve_from_cwd(&self, path: &str) -> Result<PathBuf, PathResolveError> { fn resolve_from_cwd(&self, path: &str) -> Result<PathBuf, PathResolveError> {
@ -45,14 +49,15 @@ impl RuntimePermissionDescriptorParser {
fn resolve_cwd(&self) -> Result<PathBuf, PathResolveError> { fn resolve_cwd(&self) -> Result<PathBuf, PathResolveError> {
self self
.fs .sys
.cwd() .env_current_dir()
.map_err(|e| PathResolveError::CwdResolve(e.into_io_error())) .map_err(PathResolveError::CwdResolve)
} }
} }
impl deno_permissions::PermissionDescriptorParser impl<TSys: sys_traits::EnvCurrentDir + Send + Sync + std::fmt::Debug>
for RuntimePermissionDescriptorParser deno_permissions::PermissionDescriptorParser
for RuntimePermissionDescriptorParser<TSys>
{ {
fn parse_read_descriptor( fn parse_read_descriptor(
&self, &self,
@ -151,16 +156,14 @@ impl deno_permissions::PermissionDescriptorParser
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::sync::Arc;
use deno_fs::RealFs;
use deno_permissions::PermissionDescriptorParser; use deno_permissions::PermissionDescriptorParser;
use super::*; use super::*;
#[test] #[test]
fn test_handle_empty_value() { fn test_handle_empty_value() {
let parser = RuntimePermissionDescriptorParser::new(Arc::new(RealFs)); let parser =
RuntimePermissionDescriptorParser::new(sys_traits::impls::RealSys);
assert!(parser.parse_read_descriptor("").is_err()); assert!(parser.parse_read_descriptor("").is_err());
assert!(parser.parse_write_descriptor("").is_err()); assert!(parser.parse_write_descriptor("").is_err());
assert!(parser.parse_env_descriptor("").is_err()); assert!(parser.parse_env_descriptor("").is_err());

View file

@ -306,7 +306,10 @@ pub fn create_runtime_snapshot(
), ),
deno_io::deno_io::init_ops_and_esm(Default::default()), deno_io::deno_io::init_ops_and_esm(Default::default()),
deno_fs::deno_fs::init_ops_and_esm::<Permissions>(fs.clone()), deno_fs::deno_fs::init_ops_and_esm::<Permissions>(fs.clone()),
deno_node::deno_node::init_ops_and_esm::<Permissions>(None, fs.clone()), deno_node::deno_node::init_ops_and_esm::<
Permissions,
sys_traits::impls::RealSys,
>(None, fs.clone()),
runtime::init_ops_and_esm(), runtime::init_ops_and_esm(),
ops::runtime::deno_runtime::init_ops("deno:runtime".parse().unwrap()), ops::runtime::deno_runtime::init_ops("deno:runtime".parse().unwrap()),
ops::worker_host::deno_worker_host::init_ops( ops::worker_host::deno_worker_host::init_ops(

View file

@ -33,6 +33,7 @@ use deno_fs::FileSystem;
use deno_http::DefaultHttpPropertyExtractor; use deno_http::DefaultHttpPropertyExtractor;
use deno_io::Stdio; use deno_io::Stdio;
use deno_kv::dynamic::MultiBackendDbHandler; use deno_kv::dynamic::MultiBackendDbHandler;
use deno_node::ExtNodeSys;
use deno_node::NodeExtInitServices; use deno_node::NodeExtInitServices;
use deno_permissions::PermissionsContainer; use deno_permissions::PermissionsContainer;
use deno_terminal::colors; use deno_terminal::colors;
@ -337,7 +338,7 @@ fn create_handles(
(internal_handle, external_handle) (internal_handle, external_handle)
} }
pub struct WebWorkerServiceOptions { pub struct WebWorkerServiceOptions<TExtNodeSys: ExtNodeSys + 'static> {
pub blob_store: Arc<BlobStore>, pub blob_store: Arc<BlobStore>,
pub broadcast_channel: InMemoryBroadcastChannel, pub broadcast_channel: InMemoryBroadcastChannel,
pub compiled_wasm_module_store: Option<CompiledWasmModuleStore>, pub compiled_wasm_module_store: Option<CompiledWasmModuleStore>,
@ -345,7 +346,7 @@ pub struct WebWorkerServiceOptions {
pub fs: Arc<dyn FileSystem>, pub fs: Arc<dyn FileSystem>,
pub maybe_inspector_server: Option<Arc<InspectorServer>>, pub maybe_inspector_server: Option<Arc<InspectorServer>>,
pub module_loader: Rc<dyn ModuleLoader>, pub module_loader: Rc<dyn ModuleLoader>,
pub node_services: Option<NodeExtInitServices>, pub node_services: Option<NodeExtInitServices<TExtNodeSys>>,
pub npm_process_state_provider: Option<NpmProcessStateProviderRc>, pub npm_process_state_provider: Option<NpmProcessStateProviderRc>,
pub permissions: PermissionsContainer, pub permissions: PermissionsContainer,
pub root_cert_store_provider: Option<Arc<dyn RootCertStoreProvider>>, pub root_cert_store_provider: Option<Arc<dyn RootCertStoreProvider>>,
@ -402,8 +403,8 @@ impl Drop for WebWorker {
} }
impl WebWorker { impl WebWorker {
pub fn bootstrap_from_options( pub fn bootstrap_from_options<TExtNodeSys: ExtNodeSys + 'static>(
services: WebWorkerServiceOptions, services: WebWorkerServiceOptions<TExtNodeSys>,
options: WebWorkerOptions, options: WebWorkerOptions,
) -> (Self, SendableWebWorkerHandle) { ) -> (Self, SendableWebWorkerHandle) {
let (mut worker, handle, bootstrap_options) = let (mut worker, handle, bootstrap_options) =
@ -412,8 +413,8 @@ impl WebWorker {
(worker, handle) (worker, handle)
} }
fn from_options( fn from_options<TExtNodeSys: ExtNodeSys + 'static>(
services: WebWorkerServiceOptions, services: WebWorkerServiceOptions<TExtNodeSys>,
mut options: WebWorkerOptions, mut options: WebWorkerOptions,
) -> (Self, SendableWebWorkerHandle, BootstrapOptions) { ) -> (Self, SendableWebWorkerHandle, BootstrapOptions) {
deno_core::extension!(deno_permissions_web_worker, deno_core::extension!(deno_permissions_web_worker,
@ -504,7 +505,7 @@ impl WebWorker {
deno_fs::deno_fs::init_ops_and_esm::<PermissionsContainer>( deno_fs::deno_fs::init_ops_and_esm::<PermissionsContainer>(
services.fs.clone(), services.fs.clone(),
), ),
deno_node::deno_node::init_ops_and_esm::<PermissionsContainer>( deno_node::deno_node::init_ops_and_esm::<PermissionsContainer, TExtNodeSys>(
services.node_services, services.node_services,
services.fs, services.fs,
), ),

View file

@ -39,6 +39,7 @@ use deno_fs::FileSystem;
use deno_http::DefaultHttpPropertyExtractor; use deno_http::DefaultHttpPropertyExtractor;
use deno_io::Stdio; use deno_io::Stdio;
use deno_kv::dynamic::MultiBackendDbHandler; use deno_kv::dynamic::MultiBackendDbHandler;
use deno_node::ExtNodeSys;
use deno_node::NodeExtInitServices; use deno_node::NodeExtInitServices;
use deno_permissions::PermissionsContainer; use deno_permissions::PermissionsContainer;
use deno_tls::RootCertStoreProvider; use deno_tls::RootCertStoreProvider;
@ -128,7 +129,7 @@ pub struct MainWorker {
dispatch_process_exit_event_fn_global: v8::Global<v8::Function>, dispatch_process_exit_event_fn_global: v8::Global<v8::Function>,
} }
pub struct WorkerServiceOptions { pub struct WorkerServiceOptions<TExtNodeSys: ExtNodeSys> {
pub blob_store: Arc<BlobStore>, pub blob_store: Arc<BlobStore>,
pub broadcast_channel: InMemoryBroadcastChannel, pub broadcast_channel: InMemoryBroadcastChannel,
pub feature_checker: Arc<FeatureChecker>, pub feature_checker: Arc<FeatureChecker>,
@ -139,7 +140,7 @@ pub struct WorkerServiceOptions {
/// If not provided runtime will error if code being /// If not provided runtime will error if code being
/// executed tries to load modules. /// executed tries to load modules.
pub module_loader: Rc<dyn ModuleLoader>, pub module_loader: Rc<dyn ModuleLoader>,
pub node_services: Option<NodeExtInitServices>, pub node_services: Option<NodeExtInitServices<TExtNodeSys>>,
pub npm_process_state_provider: Option<NpmProcessStateProviderRc>, pub npm_process_state_provider: Option<NpmProcessStateProviderRc>,
pub permissions: PermissionsContainer, pub permissions: PermissionsContainer,
pub root_cert_store_provider: Option<Arc<dyn RootCertStoreProvider>>, pub root_cert_store_provider: Option<Arc<dyn RootCertStoreProvider>>,
@ -304,9 +305,9 @@ pub fn create_op_metrics(
} }
impl MainWorker { impl MainWorker {
pub fn bootstrap_from_options( pub fn bootstrap_from_options<TExtNodeSys: ExtNodeSys + 'static>(
main_module: ModuleSpecifier, main_module: ModuleSpecifier,
services: WorkerServiceOptions, services: WorkerServiceOptions<TExtNodeSys>,
options: WorkerOptions, options: WorkerOptions,
) -> Self { ) -> Self {
let (mut worker, bootstrap_options) = let (mut worker, bootstrap_options) =
@ -315,9 +316,9 @@ impl MainWorker {
worker worker
} }
fn from_options( fn from_options<TExtNodeSys: ExtNodeSys + 'static>(
main_module: ModuleSpecifier, main_module: ModuleSpecifier,
services: WorkerServiceOptions, services: WorkerServiceOptions<TExtNodeSys>,
mut options: WorkerOptions, mut options: WorkerOptions,
) -> (Self, BootstrapOptions) { ) -> (Self, BootstrapOptions) {
deno_core::extension!(deno_permissions_worker, deno_core::extension!(deno_permissions_worker,
@ -417,7 +418,7 @@ impl MainWorker {
deno_fs::deno_fs::init_ops_and_esm::<PermissionsContainer>( deno_fs::deno_fs::init_ops_and_esm::<PermissionsContainer>(
services.fs.clone(), services.fs.clone(),
), ),
deno_node::deno_node::init_ops_and_esm::<PermissionsContainer>( deno_node::deno_node::init_ops_and_esm::<PermissionsContainer, TExtNodeSys>(
services.node_services, services.node_services,
services.fs, services.fs,
), ),