diff --git a/.github/actions/build-python/action.yml b/.github/actions/build-python/action.yml index fa310e81..194c4994 100644 --- a/.github/actions/build-python/action.yml +++ b/.github/actions/build-python/action.yml @@ -9,6 +9,12 @@ inputs: runs: using: composite steps: + - shell: bash + run: | + #envvars + export PYENV_ROOT="$GITHUB_WORKSPACE" + echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV + echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH # The two OSes differ only in this step. - if: runner.os == 'macOS' shell: bash @@ -19,15 +25,7 @@ runs: shell: bash run: | #prerequisites - sudo apt-get update -q; sudo apt install -yq make build-essential libssl-dev zlib1g-dev \ - libbz2-dev libreadline-dev libsqlite3-dev curl \ - libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev - - shell: bash - run: | - #envvars - export PYENV_ROOT="$GITHUB_WORKSPACE" - echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV - echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH + pyenv install-prerequisites - shell: bash run: | #build diff --git a/.github/workflows/modified_scripts_build.yml b/.github/workflows/modified_scripts_build.yml index a3535930..cae758a8 100644 --- a/.github/workflows/modified_scripts_build.yml +++ b/.github/workflows/modified_scripts_build.yml @@ -220,10 +220,7 @@ jobs: echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH - run: | #prerequisites - sudo apt-get update -q; sudo apt-get install -yq make build-essential \ - libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \ - curl llvm libncurses5-dev libncursesw5-dev \ - xz-utils tk-dev libffi-dev liblzma-dev + pyenv install-prerequisites if [[ "${{ matrix.python-version }}" =~ pypy.*-(src|dev) ]]; then export PYENV_BOOTSTRAP_VERSION=pypy2.7-7 echo "PYENV_BOOTSTRAP_VERSION=$PYENV_BOOTSTRAP_VERSION" >> $GITHUB_ENV @@ -283,10 +280,7 @@ jobs: echo "_PYTHON_BUILD_FORCE_SKIP_XZ=1" >> $GITHUB_ENV - run: | #prerequisites - sudo apt-get update -q; sudo apt-get install -yq make build-essential \ - libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \ - curl libncursesw5-dev \ - xz-utils tk-dev libffi-dev liblzma-dev + pyenv install-prerequisites - run: | #build pyenv --debug install ${{ matrix.python-version }} && rc=$? || rc=$? diff --git a/plugins/python-build/README.md b/plugins/python-build/README.md index 3c95d793..e0a333b3 100644 --- a/plugins/python-build/README.md +++ b/plugins/python-build/README.md @@ -54,8 +54,11 @@ Or, if you would like to install the latest development release: ## Usage -Before you begin, you should ensure that your build environment has the proper -system dependencies for compiling the wanted Python Version (see our [recommendations](https://github.com/pyenv/pyenv/wiki#suggested-build-environment)). +On Ubuntu, Debian, and Mint, install the recommended build dependencies with: + + pyenv install-prerequisites + +For other environments, see our [build environment recommendations](https://github.com/pyenv/pyenv/wiki#suggested-build-environment). ### Using `pyenv install` with pyenv @@ -361,4 +364,3 @@ git diff --name-only master \ - Filter out any which don't live where python-build keeps its build scripts - Look only at the file name (i.e. the python version name) - Run a new docker container for each, building that version - diff --git a/plugins/python-build/bin/pyenv-install-prerequisites b/plugins/python-build/bin/pyenv-install-prerequisites new file mode 100755 index 00000000..c56bbd98 --- /dev/null +++ b/plugins/python-build/bin/pyenv-install-prerequisites @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# +# Summary: Install Python build prerequisites on Debian-based systems +# +# Usage: pyenv install-prerequisites +# +set -e +[ -n "$PYENV_DEBUG" ] && set -x + +# Provide pyenv completions +if [ "$1" = "--complete" ]; then + exit +fi + +usage() { + pyenv-help install-prerequisites 2>/dev/null + [ -z "$1" ] || exit "$1" +} + +if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + usage 0 +fi + +[ "$#" -eq 0 ] || usage 1 >&2 + +if ! command -v apt-get >/dev/null; then + echo "pyenv: installing build prerequisites is not supported on this system" >&2 + exit 1 +fi + +prerequisites=( + make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev + libsqlite3-dev curl git llvm libncurses5-dev libncursesw5-dev xz-utils + tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev libzstd-dev +) + +if [ "$(id -u)" -eq 0 ]; then + apt_get=(apt-get) +elif command -v sudo >/dev/null; then + apt_get=(sudo apt-get) +else + echo "pyenv: sudo is required to install build prerequisites" >&2 + exit 1 +fi + +"${apt_get[@]}" update -q +"${apt_get[@]}" install -yq "${prerequisites[@]}" diff --git a/plugins/python-build/test/install-prerequisites.bats b/plugins/python-build/test/install-prerequisites.bats new file mode 100644 index 00000000..2630c238 --- /dev/null +++ b/plugins/python-build/test/install-prerequisites.bats @@ -0,0 +1,83 @@ +#!/usr/bin/env bats + +load test_helper + +_setup() { + prerequisites="make build-essential libssl-dev zlib1g-dev libbz2-dev \ +libreadline-dev libsqlite3-dev curl git llvm libncurses5-dev \ +libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev \ +liblzma-dev libzstd-dev" +} + +@test "completion does not install packages" { + stub apt-get + + PATH="${BATS_TEST_DIRNAME}/../../../libexec:$PATH" \ + run pyenv completions install-prerequisites + + assert_success "--help" + unstub apt-get +} + +@test "supports help" { + stub pyenv-help 'install-prerequisites : echo "Usage: pyenv install-prerequisites"' + + run pyenv-install-prerequisites --help + + assert_success "Usage: pyenv install-prerequisites" + unstub pyenv-help +} + +@test "rejects arguments" { + stub pyenv-help 'install-prerequisites : echo "Usage: pyenv install-prerequisites"' + + run pyenv-install-prerequisites unexpected + + assert_failure "Usage: pyenv install-prerequisites" + unstub pyenv-help +} + +@test "installs build prerequisites with apt-get as root" { + stub id '-u : echo 0' + stub apt-get \ + 'update -q : true' \ + "install -yq ${prerequisites} : true" + + run pyenv-install-prerequisites + + assert_success + unstub apt-get + unstub id +} + +@test "uses sudo when not running as root" { + stub id '-u : echo 1000' + stub apt-get + stub sudo \ + 'apt-get update -q : true' \ + "apt-get install -yq ${prerequisites} : true" + + run pyenv-install-prerequisites + + assert_success + unstub sudo + unstub apt-get + unstub id +} + +@test "fails when apt-get is unavailable" { + PATH="$(path_without apt-get)" run pyenv-install-prerequisites + + assert_failure "pyenv: installing build prerequisites is not supported on this system" +} + +@test "fails when sudo is unavailable for an unprivileged user" { + stub id '-u : echo 1000' + stub apt-get + + PATH="$(path_without sudo)" run pyenv-install-prerequisites + + assert_failure "pyenv: sudo is required to install build prerequisites" + unstub apt-get + unstub id +} diff --git a/plugins/python-build/test/test_helper.bash b/plugins/python-build/test/test_helper.bash index a72806ab..5b36e7e9 100644 --- a/plugins/python-build/test/test_helper.bash +++ b/plugins/python-build/test/test_helper.bash @@ -2,6 +2,7 @@ setup() { export PYTHON_BUILD_CURL_OPTS= export PYTHON_BUILD_HTTP_CLIENT="curl" + export PYENV_TEST_DIR="${BATS_TEST_TMPDIR}/pyenv" export FIXTURE_ROOT="${BATS_TEST_DIRNAME}/fixtures" export INSTALL_ROOT="${BATS_TEST_TMPDIR}/install" PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" @@ -148,7 +149,7 @@ path_without() { if [ "$found" != "${PYENV_ROOT}/shims" ]; then alt="${PYENV_TEST_DIR}/$(echo "${found#/}" | tr '/' '-')" mkdir -p "$alt" - for util in bash head cut readlink greadlink; do + for util in bash head cut readlink greadlink tr; do if [ -x "${found}/$util" ]; then ln -s "${found}/$util" "${alt}/$util" fi