ekalinin / nodeenv

Virtual environment for Node.js & integrator with virtualenv
http://ekalinin.github.io/nodeenv/
Other
1.7k stars 209 forks source link

duplicate path in python-virtualenv #332

Open dotysan opened 1 year ago

dotysan commented 1 year ago

When installed into a running python3 venv, that path is duplicated. Fairly easy to reproduce.

python3 -m venv .venv
source .venv/bin/activate
tr : '\n' <<<$PATH

Notice that PATH is already prepended with the .venv/bin.

/HERE/.venv/bin
/usr/local/bin
/usr/bin
/usr/local/sbin
/usr/sbin
/home/bozo/.local/bin
/home/bozo/bin

Then install nodeenv inside that active venv.

pip install nodeenv
nodeenv --python-virtualenv --node=lts

The next time you re-activate...

source .venv/bin/activate
tr : '\n' <<<$PATH

...that path is duplicated.

/HERE/.venv/lib/node_modules/.bin
/HERE/.venv/bin
/HERE/.venv/bin    <== whoops!
/usr/local/bin
/usr/bin
/usr/local/sbin
/usr/sbin
/home/bozo/.local/bin
/home/bozo/bin
dotysan commented 1 year ago

I'm not familiar enough with this project to know if this is a bug or a regression.

I can't think of a reason that NODE_VIRTUAL_ENV isn't already in the PATH. So the quick and brutal fix is this.

diff --git a/nodeenv.py b/nodeenv.py
index 5c8aa2e..70bd577 100644
--- a/nodeenv.py
+++ b/nodeenv.py
@@ -1338,7 +1338,7 @@ fi
 export NODE_VIRTUAL_ENV

 _OLD_NODE_VIRTUAL_PATH="$PATH"
-PATH="$NODE_VIRTUAL_ENV/lib/node_modules/.bin:$NODE_VIRTUAL_ENV/__BIN_NAME__:$PATH"
+PATH="$NODE_VIRTUAL_ENV/lib/node_modules/.bin:$PATH"
 export PATH

 _OLD_NODE_PATH="$NODE_PATH"

However, out of the abundance of caution, if there ever is a reason that the NODE_VIRTUAL_ENV would be missing from the PATH, then here's a more spaghettified patch.

diff --git a/nodeenv.py b/nodeenv.py
index 5c8aa2e..23ed41f 100644
--- a/nodeenv.py
+++ b/nodeenv.py
@@ -1338,7 +1338,10 @@ fi
 export NODE_VIRTUAL_ENV

 _OLD_NODE_VIRTUAL_PATH="$PATH"
-PATH="$NODE_VIRTUAL_ENV/lib/node_modules/.bin:$NODE_VIRTUAL_ENV/__BIN_NAME__:$PATH"
+if [[ $PATH != *$NODE_VIRTUAL_ENV/__BIN_NAME__* ]]
+then PATH="$NODE_VIRTUAL_ENV/__BIN_NAME__:$PATH"
+fi
+PATH="$NODE_VIRTUAL_ENV/lib/node_modules/.bin:$PATH"
 export PATH

 _OLD_NODE_PATH="$NODE_PATH"

Or this variant:

diff --git a/nodeenv.py b/nodeenv.py
index 5c8aa2e..229efc2 100644
--- a/nodeenv.py
+++ b/nodeenv.py
@@ -1338,7 +1338,9 @@ fi
 export NODE_VIRTUAL_ENV

 _OLD_NODE_VIRTUAL_PATH="$PATH"
-PATH="$NODE_VIRTUAL_ENV/lib/node_modules/.bin:$NODE_VIRTUAL_ENV/__BIN_NAME__:$PATH"
+[[ $PATH = *$NODE_VIRTUAL_ENV/__BIN_NAME__* ]] \
+  || PATH="$NODE_VIRTUAL_ENV/__BIN_NAME__:$PATH"
+PATH="$NODE_VIRTUAL_ENV/lib/node_modules/.bin:$PATH"
 export PATH

 _OLD_NODE_PATH="$NODE_PATH"

Thoughts?

This is bash only. I still haven't looked at csh/fish/ps implementations of activate. But if logic is sound, happy to generate a PR and start working on those too.