Browse Source

This does not work, because every process in the tree has a new PID so we can't ensure a consistent symlink path

remotes/origin/add-with-shims
Gal Schlezinger 3 years ago
parent
commit
d1f7b9daeb
No known key found for this signature in database
GPG Key ID: 68CF3D15D272E5E1
  1. 11
      src/commands/use.rs
  2. 10
      src/current_version.rs
  3. 1
      src/main.rs
  4. 47
      src/symlink_path.rs

11
src/commands/use.rs

@ -3,6 +3,7 @@ use super::install::Install; @@ -3,6 +3,7 @@ use super::install::Install;
use crate::fs;
use crate::installed_versions;
use crate::outln;
use crate::symlink_path::DefaultMultishellPathExt;
use crate::system_version;
use crate::user_version::UserVersion;
use crate::version::Version;
@ -23,8 +24,10 @@ impl Command for Use { @@ -23,8 +24,10 @@ impl Command for Use {
type Error = Error;
fn apply(self, config: &FnmConfig) -> Result<(), Self::Error> {
let multishell_path = config.multishell_path().context(FnmEnvWasNotSourced)?;
warn_if_multishell_path_not_in_path_env_var(multishell_path, config);
let multishell_path = config
.multishell_path_or_default()
.context(FnmEnvWasNotSourced)?;
warn_if_multishell_path_not_in_path_env_var(&multishell_path, config);
let all_versions =
installed_versions::list(config.installations_dir()).context(VersionListingError)?;
@ -78,7 +81,7 @@ impl Command for Use { @@ -78,7 +81,7 @@ impl Command for Use {
}
};
replace_symlink(&version_path, multishell_path).context(SymlinkingCreationIssue)?;
replace_symlink(&version_path, &multishell_path).context(SymlinkingCreationIssue)?;
Ok(())
}
@ -197,5 +200,5 @@ pub enum Error { @@ -197,5 +200,5 @@ pub enum Error {
"You should setup your shell profile to evaluate `fnm env`, see https://github.com/Schniz/fnm#shell-setup on how to do this",
"Check out our documentation for more information: https://fnm.vercel.app"
))]
FnmEnvWasNotSourced,
FnmEnvWasNotSourced { source: Box<dyn std::error::Error> },
}

10
src/current_version.rs

@ -1,10 +1,12 @@ @@ -1,10 +1,12 @@
use crate::config::FnmConfig;
use crate::system_version;
use crate::version::Version;
use snafu::{OptionExt, ResultExt, Snafu};
use crate::{config::FnmConfig, symlink_path::DefaultMultishellPathExt};
use snafu::{ResultExt, Snafu};
pub fn current_version(config: &FnmConfig) -> Result<Option<Version>, Error> {
let multishell_path = config.multishell_path().context(EnvNotApplied)?;
let multishell_path = config
.multishell_path_or_default()
.context(CantCreateMultishellPath)?;
if multishell_path.read_link().ok() == Some(system_version::path()) {
return Ok(Some(Version::Bypassed));
@ -31,7 +33,7 @@ pub enum Error { @@ -31,7 +33,7 @@ pub enum Error {
#[snafu(display(
"`fnm env` was not applied in this context.\nCan't find fnm's environment variables"
))]
EnvNotApplied,
CantCreateMultishellPath { source: Box<dyn std::error::Error> },
#[snafu(display("Can't read the version as a valid semver"))]
VersionError {
source: semver::Error,

1
src/main.rs

@ -33,6 +33,7 @@ mod version_files; @@ -33,6 +33,7 @@ mod version_files;
#[macro_use]
mod log_level;
mod symlink_path;
fn main() {
env_logger::init();

47
src/symlink_path.rs

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
use std::{fs::create_dir_all, path::PathBuf};
use log::info;
use sysinfo::{get_current_pid, ProcessExt, System, SystemExt};
use crate::config::FnmConfig;
pub fn generate_symlink_token_based_on_pid() -> Result<String, &'static str> {
let mut system = System::new();
let current_pid = get_current_pid()?;
system.refresh_process(current_pid);
let current_process = system
.process(current_pid)
.ok_or("Couldn't find the current process in the tree")?;
let parent_pid = current_process
.parent()
.ok_or("Couldn't find the parent pid in the process tree")?;
Ok(format!("pid_{}", parent_pid))
}
pub(crate) trait DefaultMultishellPathExt {
fn multishell_path_or_default(&self) -> Result<PathBuf, Box<dyn std::error::Error>>;
}
impl DefaultMultishellPathExt for FnmConfig {
fn multishell_path_or_default(&self) -> Result<PathBuf, Box<dyn std::error::Error>> {
if let Some(given_path) = self.multishell_path() {
return Ok(given_path.to_path_buf());
}
let symlink_token = generate_symlink_token_based_on_pid()?;
let multishells_path = std::env::temp_dir().join("fnm_multishells");
let new_path = multishells_path.join(symlink_token);
info!(
"No multishell path given, generating a new one at {}",
new_path.display()
);
create_dir_all(&multishells_path)?;
Ok(new_path)
}
}
Loading…
Cancel
Save