Skip to content

Commit ae2e792

Browse files
committed
feat(env): prevent duplicated PATH from fnm env
* `fnm env` will look for `fnm_multishells` on the environment variable `$PATH`. * If found it will not print the `PATH` variable, thus preventing it to be duplicated. * It also uses the value for set `FNM_MULTISHELL_PATH` but stripes out the `/bin`
1 parent 64ef825 commit ae2e792

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

src/commands/env.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use clap::ValueEnum;
88
use colored::Colorize;
99
use std::collections::HashMap;
1010
use std::fmt::Debug;
11+
use std::path::PathBuf;
1112
use thiserror::Error;
1213

1314
#[derive(clap::Parser, Debug, Default)]
@@ -34,7 +35,7 @@ fn generate_symlink_path() -> String {
3435
)
3536
}
3637

37-
fn make_symlink(config: &FnmConfig) -> Result<std::path::PathBuf, Error> {
38+
fn make_symlink(config: &FnmConfig) -> Result<PathBuf, Error> {
3839
let base_dir = config.multishell_storage().ensure_exists_silently();
3940
let mut temp_dir = base_dir.join(generate_symlink_path());
4041

@@ -71,8 +72,20 @@ impl Command for Env {
7172
);
7273
}
7374

74-
let multishell_path = make_symlink(config)?;
75+
// Look for fnm_multishell in $PATH
76+
let path_env = std::env::var_os("PATH").ok_or(Error::CantReadPathVariable)?;
77+
let multishell_loaded =
78+
std::env::split_paths(&path_env).find(|p| p.starts_with(config.multishell_storage()));
79+
7580
let base_dir = config.base_dir_with_default();
81+
let multishell_path = match &multishell_loaded {
82+
Some(p) => {
83+
let path_str = p.to_str().unwrap();
84+
let path_str = path_str.strip_suffix("/bin").unwrap_or(path_str);
85+
PathBuf::from(path_str)
86+
},
87+
None => make_symlink(config)?,
88+
};
7689

7790
let env_vars = [
7891
("FNM_MULTISHELL_PATH", multishell_path.to_str().unwrap()),
@@ -111,7 +124,9 @@ impl Command for Env {
111124
shell.path(&multishell_path.join("bin"))
112125
};
113126

114-
println!("{}", binary_path?);
127+
if multishell_loaded.is_none() {
128+
println!("{}", binary_path?);
129+
}
115130

116131
for (name, value) in &env_vars {
117132
println!("{}", shell.set_env_var(name, value));
@@ -142,8 +157,10 @@ pub enum Error {
142157
CantCreateSymlink {
143158
#[source]
144159
source: std::io::Error,
145-
temp_dir: std::path::PathBuf,
160+
temp_dir: PathBuf,
146161
},
162+
#[error("Can't read path environment variable")]
163+
CantReadPathVariable,
147164
#[error(transparent)]
148165
ShellError {
149166
#[from]

0 commit comments

Comments
 (0)