mirror of https://github.com/jdx/mise
parent
b0fa5e91cd
commit
1aa367089b
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
cat <<EOF >mise.toml
|
||||
[env]
|
||||
FOO={value="bar", tools=true}
|
||||
EOF
|
||||
assert_contains "mise hook-env -s bash" "export FOO=bar"
|
||||
|
||||
cat <<EOF >mise.toml
|
||||
[env]
|
||||
WHICH={value="{{ exec(command='which which') }}", tools=true}
|
||||
EOF
|
||||
assert_contains "mise hook-env -s bash" "export WHICH=$(which which)"
|
|
@ -35,7 +35,8 @@ impl Envrc {
|
|||
for cf in config.config_files.keys() {
|
||||
writeln!(file, "watch_file {}", cf.to_string_lossy())?;
|
||||
}
|
||||
for (k, v) in ts.env(config)? {
|
||||
let (env, env_results) = ts.final_env(config)?;
|
||||
for (k, v) in env {
|
||||
if k == *PATH_KEY {
|
||||
writeln!(file, "PATH_add {}", v)?;
|
||||
} else {
|
||||
|
@ -47,7 +48,7 @@ impl Envrc {
|
|||
)?;
|
||||
}
|
||||
}
|
||||
for path in ts.list_paths().into_iter().rev() {
|
||||
for path in ts.list_final_paths(config, env_results)?.into_iter().rev() {
|
||||
writeln!(file, "PATH_add {}", path.to_string_lossy())?;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ impl Path {
|
|||
let path = env.get("PATH").cloned().unwrap_or_default();
|
||||
env::split_paths(&path).collect()
|
||||
} else {
|
||||
ts.list_final_paths()?
|
||||
let (_env, env_results) = ts.final_env(&config)?;
|
||||
ts.list_final_paths(&config, env_results)?
|
||||
};
|
||||
for path in paths {
|
||||
println!("{}", path.display());
|
||||
|
|
|
@ -125,7 +125,7 @@ impl Env {
|
|||
}
|
||||
|
||||
fn output_dotenv(&self, config: &Config, ts: Toolset) -> Result<()> {
|
||||
for (k, v) in ts.env(config)? {
|
||||
for (k, v) in ts.final_env(config)?.0 {
|
||||
let k = k.to_string();
|
||||
let v = v.to_string();
|
||||
miseprint!("{}={}\n", k, v)?;
|
||||
|
|
|
@ -53,11 +53,12 @@ pub struct Exec {
|
|||
|
||||
impl Exec {
|
||||
pub fn run(self) -> Result<()> {
|
||||
let config = Config::get();
|
||||
let mut ts = measure!("toolset", {
|
||||
ToolsetBuilder::new()
|
||||
.with_args(&self.tool)
|
||||
.with_default_to_latest(true)
|
||||
.build(&Config::get())?
|
||||
.build(&config)?
|
||||
});
|
||||
let opts = InstallOptions {
|
||||
force: false,
|
||||
|
@ -81,7 +82,7 @@ impl Exec {
|
|||
});
|
||||
|
||||
let (program, mut args) = parse_command(&env::SHELL, &self.command, &self.c);
|
||||
let env = measure!("env_with_path", { ts.env_with_path(&Config::get())? });
|
||||
let env = measure!("env_with_path", { ts.env_with_path(&config)? });
|
||||
|
||||
if program.rsplit('/').next() == Some("fish") {
|
||||
let mut cmd = vec![];
|
||||
|
@ -92,7 +93,9 @@ impl Exec {
|
|||
shell_escape::escape(v.into())
|
||||
));
|
||||
}
|
||||
for p in ts.list_final_paths()? {
|
||||
// TODO: env is being calculated twice with final_env and env_with_path
|
||||
let env_results = ts.final_env(&config)?.1;
|
||||
for p in ts.list_final_paths(&config, env_results)? {
|
||||
cmd.push(format!(
|
||||
"fish_add_path -gm {}",
|
||||
shell_escape::escape(p.to_string_lossy())
|
||||
|
|
|
@ -50,13 +50,13 @@ impl HookEnv {
|
|||
let ts = config.get_toolset()?;
|
||||
let shell = get_shell(self.shell).expect("no shell provided, use `--shell=zsh`");
|
||||
miseprint!("{}", hook_env::clear_old_env(&*shell))?;
|
||||
let mut mise_env = ts.env(&config)?;
|
||||
let (mut mise_env, env_results) = ts.final_env(&config)?;
|
||||
mise_env.remove(&*PATH_KEY);
|
||||
self.display_status(&config, ts, &mise_env)?;
|
||||
let mut diff = EnvDiff::new(&env::PRISTINE_ENV, mise_env.clone());
|
||||
let mut patches = diff.to_patches();
|
||||
|
||||
let paths = ts.list_final_paths()?;
|
||||
let paths = ts.list_final_paths(&config, env_results)?;
|
||||
diff.path.clone_from(&paths); // update __MISE_DIFF with the new paths for the next run
|
||||
|
||||
patches.extend(self.build_path_operations(&paths, &__MISE_DIFF.path)?);
|
||||
|
|
|
@ -468,20 +468,12 @@ impl Toolset {
|
|||
}
|
||||
/// the full mise environment including all tool paths
|
||||
pub fn env_with_path(&self, config: &Config) -> Result<EnvMap> {
|
||||
let mut env = self.env(config)?;
|
||||
let (mut env, env_results) = self.final_env(config)?;
|
||||
let mut path_env = PathEnv::from_iter(env::PATH.clone());
|
||||
for p in self.list_final_paths()? {
|
||||
for p in self.list_final_paths(config, env_results)? {
|
||||
path_env.add(p);
|
||||
}
|
||||
env.insert(PATH_KEY.to_string(), path_env.to_string());
|
||||
let mut ctx = config.tera_ctx.clone();
|
||||
ctx.insert("env", &env);
|
||||
env.extend(
|
||||
self.load_post_env(ctx, &env)?
|
||||
.env
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k, v.0)),
|
||||
);
|
||||
Ok(env)
|
||||
}
|
||||
pub fn env_from_tools(&self, config: &Config) -> Vec<(String, String, String)> {
|
||||
|
@ -501,7 +493,7 @@ impl Toolset {
|
|||
.filter(|(_, k, _)| k.to_uppercase() != "PATH")
|
||||
.collect::<Vec<(String, String, String)>>()
|
||||
}
|
||||
pub fn env(&self, config: &Config) -> Result<EnvMap> {
|
||||
fn env(&self, config: &Config) -> Result<EnvMap> {
|
||||
time!("env start");
|
||||
let entries = self
|
||||
.env_from_tools(config)
|
||||
|
@ -513,7 +505,7 @@ impl Toolset {
|
|||
.filter(|(k, _)| k == "MISE_ADD_PATH" || k == "RTX_ADD_PATH")
|
||||
.map(|(_, v)| v)
|
||||
.join(":");
|
||||
let mut entries: EnvMap = entries
|
||||
let mut env: EnvMap = entries
|
||||
.into_iter()
|
||||
.filter(|(k, _)| k != "RTX_ADD_PATH")
|
||||
.filter(|(k, _)| k != "MISE_ADD_PATH")
|
||||
|
@ -522,16 +514,35 @@ impl Toolset {
|
|||
.rev()
|
||||
.collect();
|
||||
if !add_paths.is_empty() {
|
||||
entries.insert(PATH_KEY.to_string(), add_paths);
|
||||
env.insert(PATH_KEY.to_string(), add_paths);
|
||||
}
|
||||
entries.extend(config.env()?.clone());
|
||||
env.extend(config.env()?.clone());
|
||||
if let Some(venv) = &*UV_VENV {
|
||||
for (k, v) in &venv.env {
|
||||
entries.insert(k.clone(), v.clone());
|
||||
env.insert(k.clone(), v.clone());
|
||||
}
|
||||
}
|
||||
time!("env end");
|
||||
Ok(entries)
|
||||
Ok(env)
|
||||
}
|
||||
pub fn final_env(&self, config: &Config) -> Result<(EnvMap, EnvResults)> {
|
||||
let mut env = self.env(config)?;
|
||||
let mut tera_env = env.clone();
|
||||
let mut path_env = PathEnv::from_iter(env::PATH.clone());
|
||||
for p in self.list_paths().into_iter() {
|
||||
path_env.add(p);
|
||||
}
|
||||
tera_env.insert(PATH_KEY.to_string(), path_env.to_string());
|
||||
let mut ctx = config.tera_ctx.clone();
|
||||
ctx.insert("env", &tera_env);
|
||||
let env_results = self.load_post_env(config, ctx, &tera_env)?;
|
||||
env.extend(
|
||||
env_results
|
||||
.env
|
||||
.iter()
|
||||
.map(|(k, v)| (k.clone(), v.0.clone())),
|
||||
);
|
||||
Ok((env, env_results))
|
||||
}
|
||||
pub fn list_paths(&self) -> Vec<PathBuf> {
|
||||
self.list_current_installed_versions()
|
||||
|
@ -547,36 +558,30 @@ impl Toolset {
|
|||
.collect()
|
||||
}
|
||||
/// same as list_paths but includes config.list_paths, venv paths, and MISE_ADD_PATHs from self.env()
|
||||
pub fn list_final_paths(&self) -> Result<Vec<PathBuf>> {
|
||||
pub fn list_final_paths(
|
||||
&self,
|
||||
config: &Config,
|
||||
env_results: EnvResults,
|
||||
) -> Result<Vec<PathBuf>> {
|
||||
let mut paths = IndexSet::new();
|
||||
for p in Config::get().path_dirs()?.clone() {
|
||||
for p in config.path_dirs()?.clone() {
|
||||
paths.insert(p);
|
||||
}
|
||||
if let Some(venv) = &*UV_VENV {
|
||||
paths.insert(venv.venv_path.clone());
|
||||
}
|
||||
if let Some(path) = self.env(&Config::get())?.get(&*PATH_KEY) {
|
||||
if let Some(path) = self.env(config)?.get(&*PATH_KEY) {
|
||||
paths.insert(PathBuf::from(path));
|
||||
}
|
||||
for p in self.list_paths() {
|
||||
paths.insert(p);
|
||||
}
|
||||
let config = Config::get();
|
||||
let mut env = self.env(&config)?;
|
||||
let mut path_env = PathEnv::from_iter(env::PATH.clone());
|
||||
for p in paths.clone().into_iter() {
|
||||
path_env.add(p);
|
||||
}
|
||||
env.insert(PATH_KEY.to_string(), path_env.to_string());
|
||||
let mut ctx = config.tera_ctx.clone();
|
||||
ctx.insert("env", &env);
|
||||
// these are returned in order, but we need to run the post_env stuff last and then put the results in the front
|
||||
let paths = self
|
||||
.load_post_env(ctx, &env)?
|
||||
.env_paths
|
||||
.into_iter()
|
||||
.chain(paths)
|
||||
.collect();
|
||||
let paths = env_results.env_paths.into_iter().chain(paths).collect();
|
||||
Ok(paths)
|
||||
}
|
||||
pub fn which(&self, bin_name: &str) -> Option<(Arc<dyn Backend>, ToolVersion)> {
|
||||
|
@ -678,8 +683,12 @@ impl Toolset {
|
|||
!ba.is_os_supported() || SETTINGS.disable_tools().contains(&ba.short)
|
||||
}
|
||||
|
||||
fn load_post_env(&self, ctx: tera::Context, env: &EnvMap) -> Result<EnvResults> {
|
||||
let config = Config::get();
|
||||
fn load_post_env(
|
||||
&self,
|
||||
config: &Config,
|
||||
ctx: tera::Context,
|
||||
env: &EnvMap,
|
||||
) -> Result<EnvResults> {
|
||||
let entries = config
|
||||
.config_files
|
||||
.iter()
|
||||
|
|
Loading…
Reference in New Issue