Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rtx-activate: less aggressive PATH modifications #863

Closed
jdx opened this issue Sep 1, 2023 · 41 comments · Fixed by #1082 or #1150
Closed

rtx-activate: less aggressive PATH modifications #863

jdx opened this issue Sep 1, 2023 · 41 comments · Fixed by #1082 or #1150
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@jdx
Copy link
Owner

jdx commented Sep 1, 2023

Currently, when using rtx activate, rtx will prepend PATH entries to the very front of PATH, e.g.:

PATH="~/.local/share/rtx/installs/java/xx/bin:/usr/bin:..."

However this might be more aggressive than it should be. This means it's basically impossible to override rtx and allow the user to add custom PATH entries ahead of runtimes rtx adds with rtx activate.

Shims are one solution, but rtx activate could be a bit softer here and instead inject the PATH entries at the location of the rtx bin itself. This means if PATH was initially the following:

PATH="~/bin:~/.local/share/rtx/bin:/usr/bin"

then after running rtx activate it could change to this:

PATH="~/bin:~/.local/share/rtx/installs/java/xx/bin:~/.local/share/rtx/bin:/usr/bin"

Note that ~/bin is before the install directories.

Now while I could see use-cases where users want this, it also might be undesirable since the place that rtx is added to PATH matters. Most users will probably want it at the front or near the front regardless. For that reason, we probably want this to be an option (though I'm not sure what default is best).

FYI this is likely a somewhat challenging task. The way rtx sets up env vars is complex and it's also some of the oldest code in the codebase where I was still learning rust. That said, I think this line is what will need to be modified:

https://github.com/jdx/rtx/blob/58b0e0e56f24fb12fae8d36cdf245dcec0808796/src/cli/hook_env.rs#L92

@jdx jdx added enhancement New feature or request help wanted Extra attention is needed labels Sep 1, 2023
@brentm5
Copy link

brentm5 commented Sep 13, 2023

I actually just ran into this and as far as I could tell there was no way for me to change this in my own config. The use case I had was chef-workstation and the bundled gems as part of this. By default rtx would try and load gems that were loaded into my default ruby version.

I would suspect there are a lot of edge cases here because of the various setups people have. For example, I could see a situation for my own setup where based on the project I was in (some projects actually do manage these gems directly) i would want rtx to manage the dependencies however by default its much simpler to just use the gems bundled with chef-workstation.

@Aeron
Copy link

Aeron commented Sep 13, 2023

It also messes up any Python virtual environment in cases where I’m not using the plugin’s built-in virtual environment handling. I have a separate listener that reacts to $PWD change and activates the environment if there is one. But even without — if I do it manually — RTX will change $PATH eventually, and virtual environment binaries will fall behind.

How eventually? It’s a mystery. It can occur right on the following prompt or after a few commands.

I can’t stress enough how often I installed something by PIP as a global package instead of an environment one because of this issue.

The obvious solution would be to have the .rtx.toml in each directory with a virtual environment, with the venv key explicitly configured. But I don’t want excessive entities without any apparent reason for it. It worked perfectly before.

My solution was to write yet another listener that reacts to the prompt event and checks if the first element of $PATH resembles a virtual environment path, then re-activates the environment if necessary. But it’s a crutch solution for sure.

@jdx
Copy link
Owner Author

jdx commented Sep 13, 2023

@Aeron you might have better luck not using rtx activate and just sticking with shims

@Aeron
Copy link

Aeron commented Sep 14, 2023

Well, yeah, but Python is not the only plugin I use. It’s not the “Hey, fix my specific case” demand, by no means. But if it treats $PATH that way, it could be a problem not only for Python’s virtual environment.

If RTX needs to listen for shell’s prompt and preexec events and force its way regularly, then it probably should emit custom events. Therefore, users can have more control over it for their narrow cases.

Otherwise, it would be a million specific cases to deal with. And it’s not like RTX has (or should have) a monopoly on the last word for $PATH look. At least, that’s what I think.

Yet, in my specific case, it would be wonderful if RTX could respect not only .rtx.toml in $PWD but also existing $VIRTUAL_ENV. I believe it’s a normal behavior for any virtual environment handler.

@jdx
Copy link
Owner Author

jdx commented Sep 14, 2023

@Aeron I'm not 100% but it sounds like you think my plan of inserting runtimes into PATH at the location of the rtx bin would be insufficient and you'd prefer more control via events?

I feel like inserting instead of just always prepending to the front would work, though it might in some cases require installing rtx to a dedicated directory (one reason I think it should be behind a config setting of some kind).

Let me know if I got what you said correct though, I wasn't 100%.

In general, virtualenv stuff needs to be improved. (For users using rtx virtualenv activation as well as those that are not) I know it's a well-liked feature but has notable gaps.

@Aeron
Copy link

Aeron commented Sep 15, 2023

Oh, no-no, I don’t think your plan would not succeed, but as you said, it is a somewhat challenging task. Events are an option, alternative solution, or option B, perhaps easier and faster to implement. If anything, I agree with you and the general idea.

@karlbright
Copy link

I like this solution, it may also be worth considering an addition to rtx doctor here that will list any possible overrides that could be impacted ability to use rtx installed tools. I can imagine this will help with people debugging own issues, as well as helping resolve any opened issues of people having problems with PATHs.

@CharString
Copy link
Contributor

Python people probably want $VIRTUAL_ENV paths before the rtx activate paths. I know I work around this by changing the events my rtx activate and auto venv activator trigger on.

@jdx jdx linked a pull request Dec 6, 2023 that will close this issue
@Fall1ngStar
Copy link

Hey jdx thanks a lot for the work on this issue, this has been a recurring issue for me working with python ! Looks like the path is updated the old way in hook-env.rs

The following bit of code

let new_path = join_paths([installs.clone(), env::PATH.clone()].concat())?
            .to_string_lossy()
            .to_string();

could be replaced with

let mut path_env = PathEnv::from_iter(env::PATH.clone());
for p in installs.clone() {
     path_env.add(p);
}
let new_path = path_env.join().to_string_lossy().to_string();

Do you want me to open a PR for this ?

@jdx
Copy link
Owner Author

jdx commented Dec 6, 2023

it won't work because there won't be a shim directory to use

@jdx jdx pinned this issue Dec 6, 2023
@jdx
Copy link
Owner Author

jdx commented Dec 6, 2023

One idea I had is maybe we could keep track of any paths added to the front since activate was first launched. I think we can compare the difference between env::var("PATH") and env::PRISTINE_ENV["PATH"] which would tell us that

@jdx
Copy link
Owner Author

jdx commented Dec 13, 2023

I tried out that idea I had and it seems to work. Would anyone mind trying out by installing from HEAD?

jdx added a commit that referenced this issue Dec 13, 2023
With this change, if you manually run PATH="/foo:$PATH" in
your shell after activating rtx, rtx will keep "/foo" in front of its own PATH entries.
Fixes #863
jdx added a commit that referenced this issue Dec 13, 2023
With this change, if you manually run PATH="/foo:$PATH" in
your shell after activating rtx, rtx will keep "/foo" in front of its own PATH entries.
Fixes #863
@jdx jdx closed this as completed in #1150 Dec 13, 2023
jdx added a commit that referenced this issue Dec 13, 2023
With this change, if you manually run PATH="/foo:$PATH" in
your shell after activating rtx, rtx will keep "/foo" in front of its own PATH entries.
Fixes #863
@Fall1ngStar
Copy link

Not sure that the fix solves the issue (at least for my use case)
Here's the top of my path just after activating a python virtualenv

image

And the same command a few minutes later

image

(compiled from master)
image

@jdx
Copy link
Owner Author

jdx commented Dec 13, 2023

you didn't install from HEAD, this hasn't been released yet

@Fall1ngStar
Copy link

I'm confused, isn't 9160c4f the commit that fixed it ? I used the cargo install rtx-cli --git https://github.com/jdx/rtx --branch main command to install it

@jdx
Copy link
Owner Author

jdx commented Dec 13, 2023

oh apologies. You're running in a new shell and everything? does echo $__RTX_ORIG_PATH print anything?

it seems to work for me in fish at least:

~ ❯ python -m venv .venv
~ ❯ echo $PATH
/Users/jdx/.rtx/installs/ruby/3.2.2/bin ...
~ ❯ source .venv/bin/activate.fish
~ ❯ echo $PATH
/Users/jdx/.venv/bin /Users/jdx/.rtx/installs/ruby/3.2.2/bin ...
~ ❯ cd ~/src/rtx
rtx  main ❯ echo $PATH
/Users/jdx/.venv/bin /Users/jdx/.rtx/installs/tiny/1.1.0/bin ...

@jdx
Copy link
Owner Author

jdx commented Dec 13, 2023

I get the same results in zsh too

@jdx
Copy link
Owner Author

jdx commented Dec 13, 2023

make sure where you're calling rtx activate you're using the HEAD revision

@jdx
Copy link
Owner Author

jdx commented Dec 13, 2023

oh are you using shims and not rtx activate?

@Fall1ngStar
Copy link

Using fish with rtx activate fish | source

@Fall1ngStar
Copy link

ah yeah and I had shims remaining as a test for the first version of the fix, would that affect it ?

@jdx
Copy link
Owner Author

jdx commented Dec 13, 2023

maybe try removing the shims directory, that might mess it up

@Fall1ngStar
Copy link

ok so I tried removing the shims directory but it did not change the result. Also adjusted the order of initialization in my config.fish file, and I can see the $__RTX_ORIG_PATH variable. Do you have a consistent way to trigger the hook ? would be easier for testing.

Also, food for thoughts, the way poetry shell does its thing is by creating a subshell, then sourcing th virtualenv file; could that affect the behaviour of rtx ?

@jdx
Copy link
Owner Author

jdx commented Dec 13, 2023

let's try this to make sure it's working at all:

$ rtx activate fish | source # remove this from your config.fish temporarily and just run it in a subshell so we can isolate
$ set -gx PATH FOO $PATH # this adds "FOO" (an invalid path entry, but easy to spot), it should stay at the very front because it's not in $__RTX_ORIG_PATH
$ echo $PATH # verify FOO is in front
$ cd ... # enter some directory with a .tool-versions or .rtx.toml file
$ echo $PATH # verify the new tools in this directory are picked up, but "FOO" is still in front of PATH

one thing that might be happening: if something is modifying PATH aside from simply adding something to the front then it won't work. I might need to try messing with poetry here.

Also, are you using the automatic venv activation for python or poetry? Or just running source .venv/bin/activate.fish?

@Fall1ngStar
Copy link

Commands above work as expected

image

I use the poetry shell command to activate manually my virtualenv. I'm going to try to reproduce the error with poetry today

@Fall1ngStar
Copy link

Was able to reproduce consistently in a VM, here's the log

[ec2-user@ip-10-62-56-74 test-project]$ rtx doctor
rtx version:
  2023.12.25 linux-arm64 (e1f4173 2023-12-13)

build:
  Target: aarch64-unknown-linux-gnu
  Features: DEFAULT, NATIVE_TLS, OPENSSL
  Built: Wed, 13 Dec 2023 06:55:22 +0000
  Rust Version: rustc 1.74.1 (a28077b28 2023-12-04)
  Profile: release

shell:
  /bin/bash
  GNU bash, version 5.2.15(1)-release (aarch64-amazon-linux-gnu)
  Copyright (C) 2022 Free Software Foundation, Inc.
  License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

  This is free software; you are free to change and redistribute it.
  There is NO WARRANTY, to the extent permitted by law.

rtx data directory:
  /home/ec2-user/.local/share/rtx

rtx environment variables:
  RTX_SHELL=bash

settings:
  {"always_keep_download": "false", "always_keep_install": "false", "asdf_compat": "false", "disable_default_shorthands": "false", "disable_tools": "[]", "experimental": "false", "jobs": "4", "legacy_version_file": "true", "legacy_version_file_disable_tools": "[]", "plugin_autoupdate_last_check_duration": "7d", "raw": "false", "trusted_config_paths": "[]", "verbose": "false", "yes": "false"}

config files:
  /home/ec2-user/.tool-versions
  /home/ec2-user/test-project/.rtx.toml

plugins:
  bun      (core)
  deno     (core)
  go       (core)
  java     (core)
  node     (core)
  python   (core)
  ruby     (core)

toolset:
  node@20, python@3.12

No problems found
[ec2-user@ip-10-62-56-74 test-project]$ poetry shell
Spawning shell within /home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12
. /home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12/bin/activate
[ec2-user@ip-10-62-56-74 test-project]$ . /home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12/bin/activate
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$ tr ':' '\n' <<< "$PATH"
/home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12/bin
/home/ec2-user/.local/share/rtx/installs/node/20/bin
/home/ec2-user/.local/share/rtx/installs/python/3.12/bin
/home/ec2-user/.local/share/rtx/bin
/home/ec2-user/.cargo/bin
/home/ec2-user/.local/bin
/home/ec2-user/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/var/lib/snapd/snap/bin
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$ rtx use node@20
rtx ~/test-project/.rtx.toml node@20
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$ tr ':' '\n' <<< "$PATH"
/home/ec2-user/.local/share/rtx/installs/node/20/bin
/home/ec2-user/.local/share/rtx/installs/python/3.12/bin
/home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12/bin
/home/ec2-user/.local/share/rtx/bin
/home/ec2-user/.cargo/bin
/home/ec2-user/.local/bin
/home/ec2-user/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/var/lib/snapd/snap/bin

Please let me know if there is any flaw in my approach

@jdx
Copy link
Owner Author

jdx commented Dec 13, 2023

update: this has been released in 2023.12.25 but it's under experimental so set RTX_EXPERIMENTAL=1 to test it

@jdx jdx reopened this Dec 13, 2023
@Fall1ngStar
Copy link

Added the export at the beginning, should be enough to enable ?

[ec2-user@ip-10-62-56-74 test-project]$ RTX_EXPERIMENTAL=1
[ec2-user@ip-10-62-56-74 test-project]$ rtx doctor
rtx version:
  2023.12.25 linux-arm64 (e1f4173 2023-12-13)

build:
  Target: aarch64-unknown-linux-gnu
  Features: DEFAULT, NATIVE_TLS, OPENSSL
  Built: Wed, 13 Dec 2023 06:55:22 +0000
  Rust Version: rustc 1.74.1 (a28077b28 2023-12-04)
  Profile: release

shell:
  /bin/bash
  GNU bash, version 5.2.15(1)-release (aarch64-amazon-linux-gnu)
  Copyright (C) 2022 Free Software Foundation, Inc.
  License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

  This is free software; you are free to change and redistribute it.
  There is NO WARRANTY, to the extent permitted by law.

rtx data directory:
  /home/ec2-user/.local/share/rtx

rtx environment variables:
  RTX_SHELL=bash

settings:
  {"always_keep_download": "false", "always_keep_install": "false", "asdf_compat": "false", "disable_default_shorthands": "false", "disable_tools": "[]", "experimental": "false", "jobs": "4", "legacy_version_file": "true", "legacy_version_file_disable_tools": "[]", "plugin_autoupdate_last_check_duration": "7d", "raw": "false", "trusted_config_paths": "[]", "verbose": "false", "yes": "false"}

config files:
  /home/ec2-user/.tool-versions
  /home/ec2-user/test-project/.rtx.toml

plugins:
  bun      (core)
  deno     (core)
  go       (core)
  java     (core)
  node     (core)
  python   (core)
  ruby     (core)

toolset:
  node@20, python@3.12

No problems found
[ec2-user@ip-10-62-56-74 test-project]$ poetry shell
Spawning shell within /home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12
. /home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12/bin/activate
[ec2-user@ip-10-62-56-74 test-project]$ . /home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12/bin/activate
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$ tr ':' '\n' <<< "$PATH"
/home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12/bin
/home/ec2-user/.local/share/rtx/installs/node/20/bin
/home/ec2-user/.local/share/rtx/installs/python/3.12/bin
/home/ec2-user/.local/share/rtx/bin
/home/ec2-user/.cargo/bin
/home/ec2-user/.local/bin
/home/ec2-user/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/var/lib/snapd/snap/bin
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$ rtx use node@20
rtx ~/test-project/.rtx.toml node@20
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$ tr ':' '\n' <<< "$PATH"
/home/ec2-user/.local/share/rtx/installs/node/20/bin
/home/ec2-user/.local/share/rtx/installs/python/3.12/bin
/home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12/bin
/home/ec2-user/.local/share/rtx/bin
/home/ec2-user/.cargo/bin
/home/ec2-user/.local/bin
/home/ec2-user/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/var/lib/snapd/snap/bin
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$

@jdx
Copy link
Owner Author

jdx commented Dec 13, 2023

no, it needs to be there when you call rtx activate. With fish you can use a universal variable: set -Ux RTX_EXPERIMENTAL 1. You can also use a setting with rtx settings set experimental 1

@jdx
Copy link
Owner Author

jdx commented Dec 13, 2023

the way it works is when you call rtx activate it will save PATH at that moment to __RTX_ORIG_PATH. Later, when rtx calls rtx hook-env before the prompt is displayed, it checks that variable and if it matches the end of the current PATH it will take everything added after __RTX_ORIG_PATH was set and prepend it before rtx bins.

So effectively what this should do is make it so if you do this:

set PATH A $PATH
rtx activate fish | source
set PATH B $PATH

then PATH will be the following:

B:[RTXBINS]:A:...

what might be happening (I need to look), is that poetry is modifying the PATH in a way that changes the things that were set in __RTX_ORIG_PATH. If that does not match the suffix of PATH then rtx will just ignore it and prepend things to the beginning. In other words it might be doing something like this:

set PATH A $PATH
rtx activate $PATH
set PATH B $PATH
set PATH $PATH C

in that case, because "C" is added to the end of PATH rtx should generate this with nothing prepended:

[RTXBINS]:B:A:...:C

That's a use-case I might need to think about a bit more. Maybe instead of saving the entire suffix I could just find the first entry in PATH and prepend things before that.

@Fall1ngStar
Copy link

Here's the log with experimental activated

Log
[ec2-user@ip-10-62-56-74 test-project]$ rtx settings set experimental true
[ec2-user@ip-10-62-56-74 test-project]$ rtx doctor
rtx version:
  2023.12.25 linux-arm64 (e1f4173 2023-12-13)

build:
  Target: aarch64-unknown-linux-gnu
  Features: DEFAULT, NATIVE_TLS, OPENSSL
  Built: Wed, 13 Dec 2023 06:55:22 +0000
  Rust Version: rustc 1.74.1 (a28077b28 2023-12-04)
  Profile: release

shell:
  /bin/bash
  GNU bash, version 5.2.15(1)-release (aarch64-amazon-linux-gnu)
  Copyright (C) 2022 Free Software Foundation, Inc.
  License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

  This is free software; you are free to change and redistribute it.
  There is NO WARRANTY, to the extent permitted by law.

rtx data directory:
  /home/ec2-user/.local/share/rtx

rtx environment variables:
  RTX_SHELL=bash

settings:
  {"always_keep_download": "false", "always_keep_install": "false", "asdf_compat": "false", "disable_default_shorthands": "false", "disable_tools": "[]", "experimental": "true", "jobs": "4", "legacy_version_file": "true", "legacy_version_file_disable_tools": "[]", "plugin_autoupdate_last_check_duration": "7d", "raw": "false", "trusted_config_paths": "[]", "verbose": "false", "yes": "false"}

config files:
  /home/ec2-user/.config/rtx/config.toml
  /home/ec2-user/.tool-versions
  /home/ec2-user/test-project/.rtx.toml

plugins:
  bun      (core)
  deno     (core)
  erlang   (core)
  go       (core)
  java     (core)
  node     (core)
  python   (core)
  ruby     (core)

toolset:
  node@20, python@3.12

No problems found
[ec2-user@ip-10-62-56-74 test-project]$ poetry shell
Spawning shell within /home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12
. /home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12/bin/activate
[ec2-user@ip-10-62-56-74 test-project]$ . /home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12/bin/activate
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$ tr ':' '\n' <<< "$PATH"
/home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12/bin
/home/ec2-user/.local/share/rtx/installs/node/20/bin
/home/ec2-user/.local/share/rtx/installs/python/3.12/bin
/home/ec2-user/.local/share/rtx/bin
/home/ec2-user/.cargo/bin
/home/ec2-user/.local/bin
/home/ec2-user/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/var/lib/snapd/snap/bin
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$ export PATH="FOO:$PATH"
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$ rtx use node@20
rtx ~/test-project/.rtx.toml node@20
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$ tr ':' '\n' <<< "$PATH"
/home/ec2-user/.local/share/rtx/installs/node/20/bin
/home/ec2-user/.local/share/rtx/installs/python/3.12/bin
FOO
/home/ec2-user/.cache/pypoetry/virtualenvs/test-project-G_hDmf5f-py3.12/bin
/home/ec2-user/.local/share/rtx/bin
/home/ec2-user/.cargo/bin
/home/ec2-user/.local/bin
/home/ec2-user/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/var/lib/snapd/snap/bin
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$ tr ':' '\n' <<< "$__RTX_ORIG_PATH"
/home/ec2-user/.local/share/rtx/installs/node/20/bin
/home/ec2-user/.local/share/rtx/installs/python/3.12/bin
/home/ec2-user/.local/share/rtx/bin
/home/ec2-user/.cargo/bin
/home/ec2-user/.local/bin
/home/ec2-user/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/var/lib/snapd/snap/bin
(test-project-py3.12) [ec2-user@ip-10-62-56-74 test-project]$

I've also thrown a dummy value in the path and it was moved behind rtx bins.

I've checked the poetry repository and the way poetry shell works is it creates a subshell and then send a command to activate the virtualenv like the user could do manually.

We then have the following order for activations

(parent shell)
rtx activate (in shell init)
poetry shell
| (subshell)
| rtx activate (in shell init)
| virtualenv activate

Could it be caused by the fact that rtx activate is called at two different levels ?

@jdx
Copy link
Owner Author

jdx commented Dec 13, 2023

Could it be caused by the fact that rtx activate is called at two different levels ?

Ah that's the problem. rtx puts itself before everything that was added after it, but if you call rtx activate in a subshell then it will reset __RTX_ORIG_PATH and put itself before everything in there including the venv.

You could try this to make sure:

set -gx MY_PATH $PATH
poetry shell
rtx activate fish | source
set -gx __RTX_ORIG_PATH $MY_PATH

then it should work as expected I think.

Trouble is I'm not really sure what rtx should do differently here. I don't want to reuse an existing __RTX_ORIG_PATH since I actually think it should reset it in most use-cases. Maybe I could add this as an argument to activate so you could do this:

rtx activate fish --prepend-path "$MY_PATH" | source

@Fall1ngStar
Copy link

if you call rtx activate in a subshell then it will reset __RTX_ORIG_PATH and put itself before everything in there including the venv

So maybe instead of trying to fix my PATH, maybe I should prevent the rtx activate in the subshell ? Is there a variable available to do a check on ?

@jylenhofdecat
Copy link

jylenhofdecat commented Dec 14, 2023

Perhaps following the last fix already committed in and the last idea a solution could be that the rtx activate bash should be this :

export RTX_SHELL=bash
if [ $SHLVL -eq 1 ]; then
  export __RTX_ORIG_PATH="$PATH"
fi

rtx() {
  local command
  command="${1:-}"
  if [ "$#" = 0 ]; then
    command /usr/bin/rtx
    return
  fi
  shift

  case "$command" in
  deactivate|s|shell)
    # if argv doesn't contains -h,--help
    if [[ ! " $@ " =~ " --help " ]] && [[ ! " $@ " =~ " -h " ]]; then
      eval "$(command /usr/bin/rtx "$command" "$@")"
      return $?
    fi
    ;;
  esac
  command /usr/bin/rtx "$command" "$@"
}

