Add 'plugins/pyenv-link/' from commit '2f8cb2cf1f093e955a72babf0b65a07f84f33522'

git-subtree-dir: plugins/pyenv-link
git-subtree-mainline: ef7a9f5d14
git-subtree-split: 2f8cb2cf1f
This commit is contained in:
macayu17 2026-09-08 02:55:49 +05:30
commit fb7f2071fb
4 changed files with 262 additions and 0 deletions

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 yfprojects
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,62 @@
# pyenv-link
A [pyenv](https://github.com/pyenv/pyenv) plugin for linking python versions and virtual envs into your pyenv root.
This plugin recommends the [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv/) plugin.
## Installation
This will install the latest development version of *pyenv-link* into
the `$(pyenv root)/plugins/pyenv-link` directory.
**Important note:** If you installed pyenv into a non-standard directory, make
sure that you clone this repo into the 'plugins' directory of wherever you
installed into.
From inside that directory you can:
- Check out a specific release tag.
- Get the latest development release by running `git pull` to download the
latest changes.
```bash
git clone https://github.com/real-yfprojects/pyenv-link.git $(pyenv root)/plugins/pyenv-link
```
For the Fish shell:
```fish
git clone https://github.com/real-yfprojects/pyenv-link.git (pyenv root)/plugins/pyenv-link
```
## Usage
Make an arbitrary virtualenv available through pyenv. This automatically guesses a fitting name from the prompt, the directory name or the location of the venv.
```console
$ pyenv link version .venv
Linked new version named myproject-py3.10
```
You can also specify a name to use for the venv.
```console
$ pyenv link version .venv myname
Linked new version named myname
```
Now you can make pyenv activate/use the venv automatically:
```console
$ pyenv local myproject-py3.10
```
## Contributing
This project is developed in an open-source, community-driven way, as a voluntary effort in the authors free time.
All kinds of contributions are greatly appreciated. This not only includes implementing new features but also refactoring work or improvements to the documentation.
Bug reports, feature requests and other suggestions are welcome too.
### TODO
- [ ] Tests
- [ ] CI

View file

@ -0,0 +1,34 @@
#!/usr/bin/env bash
#
# Summary: Activate virtual environment
#
# Usage: pyenv link version <virtualenv>
#
# Link a virtual python environment to pyenvs version directory
# so that the venv can be used like one created with *pyenv-virtualenv*.
#
# <virtualenv> should be a path to a virtual python environments location.
set -e
[ -n "$PYENV_DEBUG" ] && set -x
# Provide pyenv completions
case "$1" in
--complete)
if [ -z "$2" ]; then
echo version
else
shift 2
pyenv-link-version --complete "$@"
fi
;;
version)
shift
pyenv-link-version "$@"
exit $?
;;
*)
pyenv-help --usage link >&2
exit 1
;;
esac

View file

@ -0,0 +1,145 @@
#!/usr/bin/env bash
#
# Summary: Activate virtual environment
#
# Usage: pyenv link-venv [--dry] [--quiet] <virtualenv> [<name>]
#
# Link a virtual python environment to pyenvs version directory
# so that the venv can be used like one created with *pyenv-virtualenv*.
#
# <virtualenv> should be a path to a virtual python environments location.
# <name> should be string used as a version name it may not be present
# in the pyenv version directory yet.
# If not specified a matching name is guessed from pyvenv.cfg
# or directory name of the venv.
set -e
[ -n "$PYENV_DEBUG" ] && set -x
# functions
if ! {
enable -f "${BASH_SOURCE%/*}"/../../../libexec/pyenv-realpath.dylib realpath ||
type realpath # realpath available?
} >/dev/null 2>&1; then
# realpath requires GNU coreutils to be installed. That's why its bundled with pyenv
echo realpath not available >&2
# work-around when realpath is unavailable
realpath() {
echo "$(cd "$1" && pwd)"
}
fi
array_doesnt_contain() {
local array="$1[@]"
local seeking=$2
local in=0
for element in "${!array}"; do
if [[ $element == "$seeking" ]]; then
in=1
break
fi
done
return $in
}
COMMON_VENV_NAMES=('venv' 'env' '.venv' '.env' 'ENV' 'VENV')
guess_name() {
local venv_dir=$1
local name
# guess venv name from pyvenv.cfg
local pyvenv_cfg_path=$venv_dir/pyvenv.cfg
if [ -f "$pyvenv_cfg_path" ]; then
# if `prompt` key wasn't found the var remains empty
name=$(cut -b 1-1024 "$pyvenv_cfg_path" | sed -n '/^ *prompt *= */s///p')
fi
# guess venv name from name of venv directory
local venv_dir_name=${venv_dir##*/}
if [ -z "$name" ] && array_doesnt_contain COMMON_VENV_NAMES "$venv_dir_name"; then
name=$venv_dir_name
fi
# guess venv name from name of the parent directory of the venv directory
local venv_dir_parent=${venv_dir%/*}
local venv_dir_parent_name=${venv_dir_parent##*/}
if [ -z "$name" ]; then
name=$venv_dir_parent_name
fi
echo "$name"
}
# process args
POSARGS=()
# Provide pyenv completions
if [ "$1" = "--complete" ]; then
echo --dry
echo --quiet
exit
fi
for arg in "$@"; do
case $arg in
--dry)
dry=true # any value
;;
--quiet)
quiet=true # any value
;;
-*)
pyenv-help --usage link-version >&2
exit 1
;;
*)
POSARGS+=("$arg")
;;
esac
done
if [ ! ${#POSARGS[@]} -le 2 ] || [ ! ${#POSARGS[@]} -ge 1 ]; then
pyenv-help --usage link-version >&2
exit 1
fi
venv_dir=${POSARGS[0]%/}
venv_name=${POSARGS[1]}
# Check venv exists
if [ ! -d "$venv_dir" ]; then
echo "The virtual env you specified doesn't exist"
exit 2
fi
# make venv dir absolute
venv_dir=$(realpath "$venv_dir")
# determine venv name
if [ -z "$venv_name" ]; then
venv_name=$(guess_name "$venv_dir")
fi
# check whether version exists already
if pyenv-prefix "$venv_name" >/dev/null 2>&1; then
echo Version "$venv_name" already exists >&2
exit 3
fi
# construct location to link to
pyenv_prefix_path="$PYENV_ROOT/versions/$venv_name"
# link to pyenv version directory
if [ -z "$dry" ]; then
# Handle OS types
case "$(uname -s)" in
Darwin*)
# long form flags aren't supported
ln -s "$venv_dir" "$pyenv_prefix_path";;
*)
ln --symbolic "$venv_dir" "$pyenv_prefix_path";;
esac
fi
# output
[ -z "$quiet" ] && echo Linked new version named "$venv_name" || true