|
3 | 3 | pub mod bin_entries; |
4 | 4 | pub mod lifecycle_scripts; |
5 | 5 |
|
6 | | -use std::borrow::Cow; |
7 | | -use std::collections::HashMap; |
8 | | -use std::io::ErrorKind; |
9 | 6 | use std::path::Path; |
10 | 7 | use std::path::PathBuf; |
11 | | -use std::sync::Arc; |
12 | | -use std::sync::Mutex; |
13 | 8 |
|
14 | 9 | use async_trait::async_trait; |
15 | 10 | use deno_ast::ModuleSpecifier; |
16 | | -use deno_core::anyhow::Context; |
17 | 11 | use deno_core::error::AnyError; |
18 | | -use deno_core::futures; |
19 | | -use deno_core::futures::StreamExt; |
20 | 12 | use deno_npm::NpmPackageCacheFolderId; |
21 | 13 | use deno_npm::NpmPackageId; |
22 | | -use deno_npm::NpmResolutionPackage; |
23 | | -use deno_runtime::deno_node::NodePermissions; |
24 | 14 | use node_resolver::errors::PackageFolderResolveError; |
25 | | -use sys_traits::FsCanonicalize; |
26 | 15 |
|
27 | 16 | use super::super::PackageCaching; |
28 | | -use crate::npm::CliNpmTarballCache; |
29 | | -use crate::sys::CliSys; |
30 | 17 |
|
31 | 18 | /// Part of the resolution that interacts with the file system. |
32 | 19 | #[async_trait(?Send)] |
@@ -63,101 +50,4 @@ pub trait NpmPackageFsResolver: Send + Sync { |
63 | 50 | &self, |
64 | 51 | caching: PackageCaching<'a>, |
65 | 52 | ) -> Result<(), AnyError>; |
66 | | - |
67 | | - #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] |
68 | | - fn ensure_read_permission<'a>( |
69 | | - &self, |
70 | | - permissions: &mut dyn NodePermissions, |
71 | | - path: &'a Path, |
72 | | - ) -> Result<Cow<'a, Path>, AnyError>; |
73 | | -} |
74 | | - |
75 | | -#[derive(Debug)] |
76 | | -pub struct RegistryReadPermissionChecker { |
77 | | - sys: CliSys, |
78 | | - cache: Mutex<HashMap<PathBuf, PathBuf>>, |
79 | | - registry_path: PathBuf, |
80 | | -} |
81 | | - |
82 | | -impl RegistryReadPermissionChecker { |
83 | | - pub fn new(sys: CliSys, registry_path: PathBuf) -> Self { |
84 | | - Self { |
85 | | - sys, |
86 | | - registry_path, |
87 | | - cache: Default::default(), |
88 | | - } |
89 | | - } |
90 | | - |
91 | | - pub fn ensure_registry_read_permission<'a>( |
92 | | - &self, |
93 | | - permissions: &mut dyn NodePermissions, |
94 | | - path: &'a Path, |
95 | | - ) -> Result<Cow<'a, Path>, AnyError> { |
96 | | - if permissions.query_read_all() { |
97 | | - return Ok(Cow::Borrowed(path)); // skip permissions checks below |
98 | | - } |
99 | | - |
100 | | - // allow reading if it's in the node_modules |
101 | | - let is_path_in_node_modules = path.starts_with(&self.registry_path) |
102 | | - && path |
103 | | - .components() |
104 | | - .all(|c| !matches!(c, std::path::Component::ParentDir)); |
105 | | - |
106 | | - if is_path_in_node_modules { |
107 | | - let mut cache = self.cache.lock().unwrap(); |
108 | | - let mut canonicalize = |
109 | | - |path: &Path| -> Result<Option<PathBuf>, AnyError> { |
110 | | - match cache.get(path) { |
111 | | - Some(canon) => Ok(Some(canon.clone())), |
112 | | - None => match self.sys.fs_canonicalize(path) { |
113 | | - Ok(canon) => { |
114 | | - cache.insert(path.to_path_buf(), canon.clone()); |
115 | | - Ok(Some(canon)) |
116 | | - } |
117 | | - Err(e) => { |
118 | | - if e.kind() == ErrorKind::NotFound { |
119 | | - return Ok(None); |
120 | | - } |
121 | | - Err(AnyError::from(e)).with_context(|| { |
122 | | - format!("failed canonicalizing '{}'", path.display()) |
123 | | - }) |
124 | | - } |
125 | | - }, |
126 | | - } |
127 | | - }; |
128 | | - if let Some(registry_path_canon) = canonicalize(&self.registry_path)? { |
129 | | - if let Some(path_canon) = canonicalize(path)? { |
130 | | - if path_canon.starts_with(registry_path_canon) { |
131 | | - return Ok(Cow::Owned(path_canon)); |
132 | | - } |
133 | | - } else if path.starts_with(registry_path_canon) |
134 | | - || path.starts_with(&self.registry_path) |
135 | | - { |
136 | | - return Ok(Cow::Borrowed(path)); |
137 | | - } |
138 | | - } |
139 | | - } |
140 | | - |
141 | | - permissions.check_read_path(path).map_err(Into::into) |
142 | | - } |
143 | | -} |
144 | | - |
145 | | -/// Caches all the packages in parallel. |
146 | | -pub async fn cache_packages( |
147 | | - packages: &[NpmResolutionPackage], |
148 | | - tarball_cache: &Arc<CliNpmTarballCache>, |
149 | | -) -> Result<(), AnyError> { |
150 | | - let mut futures_unordered = futures::stream::FuturesUnordered::new(); |
151 | | - for package in packages { |
152 | | - futures_unordered.push(async move { |
153 | | - tarball_cache |
154 | | - .ensure_package(&package.id.nv, &package.dist) |
155 | | - .await |
156 | | - }); |
157 | | - } |
158 | | - while let Some(result) = futures_unordered.next().await { |
159 | | - // surface the first error |
160 | | - result?; |
161 | | - } |
162 | | - Ok(()) |
163 | 53 | } |
0 commit comments