From 5f2d3a269f0f50d261ed6364ae42efd5491504f7 Mon Sep 17 00:00:00 2001 From: Gal Schlezinger Date: Thu, 1 Apr 2021 15:49:12 +0300 Subject: [PATCH] Create version symlinks in a nested directory (#422) --- src/commands/env.rs | 18 ++++++++++-------- src/config.rs | 26 ++++++++++++++++---------- src/main.rs | 1 + src/path_ext.rs | 12 ++++++++++++ 4 files changed, 39 insertions(+), 18 deletions(-) create mode 100644 src/path_ext.rs diff --git a/src/commands/env.rs b/src/commands/env.rs index 353619b..5173646 100644 --- a/src/commands/env.rs +++ b/src/commands/env.rs @@ -2,6 +2,7 @@ use super::command::Command; use crate::config::FnmConfig; use crate::fs::symlink_dir; use crate::outln; +use crate::path_ext::PathExt; use crate::shell::{infer_shell, Shell, AVAILABLE_SHELLS}; use colored::Colorize; use snafu::{OptionExt, Snafu}; @@ -22,21 +23,22 @@ pub struct Env { use_on_cd: bool, } -fn generate_symlink_path(root: &std::path::Path) -> std::path::PathBuf { - let temp_dir_name = format!( - "fnm_multishell_{}_{}", +fn generate_symlink_path() -> String { + format!( + "{}_{}", std::process::id(), chrono::Utc::now().timestamp_millis(), - ); - root.join(temp_dir_name) + ) } fn make_symlink(config: &FnmConfig) -> std::path::PathBuf { - let system_temp_dir = std::env::temp_dir(); - let mut temp_dir = generate_symlink_path(&system_temp_dir); + let base_dir = std::env::temp_dir() + .join("fnm_multishells") + .ensure_exists_silently(); + let mut temp_dir = base_dir.join(generate_symlink_path()); while temp_dir.exists() { - temp_dir = generate_symlink_path(&system_temp_dir); + temp_dir = base_dir.join(generate_symlink_path()); } symlink_dir(config.default_version_dir(), &temp_dir).expect("Can't create symlink!"); diff --git a/src/config.rs b/src/config.rs index 3f261db..843b00c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,6 @@ use crate::arch; use crate::log_level::LogLevel; +use crate::path_ext::PathExt; use dirs::home_dir; use structopt::StructOpt; @@ -64,14 +65,16 @@ impl FnmConfig { } pub fn base_dir_with_default(&self) -> std::path::PathBuf { - ensure_exists_silently( - (self.base_dir.clone()) - .unwrap_or_else(|| home_dir().expect("Can't get home directory").join(".fnm")), - ) + self.base_dir + .clone() + .unwrap_or_else(|| home_dir().expect("Can't get home directory").join(".fnm")) + .ensure_exists_silently() } pub fn installations_dir(&self) -> std::path::PathBuf { - ensure_exists_silently(self.base_dir_with_default().join("node-versions")) + self.base_dir_with_default() + .join("node-versions") + .ensure_exists_silently() } pub fn default_version_dir(&self) -> std::path::PathBuf { @@ -79,7 +82,9 @@ impl FnmConfig { } pub fn aliases_dir(&self) -> std::path::PathBuf { - ensure_exists_silently(self.base_dir_with_default().join("aliases")) + self.base_dir_with_default() + .join("aliases") + .ensure_exists_silently() } #[cfg(test)] @@ -87,9 +92,10 @@ impl FnmConfig { self.base_dir = base_dir; self } -} -fn ensure_exists_silently>(path: T) -> T { - std::fs::create_dir_all(path.as_ref()).ok(); - path + pub fn multishell_base_dir(&self) -> std::path::PathBuf { + std::env::temp_dir() + .join("fnm_multishell") + .ensure_exists_silently() + } } diff --git a/src/main.rs b/src/main.rs index c85ac2e..78470bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ mod downloader; mod fs; mod installed_versions; mod lts; +mod path_ext; mod remote_node_index; mod shell; mod system_info; diff --git a/src/path_ext.rs b/src/path_ext.rs new file mode 100644 index 0000000..7a5fea2 --- /dev/null +++ b/src/path_ext.rs @@ -0,0 +1,12 @@ +pub trait PathExt { + fn ensure_exists_silently(self) -> Self; +} + +impl> PathExt for T { + /// Ensures a path is existing by creating it recursively + /// if it is missing. No error is emitted if the creation has failed. + fn ensure_exists_silently(self) -> Self { + std::fs::create_dir_all(self.as_ref()).ok(); + self + } +}