_rtx_hook() {
  local previous_exit_status=$?;
  eval "$(rtx hook-env -s bash)";
  return $previous_exit_status;
};
if [[ ";${PROMPT_COMMAND:-};" != *";_rtx_hook;"* ]]; then
  PROMPT_COMMAND="_rtx_hook${PROMPT_COMMAND:+;$PROMPT_COMMAND}"
fi

INSTEAD OF this :

export RTX_SHELL=bash
export __RTX_ORIG_PATH="$PATH"

rtx() {
  local command
  command="${1:-}"
  if [ "$#" = 0 ]; then
    command /usr/bin/rtx
    return
  fi
  shift

  case "$command" in
  deactivate|s|shell)
    # if argv doesn't contains -h,--help
    if [[ ! " $@ " =~ " --help " ]] && [[ ! " $@ " =~ " -h " ]]; then
      eval "$(command /usr/bin/rtx "$command" "$@")"
      return $?
    fi
    ;;
  esac
  command /usr/bin/rtx "$command" "$@"
}

_rtx_hook() {
  local previous_exit_status=$?;
  eval "$(rtx hook-env -s bash)";
  return $previous_exit_status;
};
if [[ ";${PROMPT_COMMAND:-};" != *";_rtx_hook;"* ]]; then
  PROMPT_COMMAND="_rtx_hook${PROMPT_COMMAND:+;$PROMPT_COMMAND}"
