-
Notifications
You must be signed in to change notification settings - Fork 437
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
Update shell config file during installation (bash & zsh) #137
Conversation
bin/pyenv-installer
Outdated
echo "Appending the following lines to $1:" | ||
echo ' # pyenv' | ||
echo ' export PATH="'"$PYENV_ROOT/bin:"'$PATH"' | ||
echo ' eval "$(pyenv init --path)"' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The suggested default is pyenv init -
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this is true, I've had the most success across multiple OS'es using the above, or the above in conjunction with pyenv init -
. Maybe that's an issue for a separate thread, though? Are there any disadvantages to including pyenv init --path
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Big disadvantage. That's not the suggested setup. 🙂
The suggested setup is not random. It was worked out based on user input about their use cases, to provide full features, in the vast majority of cases and with minimal side effects.
E.g. it provides shell completion, and it doesn't add duplicate PATH entries in a nested shell.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. I'll see if I can replicate some of my issues with this suggested setup.
To be clear, I'm talking about having more success in general with:
eval "$(pyenv init -)"
eval "$(pyenv init --path)"
Over:
eval "$(pyenv init -)"
But maybe this comes down to a debate of where pyenv shims belong in the PATH and of course that will be user-dependent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the submission! As this is one of the most requested features, you're eligible for a bounty from donated money when this goes live, if you're interested.
bin/pyenv-installer
Outdated
echo ' # pyenv' | ||
echo ' export PATH="'"$PYENV_ROOT/bin:"'$PATH"' | ||
echo ' eval "$(pyenv init --path)"' | ||
echo ' eval "$(pyenv virtualenv-init -)"' | ||
echo '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably sufficient to just say which files are being updated, like RVM does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bin/pyenv-installer
Outdated
|
||
add_userpath() { | ||
OS="$(uname -s)" | ||
CURRENT_SHELL="$(basename "$SHELL")" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is a Bash script, $SHELL
would probably always be Bash.
pyenv-init
has logic to detect the shell of the parent process.
That said, this logic seems to rather belong in pyenv-init
to avoid duplication. E.g. it likewise determines profile files for diffent shells and commands to write -- we just need to actually write them rather than just display.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After inspecting pyenv-init, I think we should just copy the logic of determining user shell directly from it, because:
- The script(
pyenv-init
) is not composed to be sourced by other one, so that we can't simply source it and variables(rc
,shell
,profile
) in our script. bin/py-installer
should be a self-containing script, which could be runned even ifpyenv-init
changed, so a little duplication might be acceptable.
So here's what I'll try to do next:
- Copying the logic directly of determining shell & rc files from pyenv-init and put a reference to the original code.
- Keep the
OS
variable so that it can better fit mac users.
I'll start working on this if you think it's appropriate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is to add yet another mode to pyenv-init
-- e.g. --install
-- that would write shell configuration. Just like currently, the installer runs it without arguments and it prints installation instructions.
Apart from avoiding code duplication, we won't need to adapt Pyenv-installer if we change something in the suggested shell configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copied the shell detection mechanism from pyenv-init
in pyenv-installer
.
This resolves the issue of pyenv-init
being unable to detect the parent of the parent process when invoked through pyenv-installer
, as described in my experiment(ianchen-tw#2).
fi | ||
} | ||
|
||
if ! command -v pyenv 1>/dev/null; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the logic behind this criterion?
Maybe rather check that shell config files don't have any mention of "pyenv"? Or run a new shell with -i
and/or --login
and check if anything related to Pyenv is set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I lost the context of this comment.
Could you check if this still being an issue after reviewing the updated code?
Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAICS, this line is supposed to detect whether we need to add shell configuration stuff, or if it's already present.
I can't see how this test achieves that.
Since there's an infinite variety of setups, perhaps the best way of action is to see how other language managers do this -- to see what measures have proven to be sufficient in practice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This criterion is based on assumptions of how pyenv-installer
might be used:
- Most users would run
pyenv-installer
on a newly configured system (without pyenv installed). - The installer will update shell configuration stuff correctly, therefore
pyenv
would be detected after restarting the shell.
This criterion is not water-proof, especially for users that rerun the installer many times without restarting their shell. But it's probably the simplest way AFAICS.
bin/pyenv-installer
Outdated
add_userpath | ||
|
||
if ${SRC_WRITTEN}; then | ||
echo "Close and reopen your terminal to start using pyenv" >&2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restarting the shell is enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
README.rst
Outdated
then remove these three lines from ``.bashrc``: | ||
|
||
then remove these three lines from your shell config file(``.bashrc``, ``.zshrc``, ``.profile``...): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would love to, lets continue this conversation once the PR gets accepted |
I'm still working on this PR. |
0c69fb5
to
6cad90a
Compare
Hello @native-api, Thank you for your help with writing the pull request for the Pyenv(pyenv/pyenv#2561). I have updated this PR and am hopeful that we can get it to work. |
if [ -z "$shell" ]; then | ||
shell="$(ps -p "$PPID" -o 'args=' 2>/dev/null || true)" | ||
shell="${shell%% *}" | ||
shell="${shell##-}" | ||
shell="${shell:-$SHELL}" | ||
shell="${shell##*/}" | ||
shell="${shell%%-*}" | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the heck did we export --detect-shell
, to be used with eval
to boot, if we STILL need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Considering this example:
Run curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
in zsh.
Just to make sure this scenario would work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That just means that --detect-shell
needs to do better.
Thanks to eval
, it can run code in the same process, evading the "shell of parent of parent" problem.
Just make it output the shell detection code that you've copypasted.
fi | ||
} | ||
|
||
if ! command -v pyenv 1>/dev/null; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAICS, this line is supposed to detect whether we need to add shell configuration stuff, or if it's already present.
I can't see how this test achieves that.
Since there's an infinite variety of setups, perhaps the best way of action is to see how other language managers do this -- to see what measures have proven to be sufficient in practice.
write_source() { | ||
# expand ~ to user's home | ||
local target="${1/#\~/$HOME}" | ||
|
||
echo "Update file: $1" >&2 | ||
|
||
echo "" >>$target | ||
echo '# pyenv' >>$target | ||
echo 'export PATH="'"$PYENV_ROOT/bin:"'$PATH"' >>$target | ||
echo 'eval "$(pyenv init -)"' >>$target | ||
echo 'eval "$(pyenv virtualenv-init -)"' >>$target | ||
|
||
USER_PATH_ADDED=true | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still heavily dislike the duplication with pyenv-init
.
It's going to be a constant headache and source of errors during maintenance.
I understand the desire to keep installation logic out of pyenv-init
as it's of no use after installation. But however you look at it, the bulk of it is already in Pyenv-Init anyway!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "is-Pyenv-shell-setup-already-done" part of the logic is something that could probably be kept out of Pyenv-Init -- if it proves to be different enough from existing Pyenv-Init logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add pyenv init --profile
and pyenv init --rc
to output just the stuff that needs to be written, then write it here. But since those files are detected inside --detect-shell
, it seems simpler and even less code in pyenv-init
to just add a single pyenv-init --install
.
I can try to complete the PR myself, addressing the remaining concerns (will probably have time this weekend). |
Just wanted to express my thanks to @native-api for continuing to work on my PR and for spending extra time on it. |
@native-api any update? If no one is interested in this pull request anymore, I'll likely close it. |
Fix: #112
For users using the installation script, it is natural that the environment variables will be automatically modified
Outline
Discussion:
References