use std::env;
use std::path::PathBuf;
use deno_cache_dir::DenoDirResolutionError;
use deno_cache_dir::ResolveDenoDirSys;
use super::DiskCache;
use super::DiskCacheSys;
#[derive(Debug, Clone)]
pub struct DenoDirOptions {
pub maybe_initial_cwd: Option<PathBuf>,
pub maybe_custom_root: Option<PathBuf>,
}
#[sys_traits::auto_impl]
pub trait DenoDirSys: DiskCacheSys + ResolveDenoDirSys + Clone {}
#[allow(clippy::disallowed_types, reason = "definition")]
pub type DenoDirProviderRc<TSys> =
deno_maybe_sync::MaybeArc<DenoDirProvider<TSys>>;
pub struct DenoDirProvider<TSys: DenoDirSys> {
options: DenoDirOptions,
sys: TSys,
deno_dir_cell: once_cell::sync::OnceCell<DenoDir<TSys>>,
}
impl<TSys: DenoDirSys> DenoDirProvider<TSys> {
pub fn new(sys: TSys, options: DenoDirOptions) -> Self {
Self {
options,
sys,
deno_dir_cell: Default::default(),
}
}
pub fn get_or_create(
&self,
) -> Result<&DenoDir<TSys>, DenoDirResolutionError> {
self.deno_dir_cell.get_or_try_init(|| {
let path = deno_cache_dir::resolve_deno_dir(
&self.sys,
deno_cache_dir::ResolveDenoDirOptions {
maybe_custom_root: self.options.maybe_custom_root.as_deref(),
maybe_initial_cwd: self.options.maybe_initial_cwd.as_deref(),
},
)?;
Ok(DenoDir::new(self.sys.clone(), path.into_owned()))
})
}
}
#[derive(Debug, Clone)]
pub struct DenoDir<TSys: DiskCacheSys> {
pub root: PathBuf,
pub gen_cache: DiskCache<TSys>,
}
impl<TSys: DiskCacheSys> DenoDir<TSys> {
pub fn new(sys: TSys, root: PathBuf) -> Self {
#[cfg(not(target_arch = "wasm32"))]
assert!(root.is_absolute());
let gen_path = root.join("gen");
Self {
root,
gen_cache: DiskCache::new(sys, gen_path),
}
}
pub fn root_path_for_display(&self) -> std::path::Display<'_> {
self.root.display()
}
pub fn code_cache_db_file_path(&self) -> PathBuf {
self.root.join("v8_code_cache_v2")
}
pub fn fmt_incremental_cache_db_file_path(&self) -> PathBuf {
self.root.join("fmt_incremental_cache_v2")
}
pub fn lint_incremental_cache_db_file_path(&self) -> PathBuf {
self.root.join("lint_incremental_cache_v2")
}
pub fn dep_analysis_db_file_path(&self) -> PathBuf {
self.root.join("dep_analysis_cache_v2")
}
pub fn fast_check_cache_db_file_path(&self) -> PathBuf {
self.root.join("fast_check_cache_v2")
}
pub fn node_analysis_db_file_path(&self) -> PathBuf {
self.root.join("node_analysis_cache_v2")
}
pub fn type_checking_cache_db_file_path(&self) -> PathBuf {
self.root.join("check_cache_v2")
}
pub fn registries_folder_path(&self) -> PathBuf {
self.root.join("registries")
}
pub fn remote_folder_path(&self) -> PathBuf {
self.root.join("remote")
}
pub fn origin_data_folder_path(&self) -> PathBuf {
self.root.join("location_data")
}
pub fn upgrade_check_file_path(&self) -> PathBuf {
self.root.join("latest.txt")
}
pub fn npm_folder_path(&self) -> PathBuf {
self.root.join("npm")
}
pub fn repl_history_file_path(&self) -> Option<PathBuf> {
#[allow(
clippy::disallowed_methods,
reason = "needs real environment variable"
)]
if let Some(deno_repl_history) = env::var_os("DENO_REPL_HISTORY") {
if deno_repl_history.is_empty() {
None
} else {
Some(PathBuf::from(deno_repl_history))
}
} else {
Some(self.root.join("deno_history.txt"))
}
}
pub fn dl_folder_path(&self) -> PathBuf {
self.root.join("dl")
}
}