fi

Notice the if added

@jdx
Copy link
Owner Author

jdx commented Dec 17, 2023

@jylenhofdecat can you explain what the SHLVL check is doing here? It's not making sense at first glance

@Fall1ngStar
Copy link

Looks like this is the level of nesting for the current shell (doc). So in @jylenhofdecat script, it would only apply the rtx activate if we're not in a nested shell.

@jdx
Copy link
Owner Author

jdx commented Dec 17, 2023

I don't think that's what we want. You should be able to run activate at any point. I also think in general it should effectively "reset" when called and make that point where it prepends to PATH even though it doesn't work well in this use case.

@jdx
Copy link
Owner Author

jdx commented Dec 17, 2023

One option is to add a flag to configure whether or not it resets PATH and the prepend variable.

That's not hard, but coming up with a good name for this behavior and describing it well definitely is.

@jylenhofdecat
Copy link

No.
On my script variation, rtx activate is launched on every shell and subshell.... This is only the __RTX_ORIG_PATH variable which is not reset

When you do "export", variable are pushed to subshell, functions are not, so it is already set, just didn't want to reset it.... because I'm doing a python virtualenv with source .venv/bin/activate in my shell manually and does'nt want it to be overriden on the beginning on my PATH

@jdx
Copy link
Owner Author

jdx commented Jan 11, 2024

given I haven't heard much here I suspect this experiment is working well. I'll probably roll this out to all users and make a flag to force mise to be aggressive in a few days/weeks. It might still have some edge cases like we discussed but I think this logic is still preferable.

@Fall1ngStar
Copy link

Haven't checked again as I moved to using the virtualenv automatic activation with the python plugin

@jdx jdx closed this as completed in 07e1921 Jan 12, 2024
@jdx jdx unpinned this issue Jan 25, 2024
jdx pushed a commit that referenced this issue Apr 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
7 participants