env._.source has issues when the sourced script changes
Describe the bug
When the script referenced by an env._.source field changes, the environment doesn't update, even though the sourced script definitely gets re-executed.
To Reproduce This appears to be order dependent so make sure to follow these steps exactly as so:
$ mkdir mise_bug
$ cd mise_bug
$ cat > .mise.toml
[env]
_.source = "./add_to_env.sh"
ADDED_IN_MISE_TOML = "added-in-mise-toml"
[settings]
experimental = true
(press control-D, then continue:)
$ env | grep added-in
$ cat > add_to_env.sh
export ADDED_IN_SOURCED_FILE="added-in-sourced-file"
echo "In add_to_env.sh: ADDED_IN_SOURCED_FILE=$ADDED_IN_SOURCED_FILE" >&2
export PATH="added-in-sourced-file:$PATH"
echo "In add_to_env.sh: PATH=$PATH" >&2
(control-D again, then:)
$ env | grep added-in
$ cd ..
$ cd mise_bug
$ env | grep added-in
Expected behavior
Before add_to_env.sh exists, there should be a "No such file or directory" error. $ADDED_IN_MISE_TOML should be set, but $ADDED_IN_SOURCED_FILE should not, and $PATH should be untouched.
After add_to_env.sh is created, the output from that script ("In add_to_env.sh: ...") should appear, $ADDED_IN_SOURCED_FILE should be set in the shell environment, and $PATH should have a prefix added. Changing out and back into the directory should have no effect.
Actual behavior
Indeed, after .mise.toml is created but before add_to_env.sh exists, everything is as expected:
/usr/bin/bash: line 1: /home/egnor/mise_bug/add_to_env.sh: No such file or directory
mise +ADDED_IN_MISE_TOML
$ env | grep added-in
ADDED_IN_MISE_TOML=added-in-mise-toml
/usr/bin/bash: line 1: /home/egnor/mise_bug/add_to_env.sh: No such file or directory
However, after creating add_to_env.sh, things are strange:
In add_to_env.sh: ADDED_IN_SOURCED_FILE=added-in-sourced-file
In add_to_env.sh: PATH=added-in-sourced-file:[... the normal PATH ...]
$ env | grep added-in
ADDED_IN_MISE_TOML=added-in-mise-toml
So even though the script is clearly run (per the In add_to_env.sh: ... lines), $ADDED_IN_SOURCED_FILE is not set and $PATH is not modified. Upon changing out and back in, things change a bit:
$ cd ..
$ cd mise_bug
In add_to_env.sh: ADDED_IN_SOURCED_FILE=added-in-sourced-file
In add_to_env.sh: PATH=added-in-sourced-file:[... the normal PATH ...]
mise +ADDED_IN_MISE_TOML +ADDED_IN_SOURCED_FILE
In add_to_env.sh: ADDED_IN_SOURCED_FILE=added-in-sourced-file
In add_to_env.sh: PATH=added-in-sourced-file:[... the normal PATH ...]
$ env | grep added-in
ADDED_IN_MISE_TOML=added-in-mise-toml
ADDED_IN_SOURCED_FILE=added-in-sourced-file
In add_to_env.sh: ADDED_IN_SOURCED_FILE=added-in-sourced-file
In add_to_env.sh: PATH=added-in-sourced-file:[... the normal PATH ...]
So now the script is being run twice (for some reason) and this time $ADDED_IN_SOURCED_FILE is being set, but $PATH is still not being updated even though the script changes it.
mise doctor output
version: 2024.2.18 linux-x64 (4893e09 2024-02-24)
activated: yes
shims_on_path: no
build_info:
Target: x86_64-unknown-linux-musl
Features: DEFAULT, NATIVE_TLS, OPENSSL
Built: Sat, 24 Feb 2024 06:33:38 +0000
Rust Version: rustc 1.76.0 (07dca489a 2024-02-04)
Profile: release
shell:
/bin/zsh
zsh 5.9 (x86_64-ubuntu-linux-gnu)
dirs:
data: ~/.local/share/mise
config: ~/.config/mise
cache: ~/.cache/mise
state: ~/.local/state/mise
shims: ~/.local/share/mise/shims
config_files:
~/mise_bug/.mise.toml
plugins:
bun (core)
deno (core)
erlang (core)
go (core)
java (core)
node (core)
python (core)
ruby (core)
toolset:
env_vars:
MISE_SHELL=zsh
settings:
activate_aggressive = false
all_compile = false
always_keep_download = false
always_keep_install = false
asdf_compat = false
cargo_binstall = true
color = true
disable_default_shorthands = false
disable_tools = []
experimental = true
go_default_packages_file = "~/.default-go-packages"
go_download_mirror = "https://dl.google.com/go"
go_repo = "https://github.com/golang/go"
go_set_gopath = false
go_set_goroot = true
go_skip_checksum = false
jobs = 4
legacy_version_file = true
legacy_version_file_disable_tools = []
node_compile = false
not_found_auto_install = true
paranoid = false
plugin_autoupdate_last_check_duration = "7d"
python_compile = false
python_default_packages_file = "/home/egnor/.default-python-packages"
python_pyenv_repo = "https://github.com/pyenv/pyenv.git"
raw = false
trusted_config_paths = []
quiet = false
verbose = false
yes = false
ci = false
debug = false
trace = false
log_level = "info"
python_venv_auto_create = false
[status]
missing_tools = "if_other_versions_installed"
show_env = false
show_tools = false
No problems found
Additional context I believe this also happens if the sourced script is modified to change which variables are exported, not just when it was missing and is created, but I haven't explored all the permutations.
this may be the root cause why the "short circuiting" logic isn't working in https://github.com/jdx/mise/issues/1617. I have not investigated but I suspect the short circuiting logic is still incorrectly calling the env var directives are being executed somewhere.