mirror of
https://github.com/pyenv/pyenv.git
synced 2026-09-10 07:36:16 -04:00
Incorporate the pyenv-link plugin (#3538)
Some checks failed
pyenv_tests / pyenv_tests (ubuntu-22.04) (push) Failing after 1s
build / discover_build_logic_change (push) Has been cancelled
pyenv_tests / pyenv_tests (macos-14) (push) Has been cancelled
pyenv_tests / pyenv_tests (macos-15) (push) Has been cancelled
pyenv_tests / pyenv_tests (macos-15-intel) (push) Has been cancelled
pyenv_tests / pyenv_tests (macos-26) (push) Has been cancelled
pyenv_tests / pyenv_tests (ubuntu-22.04-arm) (push) Has been cancelled
pyenv_tests / pyenv_tests (ubuntu-24.04) (push) Has been cancelled
pyenv_tests / pyenv_tests (ubuntu-24.04-arm) (push) Has been cancelled
pyenv_tests / pyenv_tests_docker (push) Has been cancelled
build / build (push) Has been cancelled
Some checks failed
pyenv_tests / pyenv_tests (ubuntu-22.04) (push) Failing after 1s
build / discover_build_logic_change (push) Has been cancelled
pyenv_tests / pyenv_tests (macos-14) (push) Has been cancelled
pyenv_tests / pyenv_tests (macos-15) (push) Has been cancelled
pyenv_tests / pyenv_tests (macos-15-intel) (push) Has been cancelled
pyenv_tests / pyenv_tests (macos-26) (push) Has been cancelled
pyenv_tests / pyenv_tests (ubuntu-22.04-arm) (push) Has been cancelled
pyenv_tests / pyenv_tests (ubuntu-24.04) (push) Has been cancelled
pyenv_tests / pyenv_tests (ubuntu-24.04-arm) (push) Has been cancelled
pyenv_tests / pyenv_tests_docker (push) Has been cancelled
build / build (push) Has been cancelled
for use in linking binary installations
This commit is contained in:
commit
ef4905cd81
36
Makefile
36
Makefile
|
|
@ -10,11 +10,14 @@ TEST_PYTHON_BUILD_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuf
|
||||||
TEST_BINARY_DOCKER_PREFIX = test-binary-docker
|
TEST_BINARY_DOCKER_PREFIX = test-binary-docker
|
||||||
TEST_BINARY_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_BINARY_DOCKER_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_BINARY_DOCKER_PREFIX)))
|
TEST_BINARY_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_BINARY_DOCKER_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_BINARY_DOCKER_PREFIX)))
|
||||||
|
|
||||||
|
TEST_LINK_DOCKER_PREFIX = test-link-docker
|
||||||
|
TEST_LINK_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_LINK_DOCKER_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_LINK_DOCKER_PREFIX)))
|
||||||
|
|
||||||
TEST_BATS_IMAGE_PREFIX = test-pyenv-docker-image
|
TEST_BATS_IMAGE_PREFIX = test-pyenv-docker-image
|
||||||
TEST_BATS_IMAGE_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_BATS_IMAGE_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_BATS_IMAGE_PREFIX)))
|
TEST_BATS_IMAGE_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_BATS_IMAGE_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_BATS_IMAGE_PREFIX)))
|
||||||
|
|
||||||
.PHONY: test-docker
|
.PHONY: test-docker
|
||||||
test-docker: $(TEST_UNIT_DOCKER_PREFIX) $(TEST_PYTHON_BUILD_DOCKER_PREFIX) $(TEST_BINARY_DOCKER_PREFIX)
|
test-docker: $(TEST_UNIT_DOCKER_PREFIX) $(TEST_PYTHON_BUILD_DOCKER_PREFIX) $(TEST_BINARY_DOCKER_PREFIX) $(TEST_LINK_DOCKER_PREFIX)
|
||||||
|
|
||||||
.PHONY: $(TEST_UNIT_DOCKER_PREFIX)
|
.PHONY: $(TEST_UNIT_DOCKER_PREFIX)
|
||||||
$(TEST_UNIT_DOCKER_PREFIX): $(TEST_UNIT_DOCKER_TARGETS)
|
$(TEST_UNIT_DOCKER_PREFIX): $(TEST_UNIT_DOCKER_TARGETS)
|
||||||
|
|
@ -88,6 +91,29 @@ $(TEST_BINARY_DOCKER_TARGETS): $(TEST_BINARY_DOCKER_PREFIX)-% : $(TEST_BATS_IMAG
|
||||||
bats $${CI:+-F "/code/test/libexec/bats-format-tap-suite"} \
|
bats $${CI:+-F "/code/test/libexec/bats-format-tap-suite"} \
|
||||||
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} plugins/pyenv-binary/test/$${BATS_FILE_FILTER}
|
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} plugins/pyenv-binary/test/$${BATS_FILE_FILTER}
|
||||||
|
|
||||||
|
.PHONY: $(TEST_LINK_DOCKER_PREFIX)
|
||||||
|
$(TEST_LINK_DOCKER_PREFIX): $(TEST_LINK_DOCKER_TARGETS)
|
||||||
|
|
||||||
|
.PHONY: $(TEST_LINK_DOCKER_TARGETS)
|
||||||
|
$(TEST_LINK_DOCKER_TARGETS): DOCKER_IMAGE = $(TEST_BATS_IMAGE_PREFIX)
|
||||||
|
$(TEST_LINK_DOCKER_TARGETS): GNU = $(if $(findstring -gnu-,$@),True,False)
|
||||||
|
$(TEST_LINK_DOCKER_TARGETS): BASH = $(filter $(TEST_BASH_VERSIONS),$(subst -, ,$@))
|
||||||
|
$(TEST_LINK_DOCKER_TARGETS): DOCKER_TAG = bash-$(BASH)-gnu-$(GNU)
|
||||||
|
$(TEST_LINK_DOCKER_TARGETS): INTERACTIVE = $(if $(findstring true,$(CI)),,-ti)
|
||||||
|
$(TEST_LINK_DOCKER_TARGETS): $(TEST_LINK_DOCKER_PREFIX)-% : $(TEST_BATS_IMAGE_PREFIX)-%
|
||||||
|
$(info Running test with docker image '$(DOCKER_IMAGE):$(DOCKER_TAG)')
|
||||||
|
docker run \
|
||||||
|
--init \
|
||||||
|
-v $(PWD):/code:ro \
|
||||||
|
-v /etc/passwd:/etc/passwd:ro \
|
||||||
|
-v /etc/group:/etc/group:ro \
|
||||||
|
-u "$$(id -u $$(whoami)):$$(id -g $$(whoami))" \
|
||||||
|
$${CI+-e CI="$${CI}"} \
|
||||||
|
$(INTERACTIVE) \
|
||||||
|
$(DOCKER_IMAGE):$(DOCKER_TAG) \
|
||||||
|
bats $${CI:+-F "/code/test/libexec/bats-format-tap-suite"} \
|
||||||
|
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} plugins/pyenv-link/test/$${BATS_FILE_FILTER}
|
||||||
|
|
||||||
# Build all images needed for bats under docker
|
# Build all images needed for bats under docker
|
||||||
.PHONY: $(TEST_BATS_IMAGE_PREFIX)
|
.PHONY: $(TEST_BATS_IMAGE_PREFIX)
|
||||||
$(TEST_BATS_IMAGE_PREFIX): $(TEST_BATS_IMAGE_TARGETS)
|
$(TEST_BATS_IMAGE_PREFIX): $(TEST_BATS_IMAGE_TARGETS)
|
||||||
|
|
@ -110,13 +136,13 @@ $(TEST_BATS_IMAGE_TARGETS):
|
||||||
./ ; \
|
./ ; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
.PHONY: test test-unit test-python-build test-binary
|
.PHONY: test test-unit test-python-build test-binary test-link
|
||||||
|
|
||||||
# Do not pass in user flags to build tests.
|
# Do not pass in user flags to build tests.
|
||||||
unexport PYTHON_CFLAGS
|
unexport PYTHON_CFLAGS
|
||||||
unexport PYTHON_CONFIGURE_OPTS
|
unexport PYTHON_CONFIGURE_OPTS
|
||||||
|
|
||||||
test: test-unit test-python-build test-binary
|
test: test-unit test-python-build test-binary test-link
|
||||||
|
|
||||||
test-unit: bats
|
test-unit: bats
|
||||||
PATH="./bats/bin:$$PATH" test/run
|
PATH="./bats/bin:$$PATH" test/run
|
||||||
|
|
@ -129,6 +155,10 @@ test-binary: bats
|
||||||
cd plugins/pyenv-binary && $(PWD)/bats/bin/bats $${CI:+-F "$(PWD)/test/libexec/bats-format-tap-suite"} \
|
cd plugins/pyenv-binary && $(PWD)/bats/bin/bats $${CI:+-F "$(PWD)/test/libexec/bats-format-tap-suite"} \
|
||||||
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} test/$${BATS_FILE_FILTER}
|
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} test/$${BATS_FILE_FILTER}
|
||||||
|
|
||||||
|
test-link: bats
|
||||||
|
cd plugins/pyenv-link && $(PWD)/bats/bin/bats $${CI:+-F "$(PWD)/test/libexec/bats-format-tap-suite"} \
|
||||||
|
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} test/$${BATS_FILE_FILTER}
|
||||||
|
|
||||||
.SECONDARY: bats-$(TEST_BATS_VERSION)
|
.SECONDARY: bats-$(TEST_BATS_VERSION)
|
||||||
bats-$(TEST_BATS_VERSION):
|
bats-$(TEST_BATS_VERSION):
|
||||||
git clone --depth 1 --branch $(TEST_BATS_VERSION) https://github.com/bats-core/bats-core.git bats-$(TEST_BATS_VERSION)
|
git clone --depth 1 --branch $(TEST_BATS_VERSION) https://github.com/bats-core/bats-core.git bats-$(TEST_BATS_VERSION)
|
||||||
|
|
|
||||||
|
|
@ -473,12 +473,12 @@ function pyenv {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ("${commands[*]}" -split ' ') -contains \$command ) {
|
if ( ("${commands[*]}" -split ' ') -contains \$command ) {
|
||||||
\$shell_cmds = (& (get-command -commandtype application pyenv) sh-\$command \$args)
|
\$shell_cmds = (& (get-command -commandtype application pyenv -totalcount 1) sh-\$command \$args)
|
||||||
if ( \$shell_cmds.Count -gt 0 ) {
|
if ( \$shell_cmds.Count -gt 0 ) {
|
||||||
iex (\$shell_cmds -join "\`n")
|
iex (\$shell_cmds -join "\`n")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
& (get-command -commandtype application pyenv) \$command \$args
|
& (get-command -commandtype application pyenv -totalcount 1) \$command \$args
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOS
|
EOS
|
||||||
|
|
|
||||||
1
plugins/.gitignore
vendored
1
plugins/.gitignore
vendored
|
|
@ -3,4 +3,5 @@
|
||||||
!/version-ext-compat
|
!/version-ext-compat
|
||||||
!/python-build
|
!/python-build
|
||||||
!/pyenv-binary
|
!/pyenv-binary
|
||||||
|
!/pyenv-link
|
||||||
/python-build/test/build
|
/python-build/test/build
|
||||||
|
|
|
||||||
21
plugins/pyenv-link/LICENSE
Normal file
21
plugins/pyenv-link/LICENSE
Normal 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.
|
||||||
33
plugins/pyenv-link/README.md
Normal file
33
plugins/pyenv-link/README.md
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
# pyenv-link
|
||||||
|
A [pyenv](https://github.com/pyenv/pyenv) plugin for linking Python installations and virtual environments into your pyenv root.
|
||||||
|
|
||||||
|
This plugin recommends the [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv/) plugin.
|
||||||
|
|
||||||
|
## 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
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also specify a name to use for the venv.
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ pyenv link version .venv myname
|
||||||
|
Linked new version named myname
|
||||||
|
```
|
||||||
|
|
||||||
|
The same command can give a platform-specific binary installation a shorter name:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ pyenv link version "$(pyenv root)/versions/3.13.14-linux-x86_64" 3.13.14
|
||||||
|
Linked new version named 3.13.14
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can make pyenv activate/use the venv automatically:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ pyenv local myproject
|
||||||
|
```
|
||||||
34
plugins/pyenv-link/bin/pyenv-link
Executable file
34
plugins/pyenv-link/bin/pyenv-link
Executable file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Summary: Link a Python environment as a pyenv version
|
||||||
|
#
|
||||||
|
# Usage: pyenv link version [--dry] [--quiet] <path> [<name>]
|
||||||
|
#
|
||||||
|
# Link a virtual python environment to pyenvs version directory
|
||||||
|
# so that the venv can be used like one created with *pyenv-virtualenv*.
|
||||||
|
#
|
||||||
|
# <path> should be a path to a Python installation or virtual environment.
|
||||||
|
|
||||||
|
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
|
||||||
150
plugins/pyenv-link/bin/pyenv-link-version
Executable file
150
plugins/pyenv-link/bin/pyenv-link-version
Executable file
|
|
@ -0,0 +1,150 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Summary: Link a Python environment as a pyenv version
|
||||||
|
#
|
||||||
|
# Usage: pyenv link version [--dry] [--quiet] <path> [<name>]
|
||||||
|
#
|
||||||
|
# Link a virtual python environment to pyenvs version directory
|
||||||
|
# so that the venv can be used like one created with *pyenv-virtualenv*.
|
||||||
|
#
|
||||||
|
# <path> should be a path to a Python installation or virtual environment.
|
||||||
|
# <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() {
|
||||||
|
(cd "$1" && pwd)
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
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')
|
||||||
|
case "$name" in
|
||||||
|
\"*\" | \'*\')
|
||||||
|
name=${name:1:${#name}-2}
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# guess venv name from name of venv directory
|
||||||
|
local venv_dir_name=${venv_dir##*/}
|
||||||
|
if [ -z "$name" ]; then
|
||||||
|
case "$venv_dir_name" in
|
||||||
|
venv | env | .venv | .env | ENV | VENV) ;;
|
||||||
|
*) name=$venv_dir_name ;;
|
||||||
|
esac
|
||||||
|
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
|
||||||
|
|
||||||
|
case "$venv_name" in
|
||||||
|
"" | */* | . | .. | *:* | system | *[[:cntrl:]]* )
|
||||||
|
echo "pyenv-link: invalid version name \`${venv_name}'" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
versions_dir="$PYENV_ROOT/versions"
|
||||||
|
pyenv_prefix_path="$versions_dir/$venv_name"
|
||||||
|
|
||||||
|
if [ -e "$pyenv_prefix_path" ] || [ -L "$pyenv_prefix_path" ]; then
|
||||||
|
echo Version "$venv_name" already exists >&2
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$venv_dir" in
|
||||||
|
"$versions_dir"/*)
|
||||||
|
link_target=${venv_dir#"$versions_dir"/}
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
link_target=$venv_dir
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# link to pyenv version directory
|
||||||
|
if [ -z "$dry" ]; then
|
||||||
|
mkdir -p "$versions_dir"
|
||||||
|
ln -s "$link_target" "$pyenv_prefix_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# output
|
||||||
|
if [ -z "$quiet" ]; then
|
||||||
|
echo "Linked new version named $venv_name"
|
||||||
|
fi
|
||||||
61
plugins/pyenv-link/test/link.bats
Normal file
61
plugins/pyenv-link/test/link.bats
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
load test_helper
|
||||||
|
|
||||||
|
@test "link completions use the dispatcher" {
|
||||||
|
run pyenv completions link
|
||||||
|
assert_success
|
||||||
|
assert_output <<OUT
|
||||||
|
--help
|
||||||
|
version
|
||||||
|
OUT
|
||||||
|
run pyenv completions link version
|
||||||
|
assert_success
|
||||||
|
assert_output <<OUT
|
||||||
|
--help
|
||||||
|
--dry
|
||||||
|
--quiet
|
||||||
|
OUT
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "link requires a version path" {
|
||||||
|
run pyenv-link version
|
||||||
|
assert_failure "Usage: pyenv link version [--dry] [--quiet] <path> [<name>]"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "links an installed binary under its plain version name" {
|
||||||
|
create_alt_executable_in_version "3.13.14-linux-x86_64" python 'echo linked-python'
|
||||||
|
run pyenv-link version "$PYENV_ROOT/versions/3.13.14-linux-x86_64" 3.13.14
|
||||||
|
assert_success "Linked new version named 3.13.14"
|
||||||
|
assert_equal "3.13.14-linux-x86_64" "$(readlink "$PYENV_ROOT/versions/3.13.14")"
|
||||||
|
PYENV_VERSION=3.13.14 run pyenv exec python
|
||||||
|
assert_success "linked-python"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "links external paths containing spaces into a fresh root" {
|
||||||
|
mkdir -p "$PYENV_TEST_DIR/external env/bin"
|
||||||
|
run pyenv-link version "$PYENV_TEST_DIR/external env" custom
|
||||||
|
assert_success "Linked new version named custom"
|
||||||
|
assert_equal "$PYENV_TEST_DIR/external env" "$(readlink "$PYENV_ROOT/versions/custom")"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "refuses a dangling destination link" {
|
||||||
|
mkdir -p "$PYENV_ROOT/versions" "$PYENV_TEST_DIR/source"
|
||||||
|
ln -s missing "$PYENV_ROOT/versions/dangling"
|
||||||
|
run pyenv-link version "$PYENV_TEST_DIR/source" dangling
|
||||||
|
assert_failure "Version dangling already exists"
|
||||||
|
assert_equal missing "$(readlink "$PYENV_ROOT/versions/dangling")"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "rejects invalid version names" {
|
||||||
|
mkdir -p "$PYENV_TEST_DIR/source"
|
||||||
|
for name in ../outside . .. 'foo/bar' 'foo:bar' system; do
|
||||||
|
run pyenv-link version "$PYENV_TEST_DIR/source" "$name"
|
||||||
|
assert_failure "pyenv-link: invalid version name \`$name'"
|
||||||
|
assert [ ! -e "$PYENV_ROOT/outside" ]
|
||||||
|
done
|
||||||
|
echo "prompt = '../outside'" > "$PYENV_TEST_DIR/source/pyvenv.cfg"
|
||||||
|
run pyenv-link version "$PYENV_TEST_DIR/source"
|
||||||
|
assert_failure "pyenv-link: invalid version name \`../outside'"
|
||||||
|
assert [ ! -e "$PYENV_ROOT/outside" ]
|
||||||
|
}
|
||||||
1
plugins/pyenv-link/test/test_helper.bash
Symbolic link
1
plugins/pyenv-link/test/test_helper.bash
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../test/test_helper.bash
|
||||||
|
|
@ -2,8 +2,14 @@ unset PYENV_VERSION
|
||||||
unset PYENV_DIR
|
unset PYENV_DIR
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
export _PYENV_INSTALL_PREFIX="${BATS_TEST_DIRNAME%/*}"
|
|
||||||
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
|
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
|
||||||
|
|
||||||
|
export _PYENV_INSTALL_PREFIX="${BATS_TEST_DIRNAME%/*}"
|
||||||
|
local PLUGIN_PREFIX
|
||||||
|
if [[ $_PYENV_INSTALL_PREFIX =~ /plugins/[^/]+$ ]]; then
|
||||||
|
PLUGIN_PREFIX="$_PYENV_INSTALL_PREFIX"
|
||||||
|
_PYENV_INSTALL_PREFIX="${_PYENV_INSTALL_PREFIX::${#_PYENV_INSTALL_PREFIX}-${#BASH_REMATCH[0]}}"
|
||||||
|
fi
|
||||||
if ! enable -f "${_PYENV_INSTALL_PREFIX}"/libexec/pyenv-realpath.dylib realpath 2>/dev/null; then
|
if ! enable -f "${_PYENV_INSTALL_PREFIX}"/libexec/pyenv-realpath.dylib realpath 2>/dev/null; then
|
||||||
if [ -n "$PYENV_NATIVE_EXT" ]; then
|
if [ -n "$PYENV_NATIVE_EXT" ]; then
|
||||||
echo "pyenv: failed to load \`realpath' builtin" >&2
|
echo "pyenv: failed to load \`realpath' builtin" >&2
|
||||||
|
|
@ -27,6 +33,9 @@ setup() {
|
||||||
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
|
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
|
||||||
PATH="${PYENV_TEST_DIR}/bin:$PATH"
|
PATH="${PYENV_TEST_DIR}/bin:$PATH"
|
||||||
PATH="${_PYENV_INSTALL_PREFIX}/libexec:$PATH"
|
PATH="${_PYENV_INSTALL_PREFIX}/libexec:$PATH"
|
||||||
|
if [[ -n $PLUGIN_PREFIX ]]; then
|
||||||
|
PATH="${PLUGIN_PREFIX}/libexec:${PLUGIN_PREFIX}/bin:$PATH"
|
||||||
|
fi
|
||||||
PATH="${BATS_TEST_DIRNAME}/libexec:$PATH"
|
PATH="${BATS_TEST_DIRNAME}/libexec:$PATH"
|
||||||
PATH="${PYENV_ROOT}/shims:$PATH"
|
PATH="${PYENV_ROOT}/shims:$PATH"
|
||||||
PATH="${BATS_TEST_TMPDIR}/stubs:$PATH"
|
PATH="${BATS_TEST_TMPDIR}/stubs:$PATH"
|
||||||
|
|
@ -40,6 +49,7 @@ setup() {
|
||||||
# even if its output is redirected, breaking the comparison logic
|
# even if its output is redirected, breaking the comparison logic
|
||||||
export NO_COLOR=1
|
export NO_COLOR=1
|
||||||
|
|
||||||
|
|
||||||
# If test specific setup exist, run it
|
# If test specific setup exist, run it
|
||||||
if [[ $(type -t _setup) == function ]];then
|
if [[ $(type -t _setup) == function ]];then
|
||||||
_setup
|
_setup
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue