From 3493a60290e7f45b25f061b6ab0b8b65d2c58a72 Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Thu, 11 Jun 2020 15:33:36 +0200 Subject: [PATCH 01/13] Add bootstrap script to install dependencies relative to ReFrame This allows to run ReFrame out-of-the-box using a single preparation step: ``` ./bootstrap.sh ./bin/reframe -l ``` No need for Python virtual environments. --- bin/reframe | 23 ++++++++++++++++++++++- reframe.py | 11 ----------- test_reframe.py | 20 +++++++++++++++++--- 3 files changed, 39 insertions(+), 15 deletions(-) mode change 120000 => 100755 bin/reframe delete mode 100755 reframe.py diff --git a/bin/reframe b/bin/reframe deleted file mode 120000 index b048b4014d..0000000000 --- a/bin/reframe +++ /dev/null @@ -1 +0,0 @@ -../reframe.py \ No newline at end of file diff --git a/bin/reframe b/bin/reframe new file mode 100755 index 0000000000..0a79c77bcc --- /dev/null +++ b/bin/reframe @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +# +# Copyright 2016-2020 Swiss National Supercomputing Centre (CSCS/ETH Zurich) +# ReFrame Project Developers. See the top-level LICENSE file for details. +# +# SPDX-License-Identifier: BSD-3-Clause + +import os +import sys + +prefix = os.path.join(os.path.abspath(os.path.dirname(__file__)), '..') +pymajver = sys.version_info.major +pyminver = sys.version_info.minor +external = os.path.join(prefix, 'external', 'lib', + f'python{pymajver}.{pyminver}', 'site-packages') +sys.path = [prefix, external] + sys.path + + +import reframe.frontend.cli as cli # noqa: F401, F403 + +if __name__ == '__main__': + cli.main() diff --git a/reframe.py b/reframe.py deleted file mode 100755 index 6432fde51a..0000000000 --- a/reframe.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2016-2020 Swiss National Supercomputing Centre (CSCS/ETH Zurich) -# ReFrame Project Developers. See the top-level LICENSE file for details. -# -# SPDX-License-Identifier: BSD-3-Clause - -import reframe.frontend.cli as cli - -if __name__ == '__main__': - cli.main() diff --git a/test_reframe.py b/test_reframe.py index c11fb50bdb..28d77edb2c 100755 --- a/test_reframe.py +++ b/test_reframe.py @@ -5,12 +5,19 @@ # # SPDX-License-Identifier: BSD-3-Clause -import argparse import os -import pytest import sys -import unittests.fixtures as fixtures +prefix = os.path.abspath(os.path.dirname(__file__)) +pymajver = sys.version_info.major +pyminver = sys.version_info.minor +external = os.path.join(prefix, 'external', 'lib', + f'python{pymajver}.{pyminver}', 'site-packages') +sys.path = [prefix, external] + sys.path + +import argparse # noqa: F401, F403 +import pytest # noqa: F401, F403 +import unittests.fixtures as fixtures # noqa: F401, F403 if __name__ == '__main__': @@ -38,5 +45,12 @@ fixtures.USER_CONFIG_FILE = options.rfm_user_config fixtures.USER_SYSTEM = options.rfm_user_system fixtures.init_runtime() + + # If no positional argument is specified, use the `unittests` directory, + # so as to avoid any automatic discovery of random unit tests from the + # external dependencies. + if all(arg.startswith('-') for arg in rem_args): + rem_args.append('unittests') + sys.argv = [sys.argv[0], *rem_args] sys.exit(pytest.main()) From 70b35118155b741d182e320d8efe8fb1d7a0941d Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Thu, 11 Jun 2020 19:46:45 +0200 Subject: [PATCH 02/13] Adapt docs/conf.py --- docs/conf.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 062ead4fc8..d6191b4fdd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -29,7 +29,12 @@ import sphinx_rtd_theme -sys.path.insert(0, os.path.abspath('..')) +prefix = os.path.join(os.path.abspath(os.path.dirname(__file__)), '..') +pymajver = sys.version_info.major +pyminver = sys.version_info.minor +external = os.path.join(prefix, 'external', 'lib', + f'python{pymajver}.{pyminver}', 'site-packages') +sys.path = [prefix, external] + sys.path import reframe # noqa: F401, F403 import reframe.utility.os_ext as os_ext # noqa: F401, F403 From 1b7e73161be9c9fe013367c21555964616600e3b Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Thu, 11 Jun 2020 23:13:31 +0200 Subject: [PATCH 03/13] Add bootstrap.sh --- bootstrap.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100755 bootstrap.sh diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 0000000000..1ae3b52b5b --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# +# Copyright 2016-2020 Swiss National Supercomputing Centre (CSCS/ETH Zurich) +# ReFrame Project Developers. See the top-level LICENSE file for details. +# +# SPDX-License-Identifier: BSD-3-Clause + +# +# Bootstrap script for running ReFrame from source +# +# Run once before the first run. + +pip3 install --upgrade pip +pip3 install -r requirements.txt --prefix=external/ + +if [ x"$1" == x"+docs" ]; then + pip3 install -r docs/requirements.txt --prefix=external/ +fi From ee72816a49592fad17c1c529cb0ad6779bf06722 Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Fri, 12 Jun 2020 18:49:03 +0200 Subject: [PATCH 04/13] Make documentation in the bootstrap script --- bootstrap.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/bootstrap.sh b/bootstrap.sh index 1ae3b52b5b..4a627f47ba 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -15,4 +15,5 @@ pip3 install -r requirements.txt --prefix=external/ if [ x"$1" == x"+docs" ]; then pip3 install -r docs/requirements.txt --prefix=external/ + make -C docs fi From 2c4af152d9bff7088ae46d17a7a20015393f0487 Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Fri, 12 Jun 2020 22:37:09 +0200 Subject: [PATCH 05/13] Improve bootstrap script --- bootstrap.sh | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 1ae3b52b5b..e09e87f01b 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -10,9 +10,41 @@ # # Run once before the first run. -pip3 install --upgrade pip -pip3 install -r requirements.txt --prefix=external/ +CMD() +{ + echo '==>' $* && $* +} + +usage() +{ + echo "Usage: $0 [-h] [+docs]" + echo "Bootstrap ReFrame; \ +run once before invoking ReFrame for the first time" + echo " -h Print this help message and exit" + echo " +docs Build also the documentation" +} + + +while getopts "h" opt; do + case $opt in + "h") usage && exit 0 ;; + "?") usage && exit 0 ;; + esac +done + +shift $((OPTIND - 1)) + +pyver=$(python3 -V | sed -n 's/Python \([0-9]\+\)\.\([0-9]\+\)\..*/\1.\2/p') + +# Install pip for Python 3 +CMD python3 -m ensurepip --root external/ --default-pip + +export PATH=external/usr/bin:$PATH +export PYTHONPATH=external/usr/lib/python$pyver/site-packages:$PYTHONPATH + +CMD pip install --upgrade pip --target=external/ +CMD pip install -r requirements.txt --target=external/ if [ x"$1" == x"+docs" ]; then - pip3 install -r docs/requirements.txt --prefix=external/ + CMD pip install -r docs/requirements.txt --target=external/ fi From 40992b9ae4249d316f70eea6aef6465a412fccbc Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Fri, 12 Jun 2020 22:56:12 +0200 Subject: [PATCH 06/13] Improve bootstrap.sh --- bin/reframe | 5 +---- bootstrap.sh | 11 ++++++----- docs/conf.py | 3 +-- test_reframe.py | 5 +---- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/bin/reframe b/bin/reframe index 0a79c77bcc..9cfd074e1c 100755 --- a/bin/reframe +++ b/bin/reframe @@ -9,10 +9,7 @@ import os import sys prefix = os.path.join(os.path.abspath(os.path.dirname(__file__)), '..') -pymajver = sys.version_info.major -pyminver = sys.version_info.minor -external = os.path.join(prefix, 'external', 'lib', - f'python{pymajver}.{pyminver}', 'site-packages') +external = os.path.join(prefix, 'external') sys.path = [prefix, external] + sys.path diff --git a/bootstrap.sh b/bootstrap.sh index 9d5f01691b..a1adf1f9b6 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -39,13 +39,14 @@ pyver=$(python3 -V | sed -n 's/Python \([0-9]\+\)\.\([0-9]\+\)\..*/\1.\2/p') # Install pip for Python 3 CMD python3 -m ensurepip --root external/ --default-pip -export PATH=external/usr/bin:$PATH -export PYTHONPATH=external/usr/lib/python$pyver/site-packages:$PYTHONPATH +export PATH=external/bin:$PATH +#export PYTHONPATH=external/usr/lib/python$pyver/site-packages:$PYTHONPATH +export PYTHONPATH=external/:$PYTHONPATH -CMD pip install --upgrade pip --target=external/ -CMD pip install -r requirements.txt --target=external/ +CMD pip install -q --upgrade pip --target=external/ +CMD pip install -q -r requirements.txt --upgrade --target=external/ if [ x"$1" == x"+docs" ]; then - CMD pip install -r docs/requirements.txt --target=external/ + CMD pip install -q -r docs/requirements.txt --upgrade --target=external/ make -C docs fi diff --git a/docs/conf.py b/docs/conf.py index d6191b4fdd..ebcd3c143f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -32,8 +32,7 @@ prefix = os.path.join(os.path.abspath(os.path.dirname(__file__)), '..') pymajver = sys.version_info.major pyminver = sys.version_info.minor -external = os.path.join(prefix, 'external', 'lib', - f'python{pymajver}.{pyminver}', 'site-packages') +external = os.path.join(prefix, 'external') sys.path = [prefix, external] + sys.path import reframe # noqa: F401, F403 diff --git a/test_reframe.py b/test_reframe.py index 28d77edb2c..1af267c818 100755 --- a/test_reframe.py +++ b/test_reframe.py @@ -9,10 +9,7 @@ import sys prefix = os.path.abspath(os.path.dirname(__file__)) -pymajver = sys.version_info.major -pyminver = sys.version_info.minor -external = os.path.join(prefix, 'external', 'lib', - f'python{pymajver}.{pyminver}', 'site-packages') +external = os.path.join(prefix, 'external') sys.path = [prefix, external] + sys.path import argparse # noqa: F401, F403 From 89935364c871cc551316c3291c27afde49dab42a Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Sat, 13 Jun 2020 00:38:58 +0200 Subject: [PATCH 07/13] Fix bootstrap script for Daint/Dom --- bootstrap.sh | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index a1adf1f9b6..8a5e17eb74 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -8,18 +8,21 @@ # # Bootstrap script for running ReFrame from source # -# Run once before the first run. + +BLUE='\033[0;34m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +NC='\033[0m' CMD() { - echo '==>' $* && $* + echo -e "${BLUE}==>${NC}" ${YELLOW}$*${NC} && $* } usage() { echo "Usage: $0 [-h] [+docs]" - echo "Bootstrap ReFrame; \ -run once before invoking ReFrame for the first time" + echo "Bootstrap ReFrame by pulling all its dependencies" echo " -h Print this help message and exit" echo " +docs Build also the documentation" } @@ -33,20 +36,21 @@ while getopts "h" opt; do done shift $((OPTIND - 1)) - pyver=$(python3 -V | sed -n 's/Python \([0-9]\+\)\.\([0-9]\+\)\..*/\1.\2/p') # Install pip for Python 3 CMD python3 -m ensurepip --root external/ --default-pip -export PATH=external/bin:$PATH -#export PYTHONPATH=external/usr/lib/python$pyver/site-packages:$PYTHONPATH -export PYTHONPATH=external/:$PYTHONPATH +# ensurepip installs pip in `external/usr/` whereas the --target option installs +# everything under `external/`. That's why include both in the PYTHONPATH + +export PATH=$(pwd)/external/usr/bin:$PATH +export PYTHONPATH=$(pwd)/external:$(pwd)/external/usr/lib/python$pyver/site-packages:$PYTHONPATH -CMD pip install -q --upgrade pip --target=external/ -CMD pip install -q -r requirements.txt --upgrade --target=external/ +CMD python3 -m pip install -q --upgrade pip --target=external/ +CMD python3 -m pip install -q -r requirements.txt --target=external/ --upgrade if [ x"$1" == x"+docs" ]; then - CMD pip install -q -r docs/requirements.txt --upgrade --target=external/ + CMD python3 -m pip install -q -r docs/requirements.txt --target=external/ --upgrade make -C docs fi From 4afa780d0815c35ab21370da7887f5a223d067d0 Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Sat, 13 Jun 2020 14:07:44 +0200 Subject: [PATCH 08/13] Adapt CI deployment script --- ci-scripts/deploy.sh | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/ci-scripts/deploy.sh b/ci-scripts/deploy.sh index 85130b7c1f..4b1f684407 100755 --- a/ci-scripts/deploy.sh +++ b/ci-scripts/deploy.sh @@ -35,23 +35,29 @@ tmpdir=$(mktemp -d) echo "Deploying ReFrame version $version ..." echo "Working directory: $tmpdir ..." cd $tmpdir -git clone https://github.com/eth-cscs/reframe.git +git clone https://github.com/vkarak/reframe.git cd reframe -found_version=$(./reframe.py -V | sed -e 's/ (.*)//g') +git checkout feat/immediate-install-ci-script +./bootstrap.sh +found_version=$(./bin/reframe -V | sed -e 's/ (.*)//g') if [ $found_version != $version ]; then echo "$0: version mismatch: found $found_version, but required $version" >&2 exit 1 fi -python3 -m venv venv.deployment -source venv.deployment/bin/activate -pip install --upgrade pip setuptools wheel twine -pip install -r requirements.txt ./test_reframe.py git tag -a v$version -m "ReFrame $version" git push origin --tags -python setup.py sdist bdist_wheel -twine upload dist/* + +# We need this for running the setup.py of ReFrame +export PYTHONPATH=$(pwd)/external:$PYTHONPATH + +# We create a virtual environment here just for the deployment +python3 -m venv venv.deployment +source venv.deployment/bin/activate +python3 -m pip install --upgrade pip setuptools wheel twine +python3 setup.py sdist bdist_wheel +python3 -m twine upload dist/* deactivate cd $oldpwd echo "Deployment was successful!" From 7a0405d6263f91a010456f337460a1f3ef8e4b05 Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Sat, 13 Jun 2020 15:02:40 +0200 Subject: [PATCH 09/13] Revert temporary changes to ReFrame repository and deployment branch --- ci-scripts/deploy.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ci-scripts/deploy.sh b/ci-scripts/deploy.sh index 4b1f684407..e1fd427bbe 100755 --- a/ci-scripts/deploy.sh +++ b/ci-scripts/deploy.sh @@ -35,9 +35,8 @@ tmpdir=$(mktemp -d) echo "Deploying ReFrame version $version ..." echo "Working directory: $tmpdir ..." cd $tmpdir -git clone https://github.com/vkarak/reframe.git +git clone https://github.com/eth-cscs/reframe.git cd reframe -git checkout feat/immediate-install-ci-script ./bootstrap.sh found_version=$(./bin/reframe -V | sed -e 's/ (.*)//g') if [ $found_version != $version ]; then From f2ee93983ae80ac5021e77fb8377ea99c6563c93 Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Sat, 13 Jun 2020 19:33:14 +0200 Subject: [PATCH 10/13] Adapt CI runner script --- ci-scripts/ci-runner.bash | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/ci-scripts/ci-runner.bash b/ci-scripts/ci-runner.bash index f7ff3623f6..8bc2276974 100644 --- a/ci-scripts/ci-runner.bash +++ b/ci-scripts/ci-runner.bash @@ -132,14 +132,8 @@ else module load reframe fi -# Always install our requirements -python3 -m venv venv.unittests -source venv.unittests/bin/activate -pip install --upgrade pip -pip install -r requirements.txt - -# FIXME: XALT is causing linking problems (see UES-823) -module unload xalt +# Bootstrap ReFrame +./bootstrap.sh echo "[INFO] Loaded Modules" module list @@ -216,5 +210,4 @@ else done fi fi -deactivate exit $CI_EXITCODE From 94969dbb99d8341fe497f37bb9449dfb9ce4d50f Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Sat, 13 Jun 2020 20:01:00 +0200 Subject: [PATCH 11/13] Update README --- README.md | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index aeab704d15..4b0cff47ce 100644 --- a/README.md +++ b/README.md @@ -29,25 +29,37 @@ Users can create their own test hierarchies, create test factories for generatin ## Getting ReFrame -You may install ReFrame directly from [PyPI](https://pypi.org/project/ReFrame-HPC/) through `pip`: +ReFrame is almost ready to run just after you clone it from Github. +All you need is Python 3.6 or above and to run its bootstrap script: ```bash -pip install reframe-hpc +git clone https://github.com/eth-cscs/reframe.git +cd reframe +./bootstrap.sh +./bin/reframe -V ``` -ReFrame will be available in your PATH: +### Other installation ways -```bash -reframe -V -``` +You can also install ReFrame through the following channels: -Alternatively, and especially if you want to contribute back to the framework, you may clone this repository: +- Through [PyPI](https://pypi.org/project/ReFrame-HPC/): -```bash -git clone https://github.com/eth-cscs/reframe.git -cd reframe -./bin/reframe -V -``` + ``` + pip install reframe-hpc + ``` + +- Through [Spack](https://spack.io/): + + ``` + spack install reframe + ``` + +- Through [EasyBuild](https://easybuild.readthedocs.io/): + + ``` + eb easybuild/easyconfigs/r/ReFrame/ReFrame-VERSION.eb -r + ``` Finally, you may access all previous versions of ReFrame [here](https://github.com/eth-cscs/reframe/releases). @@ -57,24 +69,22 @@ Finally, you may access all previous versions of ReFrame [here](https://github.c You may find the official documentation of the latest release and the current master in the following links: - [Latest release](https://reframe-hpc.readthedocs.io/en/stable) -- [Current master](https://reframe-hpc.readthedocs.io) +- [Current master](https://reframe-hpc.readthedocs.io/en/latest) ### Building the documentation locally -You may build the documentation of the master locally either with Python 2 or Python 3. -Here is how to do it: +You may build the documentation of the master manually as follows: ``` -pip install -r docs/requirements.txt -make -C docs latest +./bootstrap.sh +docs ``` For viewing it, you may do the following: ``` cd docs/html -python -m http.server # or python -m SimpleHTTPServer for Python 2 +python3 -m http.server ``` The documentation is now up on [localhost:8000](http://localhost:8000), where you can navigate with your browser. From d50b65dcb9f59dafd4a0dbc1e126e78620b8910d Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Sat, 13 Jun 2020 20:13:22 +0200 Subject: [PATCH 12/13] Update documentation on how to install ReFrame from source --- docs/started.rst | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/docs/started.rst b/docs/started.rst index 1a9b386a71..d57075fc1a 100644 --- a/docs/started.rst +++ b/docs/started.rst @@ -7,11 +7,8 @@ Requirements * Python 3.6 or higher. Python 2 is not supported. -* Required Python packages can be found in the ``requirements.txt`` file, which you can install as follows: - - .. code:: bash - - pip3 install -r requirements.txt +* Required Python packages can be found in the ``requirements.txt`` file. + See :ref:`install-from-source` for more information on how to install ReFrame from source. --------------------- @@ -63,6 +60,8 @@ ReFrame's latest stable version is available through different channels: eb easybuild/easyconfigs/r/ReFrame/ReFrame-VERSION.eb -r +.. _install-from-source: + ------------------------------- Getting the Latest and Greatest ------------------------------- @@ -71,10 +70,23 @@ If you want the latest development version or any pre-release, you can clone ReF .. code:: bash - git clone https://github.com/eth-cscs/reframe.git + git clone https://github.com/eth-cscs/reframe.git Pre-release versions are denoted with the ``devX`` suffix and are `tagged `__ in the repository. +Preparing and running ReFrame from source is pretty straightforward: + +.. code:: bash + + git clone https://github.com/eth-cscs/reframe.git + cd reframe + ./bootstrap.sh + ./bin/reframe -V + +.. note:: + .. versionadded:: 3.1 + The bootstrap script for ReFrame was added. + For previous ReFrame versions you should install its requirements using ``pip install -r requirements.txt`` in a Python virtual environment. Running the Unit Tests From 39e2043aee3d3122ed38f86dcaeb8863559ef7e9 Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Mon, 15 Jun 2020 15:56:51 +0200 Subject: [PATCH 13/13] Allow a custom Python executable in the bootstrap script --- bootstrap.sh | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 8a5e17eb74..77372c2619 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -23,23 +23,29 @@ usage() { echo "Usage: $0 [-h] [+docs]" echo "Bootstrap ReFrame by pulling all its dependencies" - echo " -h Print this help message and exit" - echo " +docs Build also the documentation" + echo " -P EXEC Use EXEC as Python interpreter" + echo " -h Print this help message and exit" + echo " +docs Build also the documentation" } -while getopts "h" opt; do +while getopts "hP:" opt; do case $opt in + "P") python=$OPTARG ;; "h") usage && exit 0 ;; "?") usage && exit 0 ;; esac done shift $((OPTIND - 1)) -pyver=$(python3 -V | sed -n 's/Python \([0-9]\+\)\.\([0-9]\+\)\..*/\1.\2/p') +if [ -z $python ]; then + python=python3 +fi + +pyver=$($python -V | sed -n 's/Python \([0-9]\+\)\.\([0-9]\+\)\..*/\1.\2/p') # Install pip for Python 3 -CMD python3 -m ensurepip --root external/ --default-pip +CMD $python -m ensurepip --root external/ --default-pip # ensurepip installs pip in `external/usr/` whereas the --target option installs # everything under `external/`. That's why include both in the PYTHONPATH @@ -47,10 +53,10 @@ CMD python3 -m ensurepip --root external/ --default-pip export PATH=$(pwd)/external/usr/bin:$PATH export PYTHONPATH=$(pwd)/external:$(pwd)/external/usr/lib/python$pyver/site-packages:$PYTHONPATH -CMD python3 -m pip install -q --upgrade pip --target=external/ -CMD python3 -m pip install -q -r requirements.txt --target=external/ --upgrade +CMD $python -m pip install -q --upgrade pip --target=external/ +CMD $python -m pip install -q -r requirements.txt --target=external/ --upgrade if [ x"$1" == x"+docs" ]; then - CMD python3 -m pip install -q -r docs/requirements.txt --target=external/ --upgrade + CMD $python -m pip install -q -r docs/requirements.txt --target=external/ --upgrade make -C docs fi