/
githubmirror
/
deno
Обзор
Документация
Войти
/
githubmirror
/
deno
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
v2.7.8
cli/util/temp.rs
161 строка
5 KB
David Sherret
refactor: reduce cwd lookups and enforce `canonicalize_path` (#32250)
23 фев 2026, 06:04
Не верифицирован
23 фев 2026, 06:04
38f3ffe
Код
Авторство
О чём код?
// Copyright 2018-2026 the Deno authors. MIT license. use std::ffi::OsString; use std::path::Path; use std::path::PathBuf; use chrono::NaiveDate; use deno_core::anyhow::Context; use deno_core::error::AnyError; use super::fs::FsCleaner; use super::fs::canonicalize_path; use super::progress_bar::ProgressBar; pub struct TempNodeModulesDir { node_modules_dir_path: PathBuf, // keep alive _temp_dir: tempfile::TempDir, } impl TempNodeModulesDir { pub fn parent(&self) -> &Path { self.node_modules_dir_path.parent().unwrap() } pub fn node_modules_dir_path(&self) -> &Path { &self.node_modules_dir_path } } /// Creates a node_modules directory in a folder with the following format: /// /// <tmp-dir>/deno_nm/<date>/<random-value> /// /// Old folders are automatically deleted by this function. pub fn create_temp_node_modules_dir() -> Result<TempNodeModulesDir, AnyError> { let root_temp_folder = std::env::temp_dir().join("deno_nm"); let today = chrono::Utc::now().date_naive(); // remove any old/stale temp dirs if let Err(err) = attempt_temp_dir_garbage_collection(&root_temp_folder, today) { log::debug!("Failed init temp folder garbage collection: {:#?}", err); } let day_folder = root_temp_folder.join(folder_name_for_date(today)); std::fs::create_dir_all(&day_folder) .with_context(|| format!("Failed creating '{}'", day_folder.display()))?; let temp_node_modules_parent_dir = tempfile::TempDir::new_in(&day_folder)?; // write a package.json to make this be considered a "node" project to deno let package_json_path = temp_node_modules_parent_dir.path().join("package.json"); std::fs::write(&package_json_path, "{}").with_context(|| { format!("Failed creating '{}'", package_json_path.display()) })?; let temp_dir_path = canonicalize_path(temp_node_modules_parent_dir.path()) .unwrap_or_else(|_| temp_node_modules_parent_dir.path().to_path_buf()); let node_modules_dir_path = temp_dir_path.join("node_modules"); log::debug!( "Creating node_modules directory at: {}", node_modules_dir_path.display() ); Ok(TempNodeModulesDir { node_modules_dir_path, _temp_dir: temp_node_modules_parent_dir, }) } fn attempt_temp_dir_garbage_collection( root_temp_folder: &Path, utc_now: NaiveDate, ) -> Result<(), AnyError> { let previous_day_str = folder_name_for_date( utc_now .checked_sub_days(chrono::Days::new(1)) .unwrap_or(utc_now), ); let current_day_str = folder_name_for_date(utc_now); let next_day_str = folder_name_for_date( utc_now .checked_add_days(chrono::Days::new(1)) .unwrap_or(utc_now), ); let progress_bar = ProgressBar::new(crate::util::progress_bar::ProgressBarStyle::TextOnly); let update_guard = progress_bar.deferred_update_with_prompt( crate::util::progress_bar::ProgressMessagePrompt::Cleaning, "old temp node_modules folders...", ); // remove any folders that aren't the current date +- 1 day let mut cleaner = FsCleaner::new(Some(update_guard)); for entry in std::fs::read_dir(root_temp_folder)? { let Ok(entry) = entry else { continue; }; if entry.file_name() != previous_day_str && entry.file_name() != current_day_str && entry.file_name() != next_day_str && let Err(err) = cleaner.rm_rf(&entry.path()) { log::debug!( "Failed cleaning '{}': {:#?}", entry.file_name().display(), err ); } } Ok(()) } fn folder_name_for_date(date: chrono::NaiveDate) -> OsString { OsString::from(date.format("%Y-%m-%d").to_string()) } #[cfg(test)] mod test { use test_util::TempDir; use super::*; #[test] fn test_attempt_temp_dir_garbage_collection() { let temp_dir = TempDir::new(); let reference_date = chrono::NaiveDate::from_ymd_opt(2020, 5, 13).unwrap(); temp_dir.path().join("0000-00-00").create_dir_all(); temp_dir .path() .join("2020-05-01/sub_dir/sub") .create_dir_all(); temp_dir .path() .join("2020-05-01/sub_dir/sub/test.txt") .write(""); temp_dir.path().join("2020-05-02/sub_dir").create_dir_all(); temp_dir.path().join("2020-05-11").create_dir_all(); temp_dir.path().join("2020-05-12").create_dir_all(); temp_dir.path().join("2020-05-13").create_dir_all(); temp_dir.path().join("2020-05-14").create_dir_all(); temp_dir.path().join("2020-05-15").create_dir_all(); attempt_temp_dir_garbage_collection( temp_dir.path().as_path(), reference_date, ) .unwrap(); let mut entries = std::fs::read_dir(temp_dir.path()) .unwrap() .map(|e| e.unwrap().file_name().into_string().unwrap()) .collect::<Vec<_>>(); entries.sort(); // should only have the current day +- 1 assert_eq!( entries, vec![ "2020-05-12".to_string(), "2020-05-13".to_string(), "2020-05-14".to_string() ] ); } }