From 5df7a3628ccfd2a7d521d31f5d36163e1c145c10 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 00:30:11 +0200 Subject: [PATCH 01/51] Document pipfile(.lock) as an option --- docs/source/config_files.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/source/config_files.rst b/docs/source/config_files.rst index 5af8e02a3..2019687d6 100644 --- a/docs/source/config_files.rst +++ b/docs/source/config_files.rst @@ -54,6 +54,22 @@ though ``repo2docker`` support is best with Python 3.7, 3.6, 3.5 and 2.7. If you include a Python version in a ``runtime.txt`` file in addition to your ``environment.yml``, your ``runtime.txt`` will be ignored. +.. _Pipfile: + +``Pipfile`` and/or ``Pipfile.lock`` - Install a Python environment +================================================================== + +``Pipfile`` and/or ``Pipfile.lock`` specifies a list of Python packages that +should be installed in your environment. ``pipenv install --dev`` will be run to +install the dependencies where the existence of a ``Pipfile.lock`` will make the +``Pipfile`` be ignored. + +.. note:: + + `pipenv `_ and `virtualenv + `_ and associated ``requirements.txt`` + files are both managed by the Python Packaging Authority PyPA, where pipenv + and ``Pipfile`` and ``Pipfile.lock`` seem to be the modern solution. .. _requirements.txt: From 4c69bf1dfd3553d69e5843205e28794b28844114 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 00:53:40 +0200 Subject: [PATCH 02/51] Add tests for Pipenv --- tests/venv/pipfile/environment-yml/Pipfile | 10 ++++++++++ tests/venv/pipfile/environment-yml/README.rst | 6 ++++++ tests/venv/pipfile/environment-yml/environment.yml | 2 ++ tests/venv/pipfile/environment-yml/verify | 2 ++ tests/venv/pipfile/requirements-txt/Pipfile | 10 ++++++++++ tests/venv/pipfile/requirements-txt/README.rst | 5 +++++ tests/venv/pipfile/requirements-txt/requirements.txt | 1 + tests/venv/pipfile/requirements-txt/verify | 3 +++ tests/venv/pipfile/setup-py/Pipfile | 10 ++++++++++ tests/venv/pipfile/setup-py/README.rst | 5 +++++ tests/venv/pipfile/setup-py/dummy/__init__.py | 2 ++ tests/venv/pipfile/setup-py/setup.py | 12 ++++++++++++ tests/venv/pipfile/setup-py/verify | 4 ++++ 13 files changed, 72 insertions(+) create mode 100644 tests/venv/pipfile/environment-yml/Pipfile create mode 100644 tests/venv/pipfile/environment-yml/README.rst create mode 100644 tests/venv/pipfile/environment-yml/environment.yml create mode 100755 tests/venv/pipfile/environment-yml/verify create mode 100644 tests/venv/pipfile/requirements-txt/Pipfile create mode 100644 tests/venv/pipfile/requirements-txt/README.rst create mode 100644 tests/venv/pipfile/requirements-txt/requirements.txt create mode 100755 tests/venv/pipfile/requirements-txt/verify create mode 100644 tests/venv/pipfile/setup-py/Pipfile create mode 100644 tests/venv/pipfile/setup-py/README.rst create mode 100644 tests/venv/pipfile/setup-py/dummy/__init__.py create mode 100644 tests/venv/pipfile/setup-py/setup.py create mode 100755 tests/venv/pipfile/setup-py/verify diff --git a/tests/venv/pipfile/environment-yml/Pipfile b/tests/venv/pipfile/environment-yml/Pipfile new file mode 100644 index 000000000..1a9426575 --- /dev/null +++ b/tests/venv/pipfile/environment-yml/Pipfile @@ -0,0 +1,10 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +requests = "*" + +[dev-packages] +there = "*" diff --git a/tests/venv/pipfile/environment-yml/README.rst b/tests/venv/pipfile/environment-yml/README.rst new file mode 100644 index 000000000..b5cb5c530 --- /dev/null +++ b/tests/venv/pipfile/environment-yml/README.rst @@ -0,0 +1,6 @@ +Python - Pipfile(.lock) + environment.yml +----------------------------------------- + +We should ignore the ``Pipfile`` or ``Pipfile.lock`` if there is an +``environment.yml`` alongside it. Conda can install more things than ``pip`` or +``pipenv`` can so we would limit ourselves if we prioritized the ``Pipfile``s. diff --git a/tests/venv/pipfile/environment-yml/environment.yml b/tests/venv/pipfile/environment-yml/environment.yml new file mode 100644 index 000000000..6a91d667f --- /dev/null +++ b/tests/venv/pipfile/environment-yml/environment.yml @@ -0,0 +1,2 @@ +dependencies: + - numpy diff --git a/tests/venv/pipfile/environment-yml/verify b/tests/venv/pipfile/environment-yml/verify new file mode 100755 index 000000000..06b4510ab --- /dev/null +++ b/tests/venv/pipfile/environment-yml/verify @@ -0,0 +1,2 @@ +#!/usr/bin/env python +import numpy diff --git a/tests/venv/pipfile/requirements-txt/Pipfile b/tests/venv/pipfile/requirements-txt/Pipfile new file mode 100644 index 000000000..1a9426575 --- /dev/null +++ b/tests/venv/pipfile/requirements-txt/Pipfile @@ -0,0 +1,10 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +requests = "*" + +[dev-packages] +there = "*" diff --git a/tests/venv/pipfile/requirements-txt/README.rst b/tests/venv/pipfile/requirements-txt/README.rst new file mode 100644 index 000000000..7c1ca0d71 --- /dev/null +++ b/tests/venv/pipfile/requirements-txt/README.rst @@ -0,0 +1,5 @@ +Python - Pipfile(.lock) + requirements.txt +------------------------------------------ + +We should make ``Pipfile``` or ``Pipfile.lock`` take precedence over +``requirements.txt``. diff --git a/tests/venv/pipfile/requirements-txt/requirements.txt b/tests/venv/pipfile/requirements-txt/requirements.txt new file mode 100644 index 000000000..24ce15ab7 --- /dev/null +++ b/tests/venv/pipfile/requirements-txt/requirements.txt @@ -0,0 +1 @@ +numpy diff --git a/tests/venv/pipfile/requirements-txt/verify b/tests/venv/pipfile/requirements-txt/verify new file mode 100755 index 000000000..3ce4a99f6 --- /dev/null +++ b/tests/venv/pipfile/requirements-txt/verify @@ -0,0 +1,3 @@ +#!/usr/bin/env python +import requests +import there diff --git a/tests/venv/pipfile/setup-py/Pipfile b/tests/venv/pipfile/setup-py/Pipfile new file mode 100644 index 000000000..1a9426575 --- /dev/null +++ b/tests/venv/pipfile/setup-py/Pipfile @@ -0,0 +1,10 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +requests = "*" + +[dev-packages] +there = "*" diff --git a/tests/venv/pipfile/setup-py/README.rst b/tests/venv/pipfile/setup-py/README.rst new file mode 100644 index 000000000..dfde617cb --- /dev/null +++ b/tests/venv/pipfile/setup-py/README.rst @@ -0,0 +1,5 @@ +Python - Pipfile(.lock) + setup.py +---------------------------------- + +We should make ``setup.py`` be installed after the ``Pipfile`` or +``Pipfile.lock``. diff --git a/tests/venv/pipfile/setup-py/dummy/__init__.py b/tests/venv/pipfile/setup-py/dummy/__init__.py new file mode 100644 index 000000000..012898812 --- /dev/null +++ b/tests/venv/pipfile/setup-py/dummy/__init__.py @@ -0,0 +1,2 @@ +def dummy(): + pass diff --git a/tests/venv/pipfile/setup-py/setup.py b/tests/venv/pipfile/setup-py/setup.py new file mode 100644 index 000000000..a49ce6f8a --- /dev/null +++ b/tests/venv/pipfile/setup-py/setup.py @@ -0,0 +1,12 @@ +from setuptools import setup, find_packages + +setup( + name='Dummy', + version='1.0.0', + url='https://git-place.org/dummy/dummy.git', + author='Dummy Name', + author_email='dummy@my-email.com', + description='Dummy package for testing purposes only', + packages=find_packages(), + install_requires=['numpy'], +) diff --git a/tests/venv/pipfile/setup-py/verify b/tests/venv/pipfile/setup-py/verify new file mode 100755 index 000000000..0cdf0e217 --- /dev/null +++ b/tests/venv/pipfile/setup-py/verify @@ -0,0 +1,4 @@ +#!/usr/bin/env python +import requests +import there +import dummy From 301d1524cbb65e4e672035426e8640462437cd16 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 11:12:50 +0200 Subject: [PATCH 03/51] Add Pipfile's to PythonBuildPack's detect() --- repo2docker/buildpacks/python/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/repo2docker/buildpacks/python/__init__.py b/repo2docker/buildpacks/python/__init__.py index 7ab48e2ac..a513db7fe 100644 --- a/repo2docker/buildpacks/python/__init__.py +++ b/repo2docker/buildpacks/python/__init__.py @@ -78,6 +78,8 @@ def get_assemble_scripts(self): def detect(self): """Check if current repo should be built with the Python buildpack. """ + pipfile = self.binder_path('Pipfile') + pipfile_lock = self.binder_path('Pipfile.lock') requirements_txt = self.binder_path('requirements.txt') runtime_txt = self.binder_path('runtime.txt') setup_py = 'setup.py' @@ -91,4 +93,4 @@ def detect(self): return False if not os.path.exists('binder') and os.path.exists(setup_py): return True - return os.path.exists(requirements_txt) + return os.path.exists(pipfile) or os.path.exists(pipfile_lock) or os.path.exists(requirements_txt) From f995a995a998476d3d6b2a3fb1cc990a6022e614 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 11:29:39 +0200 Subject: [PATCH 04/51] Add Pipfile vs requirements.txt logic --- repo2docker/buildpacks/python/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/repo2docker/buildpacks/python/__init__.py b/repo2docker/buildpacks/python/__init__.py index a513db7fe..099c0c5ec 100644 --- a/repo2docker/buildpacks/python/__init__.py +++ b/repo2docker/buildpacks/python/__init__.py @@ -58,9 +58,13 @@ def get_assemble_scripts(self): '${{NB_PYTHON_PREFIX}}/bin/pip install --no-cache-dir -r "{}"'.format(nb_requirements_file) )) - # install requirements.txt in the kernel env + # install Pipfile.lock, Pipfile, or requirements.txt in the kernel env + pipfile = self.binder_path('Pipfile') + pipfile_lock = self.binder_path('Pipfile.lock') requirements_file = self.binder_path('requirements.txt') - if os.path.exists(requirements_file): + if os.path.exists(pipfile) or os.path.exists(pipfile_lock): + pass + elif os.path.exists(requirements_file): assemble_scripts.append(( '${NB_USER}', 'pip install "pip<19" && ' + \ From c5dd7c8e45d123d4c9d6aed0f3b084e151330e0f Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 14:48:13 +0200 Subject: [PATCH 05/51] Update .gitignore to avoid pytest scrap --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 69fa4ffa6..bbd850dfb 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,12 @@ lib64/ share/ include/ +# PyTest remnants +tests/dockerfile/legacy/._binder.Dockerfile +tests/dockerfile/legacy/apt-sources.list +tests/dockerfile/legacy/python3.frozen.yml +tests/dockerfile/legacy/root.frozen.yml + # Docs generated/ test_file_text.txt From 4b74a13364472dd7587277199d93cba71c843efa Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 14:51:11 +0200 Subject: [PATCH 06/51] Rethink setup.py with Pipfile As setup.py can be explicitly installed or not from a Pipfile I reasoned that it should not be installed by default after pipenv has used relevant Pipfiles. --- tests/venv/pipfile/{setup-py => setup-py-explicit}/Pipfile | 4 +--- tests/venv/pipfile/setup-py-explicit/README.rst | 4 ++++ .../{setup-py => setup-py-explicit}/dummy/__init__.py | 0 tests/venv/pipfile/{setup-py => setup-py-explicit}/setup.py | 0 tests/venv/pipfile/{setup-py => setup-py-explicit}/verify | 1 - tests/venv/pipfile/setup-py/README.rst | 5 ----- 6 files changed, 5 insertions(+), 9 deletions(-) rename tests/venv/pipfile/{setup-py => setup-py-explicit}/Pipfile (75%) create mode 100644 tests/venv/pipfile/setup-py-explicit/README.rst rename tests/venv/pipfile/{setup-py => setup-py-explicit}/dummy/__init__.py (100%) rename tests/venv/pipfile/{setup-py => setup-py-explicit}/setup.py (100%) rename tests/venv/pipfile/{setup-py => setup-py-explicit}/verify (75%) delete mode 100644 tests/venv/pipfile/setup-py/README.rst diff --git a/tests/venv/pipfile/setup-py/Pipfile b/tests/venv/pipfile/setup-py-explicit/Pipfile similarity index 75% rename from tests/venv/pipfile/setup-py/Pipfile rename to tests/venv/pipfile/setup-py-explicit/Pipfile index 1a9426575..b4ffd0c4f 100644 --- a/tests/venv/pipfile/setup-py/Pipfile +++ b/tests/venv/pipfile/setup-py-explicit/Pipfile @@ -4,7 +4,5 @@ verify_ssl = true name = "pypi" [packages] -requests = "*" - -[dev-packages] there = "*" +dummy = {path=".", editable=true} diff --git a/tests/venv/pipfile/setup-py-explicit/README.rst b/tests/venv/pipfile/setup-py-explicit/README.rst new file mode 100644 index 000000000..7a3f1309c --- /dev/null +++ b/tests/venv/pipfile/setup-py-explicit/README.rst @@ -0,0 +1,4 @@ +Python - Pipfile + setup.py +--------------------------- + +The Pipfile asked the local package to be installed with ``setup.py``, was it? diff --git a/tests/venv/pipfile/setup-py/dummy/__init__.py b/tests/venv/pipfile/setup-py-explicit/dummy/__init__.py similarity index 100% rename from tests/venv/pipfile/setup-py/dummy/__init__.py rename to tests/venv/pipfile/setup-py-explicit/dummy/__init__.py diff --git a/tests/venv/pipfile/setup-py/setup.py b/tests/venv/pipfile/setup-py-explicit/setup.py similarity index 100% rename from tests/venv/pipfile/setup-py/setup.py rename to tests/venv/pipfile/setup-py-explicit/setup.py diff --git a/tests/venv/pipfile/setup-py/verify b/tests/venv/pipfile/setup-py-explicit/verify similarity index 75% rename from tests/venv/pipfile/setup-py/verify rename to tests/venv/pipfile/setup-py-explicit/verify index 0cdf0e217..9e7ac3d7c 100755 --- a/tests/venv/pipfile/setup-py/verify +++ b/tests/venv/pipfile/setup-py-explicit/verify @@ -1,4 +1,3 @@ #!/usr/bin/env python -import requests import there import dummy diff --git a/tests/venv/pipfile/setup-py/README.rst b/tests/venv/pipfile/setup-py/README.rst deleted file mode 100644 index dfde617cb..000000000 --- a/tests/venv/pipfile/setup-py/README.rst +++ /dev/null @@ -1,5 +0,0 @@ -Python - Pipfile(.lock) + setup.py ----------------------------------- - -We should make ``setup.py`` be installed after the ``Pipfile`` or -``Pipfile.lock``. From dff18e840dc8e8e1e57807df5059191e72b170fd Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 14:53:05 +0200 Subject: [PATCH 07/51] Add test for Pipfile + setup.py We want to ignore the setup.py file if it is around along with a Pipfile. --- tests/venv/pipfile/setup-py-implicit/Pipfile | 7 +++++++ tests/venv/pipfile/setup-py-implicit/README.rst | 5 +++++ .../venv/pipfile/setup-py-implicit/dummy/__init__.py | 2 ++ tests/venv/pipfile/setup-py-implicit/setup.py | 12 ++++++++++++ tests/venv/pipfile/setup-py-implicit/verify | 9 +++++++++ 5 files changed, 35 insertions(+) create mode 100644 tests/venv/pipfile/setup-py-implicit/Pipfile create mode 100644 tests/venv/pipfile/setup-py-implicit/README.rst create mode 100644 tests/venv/pipfile/setup-py-implicit/dummy/__init__.py create mode 100644 tests/venv/pipfile/setup-py-implicit/setup.py create mode 100755 tests/venv/pipfile/setup-py-implicit/verify diff --git a/tests/venv/pipfile/setup-py-implicit/Pipfile b/tests/venv/pipfile/setup-py-implicit/Pipfile new file mode 100644 index 000000000..d61ecc754 --- /dev/null +++ b/tests/venv/pipfile/setup-py-implicit/Pipfile @@ -0,0 +1,7 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +there = "*" diff --git a/tests/venv/pipfile/setup-py-implicit/README.rst b/tests/venv/pipfile/setup-py-implicit/README.rst new file mode 100644 index 000000000..182d84b8d --- /dev/null +++ b/tests/venv/pipfile/setup-py-implicit/README.rst @@ -0,0 +1,5 @@ +Python - Pipfile + setup.py +--------------------------- + +The Pipfile did not ask for the local package to be installed with ``setup.py``, +so lets ensure it wasn't. diff --git a/tests/venv/pipfile/setup-py-implicit/dummy/__init__.py b/tests/venv/pipfile/setup-py-implicit/dummy/__init__.py new file mode 100644 index 000000000..012898812 --- /dev/null +++ b/tests/venv/pipfile/setup-py-implicit/dummy/__init__.py @@ -0,0 +1,2 @@ +def dummy(): + pass diff --git a/tests/venv/pipfile/setup-py-implicit/setup.py b/tests/venv/pipfile/setup-py-implicit/setup.py new file mode 100644 index 000000000..a49ce6f8a --- /dev/null +++ b/tests/venv/pipfile/setup-py-implicit/setup.py @@ -0,0 +1,12 @@ +from setuptools import setup, find_packages + +setup( + name='Dummy', + version='1.0.0', + url='https://git-place.org/dummy/dummy.git', + author='Dummy Name', + author_email='dummy@my-email.com', + description='Dummy package for testing purposes only', + packages=find_packages(), + install_requires=['numpy'], +) diff --git a/tests/venv/pipfile/setup-py-implicit/verify b/tests/venv/pipfile/setup-py-implicit/verify new file mode 100755 index 000000000..9507b35e2 --- /dev/null +++ b/tests/venv/pipfile/setup-py-implicit/verify @@ -0,0 +1,9 @@ +#!/usr/bin/env python +import there + +try: + import dummy +except ImportError: + pass +else: + raise Exception("'dummy' shouldn't have been installed from setup.py when a Pipfile was present") From d8cfc50c508ac4d05a125c7e2acdca8cf9e34780 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 14:55:00 +0200 Subject: [PATCH 08/51] Add test for Pipfile + Pipfile.lock We want to use the more specific version, Pipfile.lock, if it is available. Are we ignoring the Pipfile if it is, as we should? --- tests/venv/pipfile/pipfile-lock/Pipfile | 18 ++++++ tests/venv/pipfile/pipfile-lock/Pipfile.lock | 64 ++++++++++++++++++++ tests/venv/pipfile/pipfile-lock/README.rst | 4 ++ tests/venv/pipfile/pipfile-lock/verify | 3 + 4 files changed, 89 insertions(+) create mode 100644 tests/venv/pipfile/pipfile-lock/Pipfile create mode 100644 tests/venv/pipfile/pipfile-lock/Pipfile.lock create mode 100644 tests/venv/pipfile/pipfile-lock/README.rst create mode 100755 tests/venv/pipfile/pipfile-lock/verify diff --git a/tests/venv/pipfile/pipfile-lock/Pipfile b/tests/venv/pipfile/pipfile-lock/Pipfile new file mode 100644 index 000000000..dfe3a98c2 --- /dev/null +++ b/tests/venv/pipfile/pipfile-lock/Pipfile @@ -0,0 +1,18 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +numpy = "*" + +[dev-packages] +sympy = "*" + +# The Pipfile.lock was generated when the Pipfile looked like this +# ---------------------------------------------------------------- +# [packages] +# requests = "*" +# +# [dev-packages] +# there = "*" diff --git a/tests/venv/pipfile/pipfile-lock/Pipfile.lock b/tests/venv/pipfile/pipfile-lock/Pipfile.lock new file mode 100644 index 000000000..f9b7ff549 --- /dev/null +++ b/tests/venv/pipfile/pipfile-lock/Pipfile.lock @@ -0,0 +1,64 @@ +{ + "_meta": { + "hash": { + "sha256": "7160786c1e5cc8e9fe3617f458f7b1c2b617fa44b3fe2f927dee99374c3b05bc" + }, + "pipfile-spec": 6, + "requires": {}, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.python.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "certifi": { + "hashes": [ + "sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5", + "sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae" + ], + "version": "==2019.3.9" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, + "requests": { + "hashes": [ + "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e", + "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b" + ], + "index": "pypi", + "version": "==2.21.0" + }, + "urllib3": { + "hashes": [ + "sha256:4c291ca23bbb55c76518905869ef34bdd5f0e46af7afe6861e8375643ffee1a0", + "sha256:9a247273df709c4fedb38c711e44292304f73f39ab01beda9f6b9fc375669ac3" + ], + "version": "==1.24.2" + } + }, + "develop": { + "there": { + "hashes": [ + "sha256:812638ab3683286bf677f273dd6658de93ebbc99fb74ef2548dc8c045d34e8a6", + "sha256:a65e4b050b14a57ede8bb852c36eb61f0e9d9e1352039d2f9723f8d0601e146a" + ], + "index": "pypi", + "version": "==0.0.9" + } + } +} diff --git a/tests/venv/pipfile/pipfile-lock/README.rst b/tests/venv/pipfile/pipfile-lock/README.rst new file mode 100644 index 000000000..c5aa05099 --- /dev/null +++ b/tests/venv/pipfile/pipfile-lock/README.rst @@ -0,0 +1,4 @@ +Python - Pipfile + Pipfile.lock +------------------------------- + +We should make ``Pipfile.lock`` take precedence over ``Pipfile``. diff --git a/tests/venv/pipfile/pipfile-lock/verify b/tests/venv/pipfile/pipfile-lock/verify new file mode 100755 index 000000000..3ce4a99f6 --- /dev/null +++ b/tests/venv/pipfile/pipfile-lock/verify @@ -0,0 +1,3 @@ +#!/usr/bin/env python +import requests +import there From d9e58c263446729417c48f7bcec4c45872ded502 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 14:59:38 +0200 Subject: [PATCH 09/51] Fix test description --- tests/venv/pipfile/requirements-txt/README.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/venv/pipfile/requirements-txt/README.rst b/tests/venv/pipfile/requirements-txt/README.rst index 7c1ca0d71..105ae8d21 100644 --- a/tests/venv/pipfile/requirements-txt/README.rst +++ b/tests/venv/pipfile/requirements-txt/README.rst @@ -1,5 +1,4 @@ -Python - Pipfile(.lock) + requirements.txt ------------------------------------------- +Python - Pipfile + requirements.txt +----------------------------------- -We should make ``Pipfile``` or ``Pipfile.lock`` take precedence over -``requirements.txt``. +We should make ``Pipfile`` take precedence over ``requirements.txt``. From a59e169e2f8e12101432821f10c704ab3d594685 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 17:30:36 +0200 Subject: [PATCH 10/51] Fix the Pipfile + setup.py tests Apparently testing to import the package will work no matter what as we will find it locally so setup.py may not need to run. By adding a small dependency I could check if the dependency is installed and now the tests actually tests what they should. --- tests/venv/pipfile/setup-py-explicit/setup.py | 2 +- tests/venv/pipfile/setup-py-explicit/verify | 3 +++ tests/venv/pipfile/setup-py-implicit/setup.py | 2 +- tests/venv/pipfile/setup-py-implicit/verify | 4 +++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/venv/pipfile/setup-py-explicit/setup.py b/tests/venv/pipfile/setup-py-explicit/setup.py index a49ce6f8a..d503ec263 100644 --- a/tests/venv/pipfile/setup-py-explicit/setup.py +++ b/tests/venv/pipfile/setup-py-explicit/setup.py @@ -8,5 +8,5 @@ author_email='dummy@my-email.com', description='Dummy package for testing purposes only', packages=find_packages(), - install_requires=['numpy'], + install_requires=['pypi-pkg-test==0.0.4'], ) diff --git a/tests/venv/pipfile/setup-py-explicit/verify b/tests/venv/pipfile/setup-py-explicit/verify index 9e7ac3d7c..4c6eaf1e0 100755 --- a/tests/venv/pipfile/setup-py-explicit/verify +++ b/tests/venv/pipfile/setup-py-explicit/verify @@ -1,3 +1,6 @@ #!/usr/bin/env python import there import dummy + +# This package should be available, as it was a dependency for dummy +import pypi_pkg_test diff --git a/tests/venv/pipfile/setup-py-implicit/setup.py b/tests/venv/pipfile/setup-py-implicit/setup.py index a49ce6f8a..d503ec263 100644 --- a/tests/venv/pipfile/setup-py-implicit/setup.py +++ b/tests/venv/pipfile/setup-py-implicit/setup.py @@ -8,5 +8,5 @@ author_email='dummy@my-email.com', description='Dummy package for testing purposes only', packages=find_packages(), - install_requires=['numpy'], + install_requires=['pypi-pkg-test==0.0.4'], ) diff --git a/tests/venv/pipfile/setup-py-implicit/verify b/tests/venv/pipfile/setup-py-implicit/verify index 9507b35e2..d994d9218 100755 --- a/tests/venv/pipfile/setup-py-implicit/verify +++ b/tests/venv/pipfile/setup-py-implicit/verify @@ -3,7 +3,9 @@ import there try: import dummy + import pypi_pkg_test except ImportError: + # We want an ImportError to be thrown for this test to pass pass else: - raise Exception("'dummy' shouldn't have been installed from setup.py when a Pipfile was present") + raise Exception("'dummy' and its dependency 'pypi_pkg_test' shouldn't have been installed! A Pipfile was present without explicit instructions to install the local package 'dummy'.") From d019f4980ae5af8c644099e06827313fdb89ff90 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 17:32:46 +0200 Subject: [PATCH 11/51] Clarify Pipfile + Pipfile.lock test --- tests/venv/pipfile/pipfile-lock/Pipfile | 6 ++-- tests/venv/pipfile/pipfile-lock/Pipfile.lock | 38 +++----------------- tests/venv/pipfile/pipfile-lock/verify | 10 +++++- 3 files changed, 17 insertions(+), 37 deletions(-) diff --git a/tests/venv/pipfile/pipfile-lock/Pipfile b/tests/venv/pipfile/pipfile-lock/Pipfile index dfe3a98c2..576e4a5f3 100644 --- a/tests/venv/pipfile/pipfile-lock/Pipfile +++ b/tests/venv/pipfile/pipfile-lock/Pipfile @@ -7,12 +7,12 @@ name = "pypi" numpy = "*" [dev-packages] -sympy = "*" +there = "*" # The Pipfile.lock was generated when the Pipfile looked like this # ---------------------------------------------------------------- # [packages] -# requests = "*" -# +# pypi-pkg-test = "*" +# # [dev-packages] # there = "*" diff --git a/tests/venv/pipfile/pipfile-lock/Pipfile.lock b/tests/venv/pipfile/pipfile-lock/Pipfile.lock index f9b7ff549..04af668c4 100644 --- a/tests/venv/pipfile/pipfile-lock/Pipfile.lock +++ b/tests/venv/pipfile/pipfile-lock/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "7160786c1e5cc8e9fe3617f458f7b1c2b617fa44b3fe2f927dee99374c3b05bc" + "sha256": "43abc56b3f80c806377843b5636db099809298ce32cff3d9cb043adca59b7e9d" }, "pipfile-spec": 6, "requires": {}, @@ -14,41 +14,13 @@ ] }, "default": { - "certifi": { + "pypi-pkg-test": { "hashes": [ - "sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5", - "sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae" - ], - "version": "==2019.3.9" - }, - "chardet": { - "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" - ], - "version": "==3.0.4" - }, - "idna": { - "hashes": [ - "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", - "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" - ], - "version": "==2.8" - }, - "requests": { - "hashes": [ - "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e", - "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b" + "sha256:3bc6d0d3d671f5da379eb53cc13ecbb97ce66b1d11916ea2035f6f738b963cc3", + "sha256:ae89e01320aa248e9b626218ecc04c0fb4ae0b3b2a7895404277b488961edc25" ], "index": "pypi", - "version": "==2.21.0" - }, - "urllib3": { - "hashes": [ - "sha256:4c291ca23bbb55c76518905869ef34bdd5f0e46af7afe6861e8375643ffee1a0", - "sha256:9a247273df709c4fedb38c711e44292304f73f39ab01beda9f6b9fc375669ac3" - ], - "version": "==1.24.2" + "version": "==0.0.4" } }, "develop": { diff --git a/tests/venv/pipfile/pipfile-lock/verify b/tests/venv/pipfile/pipfile-lock/verify index 3ce4a99f6..9c1142f28 100755 --- a/tests/venv/pipfile/pipfile-lock/verify +++ b/tests/venv/pipfile/pipfile-lock/verify @@ -1,3 +1,11 @@ #!/usr/bin/env python -import requests +import pypi_pkg_test import there + +try: + import numpy +except ImportError: + # We want an ImportError to be thrown for this test to pass + pass +else: + raise Exception("'numpy' shouldn't have been installed! It was listed in Pipfile but not in the Pipfile.lock.") From e107360d97ec55970e311a62cb36cba84fb7d160 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 17:33:37 +0200 Subject: [PATCH 12/51] Improve Pipfile + requirements.txt test Previously we did not check that requirements.txt was ignored properly, now we do. --- tests/venv/pipfile/requirements-txt/Pipfile | 2 +- tests/venv/pipfile/requirements-txt/verify | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/venv/pipfile/requirements-txt/Pipfile b/tests/venv/pipfile/requirements-txt/Pipfile index 1a9426575..b65da6a67 100644 --- a/tests/venv/pipfile/requirements-txt/Pipfile +++ b/tests/venv/pipfile/requirements-txt/Pipfile @@ -4,7 +4,7 @@ verify_ssl = true name = "pypi" [packages] -requests = "*" +pypi-pkg-test = "*" [dev-packages] there = "*" diff --git a/tests/venv/pipfile/requirements-txt/verify b/tests/venv/pipfile/requirements-txt/verify index 3ce4a99f6..49e31463f 100755 --- a/tests/venv/pipfile/requirements-txt/verify +++ b/tests/venv/pipfile/requirements-txt/verify @@ -1,3 +1,11 @@ #!/usr/bin/env python -import requests +import pypi_pkg_test import there + +try: + import numpy +except ImportError: + # We want an ImportError to be thrown for this test to pass + pass +else: + raise Exception("'numpy' shouldn't have been installed! It was listed in requirements.txt but not in the Pipfile that has precedence.") From 97c26641c310cb0b94a1ec91c8723f663beab4c8 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 17:34:29 +0200 Subject: [PATCH 13/51] Optimize Pipfile + environment.yml test Why install a big package when we can install a trivial one? --- tests/venv/pipfile/environment-yml/environment.yml | 3 ++- tests/venv/pipfile/environment-yml/verify | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/venv/pipfile/environment-yml/environment.yml b/tests/venv/pipfile/environment-yml/environment.yml index 6a91d667f..13421ffc4 100644 --- a/tests/venv/pipfile/environment-yml/environment.yml +++ b/tests/venv/pipfile/environment-yml/environment.yml @@ -1,2 +1,3 @@ dependencies: - - numpy + - pip: + - pypi-pkg-test diff --git a/tests/venv/pipfile/environment-yml/verify b/tests/venv/pipfile/environment-yml/verify index 06b4510ab..5ce045450 100755 --- a/tests/venv/pipfile/environment-yml/verify +++ b/tests/venv/pipfile/environment-yml/verify @@ -1,2 +1,2 @@ #!/usr/bin/env python -import numpy +import pypi_pkg_test From 33970685bd0683f2142948ac0371bc51d344045f Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 17:37:14 +0200 Subject: [PATCH 14/51] Add Pipfile + Pipfile.lock BuildPack logic This is the actual meat while most previous commits were tests to verify that this worked as intented. The tests paid off quickly as this was quite hard to get working at all. - We can not use `pipenv shell` inside this script. - We must use `--system` and therefore `pipenv install` that supports it rather than `pipenv sync` that doesn. - We must generate a `Pipfile.lock` if there are none. - We must use `--ignore-pipfile` and `--deploy` on the `pipenv install` command in order to mimic how a `pipenv sync` would have worked. --- repo2docker/buildpacks/python/__init__.py | 43 +++++++++++++++-------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/repo2docker/buildpacks/python/__init__.py b/repo2docker/buildpacks/python/__init__.py index 099c0c5ec..fe55ece7c 100644 --- a/repo2docker/buildpacks/python/__init__.py +++ b/repo2docker/buildpacks/python/__init__.py @@ -42,10 +42,7 @@ def get_assemble_scripts(self): # and requirements3.txt (if it exists) # will be installed in the python 3 notebook server env. assemble_scripts = super().get_assemble_scripts() - setup_py = 'setup.py' - # KERNEL_PYTHON_PREFIX is the env with the kernel, - # whether it's distinct from the notebook or the same. - pip = '${KERNEL_PYTHON_PREFIX}/bin/pip' + if self.py2: # using python 2 kernel, # requirements3.txt allows installation in the notebook server env @@ -59,24 +56,42 @@ def get_assemble_scripts(self): )) # install Pipfile.lock, Pipfile, or requirements.txt in the kernel env + pipenv = '${KERNEL_PYTHON_PREFIX}/bin/pipenv' pipfile = self.binder_path('Pipfile') pipfile_lock = self.binder_path('Pipfile.lock') - requirements_file = self.binder_path('requirements.txt') - if os.path.exists(pipfile) or os.path.exists(pipfile_lock): - pass - elif os.path.exists(requirements_file): + if os.path.exists(pipfile_lock) or os.path.exists(pipfile): assemble_scripts.append(( '${NB_USER}', - 'pip install "pip<19" && ' + \ - '{} install --no-cache-dir -r "{}"'.format(pip, requirements_file) + 'pip install pipenv' )) - - # setup.py exists *and* binder dir is not used - if not os.path.exists('binder') and os.path.exists(setup_py): + if not os.path.exists(pipfile_lock): + assemble_scripts.append(( + '${NB_USER}', + '{} lock --python {}'.format(pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') + )) assemble_scripts.append(( '${NB_USER}', - '{} install --no-cache-dir .'.format(pip) + '{} install --ignore-pipfile --deploy --system --dev --python {}'.format(pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') )) + else: + # KERNEL_PYTHON_PREFIX is the env with the kernel, + # whether it's distinct from the notebook or the same. + pip = '${KERNEL_PYTHON_PREFIX}/bin/pip' + requirements_file = self.binder_path('requirements.txt') + setup_py = 'setup.py' + if os.path.exists(requirements_file): + assemble_scripts.append(( + '${NB_USER}', + 'pip install "pip<19" && ' + \ + '{} install --no-cache-dir -r "{}"'.format(pip, requirements_file) + )) + # setup.py exists *and* binder dir is not used + if not os.path.exists('binder') and os.path.exists(setup_py): + assemble_scripts.append(( + '${NB_USER}', + '{} install --no-cache-dir .'.format(pip) + )) + return assemble_scripts def detect(self): From 330ac775d33ac29b91c7b595e0984e91049c5f73 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 21:46:52 +0200 Subject: [PATCH 15/51] Add Pipfile + runtime.txt test --- tests/venv/pipfile/py36/Pipfile | 13 +++++++++++++ tests/venv/pipfile/py36/README.rst | 6 ++++++ tests/venv/pipfile/py36/runtime.txt | 1 + tests/venv/pipfile/py36/verify | 8 ++++++++ 4 files changed, 28 insertions(+) create mode 100644 tests/venv/pipfile/py36/Pipfile create mode 100644 tests/venv/pipfile/py36/README.rst create mode 100644 tests/venv/pipfile/py36/runtime.txt create mode 100755 tests/venv/pipfile/py36/verify diff --git a/tests/venv/pipfile/py36/Pipfile b/tests/venv/pipfile/py36/Pipfile new file mode 100644 index 000000000..fa0980ee5 --- /dev/null +++ b/tests/venv/pipfile/py36/Pipfile @@ -0,0 +1,13 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +pypi-pkg-test = "*" + +[dev-packages] +there = "*" + +[requires] +python_version = "3.6" diff --git a/tests/venv/pipfile/py36/README.rst b/tests/venv/pipfile/py36/README.rst new file mode 100644 index 000000000..1b2bb0e56 --- /dev/null +++ b/tests/venv/pipfile/py36/README.rst @@ -0,0 +1,6 @@ +Python - Pipfile with python_version and runtime.txt +---------------------------------------------------- + +We are ignoring the runtime.txt if there is a Pipfile or Pipfile.lock available. +And since `python_version = "3.6"` in the Pipfile, the `python-3.7` in +runtime.txt should be ignored. Is it? diff --git a/tests/venv/pipfile/py36/runtime.txt b/tests/venv/pipfile/py36/runtime.txt new file mode 100644 index 000000000..59a6441f4 --- /dev/null +++ b/tests/venv/pipfile/py36/runtime.txt @@ -0,0 +1 @@ +python-3.7 \ No newline at end of file diff --git a/tests/venv/pipfile/py36/verify b/tests/venv/pipfile/py36/verify new file mode 100755 index 000000000..f71a6daa8 --- /dev/null +++ b/tests/venv/pipfile/py36/verify @@ -0,0 +1,8 @@ +#!/usr/bin/env python +import sys + +import pypi_pkg_test +import there + +print(sys.version_info) +assert sys.version_info[:2] == (3, 6) From 4bde9f05c32a3a633e6f3e566f1c1987315c9076 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 23:26:21 +0200 Subject: [PATCH 16/51] Add Pipfile.lock to py36 test --- tests/venv/pipfile/py36/Pipfile.lock | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/venv/pipfile/py36/Pipfile.lock diff --git a/tests/venv/pipfile/py36/Pipfile.lock b/tests/venv/pipfile/py36/Pipfile.lock new file mode 100644 index 000000000..daa7d7083 --- /dev/null +++ b/tests/venv/pipfile/py36/Pipfile.lock @@ -0,0 +1,38 @@ +{ + "_meta": { + "hash": { + "sha256": "6cdb6013c1cba848c7d9070f8cdac089ce88c98f2910dd08ac98acce77811cb7" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.6" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.python.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "pypi-pkg-test": { + "hashes": [ + "sha256:3bc6d0d3d671f5da379eb53cc13ecbb97ce66b1d11916ea2035f6f738b963cc3", + "sha256:ae89e01320aa248e9b626218ecc04c0fb4ae0b3b2a7895404277b488961edc25" + ], + "index": "pypi", + "version": "==0.0.4" + } + }, + "develop": { + "there": { + "hashes": [ + "sha256:812638ab3683286bf677f273dd6658de93ebbc99fb74ef2548dc8c045d34e8a6", + "sha256:a65e4b050b14a57ede8bb852c36eb61f0e9d9e1352039d2f9723f8d0601e146a" + ], + "index": "pypi", + "version": "==0.0.9" + } + } +} From cf71b80cefe9e26dc92fa47768991fb12290d914 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 23:26:33 +0200 Subject: [PATCH 17/51] Detect python_(full_)version in Pipfile(.lock) Give priority to Pipfile.lock, then Pipfile, then runtime.txt. --- repo2docker/buildpacks/python/__init__.py | 63 ++++++++++++++++------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/repo2docker/buildpacks/python/__init__.py b/repo2docker/buildpacks/python/__init__.py index fe55ece7c..97a5dcb8d 100644 --- a/repo2docker/buildpacks/python/__init__.py +++ b/repo2docker/buildpacks/python/__init__.py @@ -1,39 +1,66 @@ """Generates Dockerfiles based on an input matrix based on Python.""" import os +import re from ..conda import CondaBuildPack - class PythonBuildPack(CondaBuildPack): """Setup Python for use with a repository.""" @property def python_version(self): + """ + Detect the Python version declared in a `Pipfile.lock`, `Pipfile`, or + `runtime.txt`. Will return 'x.y' if version is found (e.g '3.6'), or a + Falsy empty string '' if not found. + """ + if hasattr(self, '_python_version'): return self._python_version - try: - with open(self.binder_path('runtime.txt')) as f: - runtime = f.read().strip() - except FileNotFoundError: - runtime = '' + files_to_search_in_order = [ + { + 'path': self.binder_path('Pipfile.lock'), + 'pattern': r'\s*\"python_(?:full_)?version\": \"?([0-9a-z\.]*)\"?', # ' "python_version": "3.6"' + }, + { + 'path': self.binder_path('Pipfile'), + 'pattern': r'python_(?:full_)?version\s*=+\s*\"?([0-9a-z\.]*)\"?', # 'python_version = "3.6"' + }, + { + 'path': self.binder_path('runtime.txt'), + 'pattern': r'\s*python-([0-9a-z\.]*)\s*', # 'python-3.6' + }, + ] + + py_version = None + for file in files_to_search_in_order: + try: + with open(file['path']) as f: + for line in f: + match = re.match(file['pattern'], line) + if not match: + continue + py_version = match.group(1) + break + except FileNotFoundError: + pass + if py_version: + break - if not runtime.startswith('python-'): - # not a Python runtime (e.g. R, which subclasses this) + # extract major.minor + if py_version: + if len(py_version) == 1: + self._python_version = self.major_pythons.get(py_version[0]) + else: + # return major.minor + self._python_version = '.'.join(py_version.split('.')[:2]) + return self._python_version + else: # use the default Python self._python_version = self.major_pythons['3'] return self._python_version - py_version_info = runtime.split('-', 1)[1].split('.') - py_version = '' - if len(py_version_info) == 1: - py_version = self.major_pythons[py_version_info[0]] - else: - # get major.minor - py_version = '.'.join(py_version_info[:2]) - self._python_version = py_version - return self._python_version - def get_assemble_scripts(self): """Return series of build-steps specific to this repository. """ From b80aba447c920f210cc8bbe8408b25445f07839b Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 23:45:27 +0200 Subject: [PATCH 18/51] Add Pipfile + binder-folder tests --- tests/venv/pipfile/binder-folder-lock/Pipfile | 7 +++++ .../pipfile/binder-folder-lock/Pipfile.lock | 27 +++++++++++++++++++ .../pipfile/binder-folder-lock/README.rst | 4 +++ .../pipfile/binder-folder-lock/binder/Pipfile | 7 +++++ .../binder-folder-lock/binder/Pipfile.lock | 27 +++++++++++++++++++ tests/venv/pipfile/binder-folder-lock/verify | 5 ++++ tests/venv/pipfile/binder-folder/Pipfile | 7 +++++ tests/venv/pipfile/binder-folder/README.rst | 4 +++ .../venv/pipfile/binder-folder/binder/Pipfile | 7 +++++ tests/venv/pipfile/binder-folder/verify | 5 ++++ 10 files changed, 100 insertions(+) create mode 100644 tests/venv/pipfile/binder-folder-lock/Pipfile create mode 100644 tests/venv/pipfile/binder-folder-lock/Pipfile.lock create mode 100644 tests/venv/pipfile/binder-folder-lock/README.rst create mode 100644 tests/venv/pipfile/binder-folder-lock/binder/Pipfile create mode 100644 tests/venv/pipfile/binder-folder-lock/binder/Pipfile.lock create mode 100755 tests/venv/pipfile/binder-folder-lock/verify create mode 100644 tests/venv/pipfile/binder-folder/Pipfile create mode 100644 tests/venv/pipfile/binder-folder/README.rst create mode 100644 tests/venv/pipfile/binder-folder/binder/Pipfile create mode 100755 tests/venv/pipfile/binder-folder/verify diff --git a/tests/venv/pipfile/binder-folder-lock/Pipfile b/tests/venv/pipfile/binder-folder-lock/Pipfile new file mode 100644 index 000000000..d61ecc754 --- /dev/null +++ b/tests/venv/pipfile/binder-folder-lock/Pipfile @@ -0,0 +1,7 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +there = "*" diff --git a/tests/venv/pipfile/binder-folder-lock/Pipfile.lock b/tests/venv/pipfile/binder-folder-lock/Pipfile.lock new file mode 100644 index 000000000..86971aa8d --- /dev/null +++ b/tests/venv/pipfile/binder-folder-lock/Pipfile.lock @@ -0,0 +1,27 @@ +{ + "_meta": { + "hash": { + "sha256": "12bcb8f7793a4452f84fe65d8714098183d7ddcc6d6d80c542b411f352cf70d8" + }, + "pipfile-spec": 6, + "requires": {}, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.python.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "there": { + "hashes": [ + "sha256:812638ab3683286bf677f273dd6658de93ebbc99fb74ef2548dc8c045d34e8a6", + "sha256:a65e4b050b14a57ede8bb852c36eb61f0e9d9e1352039d2f9723f8d0601e146a" + ], + "index": "pypi", + "version": "==0.0.9" + } + }, + "develop": {} +} diff --git a/tests/venv/pipfile/binder-folder-lock/README.rst b/tests/venv/pipfile/binder-folder-lock/README.rst new file mode 100644 index 000000000..623b49b43 --- /dev/null +++ b/tests/venv/pipfile/binder-folder-lock/README.rst @@ -0,0 +1,4 @@ +Python - binder/Pipfile.lock + Pipfile.lock +------------------------------------------- + +We should make ``binder/Pipfile.lock`` take precedence over ``Pipfile.lock``. diff --git a/tests/venv/pipfile/binder-folder-lock/binder/Pipfile b/tests/venv/pipfile/binder-folder-lock/binder/Pipfile new file mode 100644 index 000000000..47e3a0dbf --- /dev/null +++ b/tests/venv/pipfile/binder-folder-lock/binder/Pipfile @@ -0,0 +1,7 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +pypi-pkg-test = "*" diff --git a/tests/venv/pipfile/binder-folder-lock/binder/Pipfile.lock b/tests/venv/pipfile/binder-folder-lock/binder/Pipfile.lock new file mode 100644 index 000000000..17c2f9745 --- /dev/null +++ b/tests/venv/pipfile/binder-folder-lock/binder/Pipfile.lock @@ -0,0 +1,27 @@ +{ + "_meta": { + "hash": { + "sha256": "760e5b427525256c5a02ebbfa2cfe695d89cdb5049859ae442c9c395930b3326" + }, + "pipfile-spec": 6, + "requires": {}, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.python.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "pypi-pkg-test": { + "hashes": [ + "sha256:3bc6d0d3d671f5da379eb53cc13ecbb97ce66b1d11916ea2035f6f738b963cc3", + "sha256:ae89e01320aa248e9b626218ecc04c0fb4ae0b3b2a7895404277b488961edc25" + ], + "index": "pypi", + "version": "==0.0.4" + } + }, + "develop": {} +} diff --git a/tests/venv/pipfile/binder-folder-lock/verify b/tests/venv/pipfile/binder-folder-lock/verify new file mode 100755 index 000000000..813cfc2cc --- /dev/null +++ b/tests/venv/pipfile/binder-folder-lock/verify @@ -0,0 +1,5 @@ +#!/usr/bin/env python +import pypi_pkg_test + +# pypi_pkg_test is installed from the binder folder's Pipfile, but not from the +# root folder's Pipfile! diff --git a/tests/venv/pipfile/binder-folder/Pipfile b/tests/venv/pipfile/binder-folder/Pipfile new file mode 100644 index 000000000..d61ecc754 --- /dev/null +++ b/tests/venv/pipfile/binder-folder/Pipfile @@ -0,0 +1,7 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +there = "*" diff --git a/tests/venv/pipfile/binder-folder/README.rst b/tests/venv/pipfile/binder-folder/README.rst new file mode 100644 index 000000000..7dd4b7508 --- /dev/null +++ b/tests/venv/pipfile/binder-folder/README.rst @@ -0,0 +1,4 @@ +Python - binder/Pipfile + Pipfile +--------------------------------- + +We should make ``binder/Pipfile`` take precedence over ``Pipfile``. diff --git a/tests/venv/pipfile/binder-folder/binder/Pipfile b/tests/venv/pipfile/binder-folder/binder/Pipfile new file mode 100644 index 000000000..47e3a0dbf --- /dev/null +++ b/tests/venv/pipfile/binder-folder/binder/Pipfile @@ -0,0 +1,7 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +pypi-pkg-test = "*" diff --git a/tests/venv/pipfile/binder-folder/verify b/tests/venv/pipfile/binder-folder/verify new file mode 100755 index 000000000..813cfc2cc --- /dev/null +++ b/tests/venv/pipfile/binder-folder/verify @@ -0,0 +1,5 @@ +#!/usr/bin/env python +import pypi_pkg_test + +# pypi_pkg_test is installed from the binder folder's Pipfile, but not from the +# root folder's Pipfile! From a1a6746db366e3869dde92a14220c1f0fbf60a4b Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 21 Apr 2019 23:55:15 +0200 Subject: [PATCH 19/51] Fix Pipfile + binder-folder support --- repo2docker/buildpacks/python/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/repo2docker/buildpacks/python/__init__.py b/repo2docker/buildpacks/python/__init__.py index 97a5dcb8d..441f1a3c6 100644 --- a/repo2docker/buildpacks/python/__init__.py +++ b/repo2docker/buildpacks/python/__init__.py @@ -87,6 +87,7 @@ def get_assemble_scripts(self): pipfile = self.binder_path('Pipfile') pipfile_lock = self.binder_path('Pipfile.lock') if os.path.exists(pipfile_lock) or os.path.exists(pipfile): + working_directory = 'binder' if os.path.exists('binder') else '.' assemble_scripts.append(( '${NB_USER}', 'pip install pipenv' @@ -94,11 +95,11 @@ def get_assemble_scripts(self): if not os.path.exists(pipfile_lock): assemble_scripts.append(( '${NB_USER}', - '{} lock --python {}'.format(pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') + '(cd {} && {} lock --python {})'.format(working_directory, pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') )) assemble_scripts.append(( '${NB_USER}', - '{} install --ignore-pipfile --deploy --system --dev --python {}'.format(pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') + '(cd {} && {} install --ignore-pipfile --deploy --system --dev --python {})'.format(working_directory, pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') )) else: # KERNEL_PYTHON_PREFIX is the env with the kernel, From 4ed7dacc2b80d89228c8b15d4afa4643866f0a16 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 12 May 2019 15:07:24 +0200 Subject: [PATCH 20/51] extract pipfile: add new CI job --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b85200299..72ddd7edb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,7 @@ env: - REPO_TYPE=unit - REPO_TYPE=base - REPO_TYPE=conda + - REPO_TYPE=pipfile - REPO_TYPE=venv - REPO_TYPE=stencila-r - REPO_TYPE=stencila-py From 10e9bb9bf6e083827c49ddac5c50c8ba20fb062d Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 12 May 2019 15:08:40 +0200 Subject: [PATCH 21/51] extract pipfile: move tests --- tests/{venv => }/pipfile/binder-folder-lock/Pipfile | 0 tests/{venv => }/pipfile/binder-folder-lock/Pipfile.lock | 0 tests/{venv => }/pipfile/binder-folder-lock/README.rst | 0 tests/{venv => }/pipfile/binder-folder-lock/binder/Pipfile | 0 tests/{venv => }/pipfile/binder-folder-lock/binder/Pipfile.lock | 0 tests/{venv => }/pipfile/binder-folder-lock/verify | 0 tests/{venv => }/pipfile/binder-folder/Pipfile | 0 tests/{venv => }/pipfile/binder-folder/README.rst | 0 tests/{venv => }/pipfile/binder-folder/binder/Pipfile | 0 tests/{venv => }/pipfile/binder-folder/verify | 0 tests/{venv => }/pipfile/environment-yml/Pipfile | 0 tests/{venv => }/pipfile/environment-yml/README.rst | 0 tests/{venv => }/pipfile/environment-yml/environment.yml | 0 tests/{venv => }/pipfile/environment-yml/verify | 0 tests/{venv => }/pipfile/pipfile-lock/Pipfile | 0 tests/{venv => }/pipfile/pipfile-lock/Pipfile.lock | 0 tests/{venv => }/pipfile/pipfile-lock/README.rst | 0 tests/{venv => }/pipfile/pipfile-lock/verify | 0 tests/{venv => }/pipfile/py36/Pipfile | 0 tests/{venv => }/pipfile/py36/Pipfile.lock | 0 tests/{venv => }/pipfile/py36/README.rst | 0 tests/{venv => }/pipfile/py36/runtime.txt | 0 tests/{venv => }/pipfile/py36/verify | 0 tests/{venv => }/pipfile/requirements-txt/Pipfile | 0 tests/{venv => }/pipfile/requirements-txt/README.rst | 0 tests/{venv => }/pipfile/requirements-txt/requirements.txt | 0 tests/{venv => }/pipfile/requirements-txt/verify | 0 tests/{venv => }/pipfile/setup-py-explicit/Pipfile | 0 tests/{venv => }/pipfile/setup-py-explicit/README.rst | 0 tests/{venv => }/pipfile/setup-py-explicit/dummy/__init__.py | 0 tests/{venv => }/pipfile/setup-py-explicit/setup.py | 0 tests/{venv => }/pipfile/setup-py-explicit/verify | 0 tests/{venv => }/pipfile/setup-py-implicit/Pipfile | 0 tests/{venv => }/pipfile/setup-py-implicit/README.rst | 0 tests/{venv => }/pipfile/setup-py-implicit/dummy/__init__.py | 0 tests/{venv => }/pipfile/setup-py-implicit/setup.py | 0 tests/{venv => }/pipfile/setup-py-implicit/verify | 0 37 files changed, 0 insertions(+), 0 deletions(-) rename tests/{venv => }/pipfile/binder-folder-lock/Pipfile (100%) rename tests/{venv => }/pipfile/binder-folder-lock/Pipfile.lock (100%) rename tests/{venv => }/pipfile/binder-folder-lock/README.rst (100%) rename tests/{venv => }/pipfile/binder-folder-lock/binder/Pipfile (100%) rename tests/{venv => }/pipfile/binder-folder-lock/binder/Pipfile.lock (100%) rename tests/{venv => }/pipfile/binder-folder-lock/verify (100%) rename tests/{venv => }/pipfile/binder-folder/Pipfile (100%) rename tests/{venv => }/pipfile/binder-folder/README.rst (100%) rename tests/{venv => }/pipfile/binder-folder/binder/Pipfile (100%) rename tests/{venv => }/pipfile/binder-folder/verify (100%) rename tests/{venv => }/pipfile/environment-yml/Pipfile (100%) rename tests/{venv => }/pipfile/environment-yml/README.rst (100%) rename tests/{venv => }/pipfile/environment-yml/environment.yml (100%) rename tests/{venv => }/pipfile/environment-yml/verify (100%) rename tests/{venv => }/pipfile/pipfile-lock/Pipfile (100%) rename tests/{venv => }/pipfile/pipfile-lock/Pipfile.lock (100%) rename tests/{venv => }/pipfile/pipfile-lock/README.rst (100%) rename tests/{venv => }/pipfile/pipfile-lock/verify (100%) rename tests/{venv => }/pipfile/py36/Pipfile (100%) rename tests/{venv => }/pipfile/py36/Pipfile.lock (100%) rename tests/{venv => }/pipfile/py36/README.rst (100%) rename tests/{venv => }/pipfile/py36/runtime.txt (100%) rename tests/{venv => }/pipfile/py36/verify (100%) rename tests/{venv => }/pipfile/requirements-txt/Pipfile (100%) rename tests/{venv => }/pipfile/requirements-txt/README.rst (100%) rename tests/{venv => }/pipfile/requirements-txt/requirements.txt (100%) rename tests/{venv => }/pipfile/requirements-txt/verify (100%) rename tests/{venv => }/pipfile/setup-py-explicit/Pipfile (100%) rename tests/{venv => }/pipfile/setup-py-explicit/README.rst (100%) rename tests/{venv => }/pipfile/setup-py-explicit/dummy/__init__.py (100%) rename tests/{venv => }/pipfile/setup-py-explicit/setup.py (100%) rename tests/{venv => }/pipfile/setup-py-explicit/verify (100%) rename tests/{venv => }/pipfile/setup-py-implicit/Pipfile (100%) rename tests/{venv => }/pipfile/setup-py-implicit/README.rst (100%) rename tests/{venv => }/pipfile/setup-py-implicit/dummy/__init__.py (100%) rename tests/{venv => }/pipfile/setup-py-implicit/setup.py (100%) rename tests/{venv => }/pipfile/setup-py-implicit/verify (100%) diff --git a/tests/venv/pipfile/binder-folder-lock/Pipfile b/tests/pipfile/binder-folder-lock/Pipfile similarity index 100% rename from tests/venv/pipfile/binder-folder-lock/Pipfile rename to tests/pipfile/binder-folder-lock/Pipfile diff --git a/tests/venv/pipfile/binder-folder-lock/Pipfile.lock b/tests/pipfile/binder-folder-lock/Pipfile.lock similarity index 100% rename from tests/venv/pipfile/binder-folder-lock/Pipfile.lock rename to tests/pipfile/binder-folder-lock/Pipfile.lock diff --git a/tests/venv/pipfile/binder-folder-lock/README.rst b/tests/pipfile/binder-folder-lock/README.rst similarity index 100% rename from tests/venv/pipfile/binder-folder-lock/README.rst rename to tests/pipfile/binder-folder-lock/README.rst diff --git a/tests/venv/pipfile/binder-folder-lock/binder/Pipfile b/tests/pipfile/binder-folder-lock/binder/Pipfile similarity index 100% rename from tests/venv/pipfile/binder-folder-lock/binder/Pipfile rename to tests/pipfile/binder-folder-lock/binder/Pipfile diff --git a/tests/venv/pipfile/binder-folder-lock/binder/Pipfile.lock b/tests/pipfile/binder-folder-lock/binder/Pipfile.lock similarity index 100% rename from tests/venv/pipfile/binder-folder-lock/binder/Pipfile.lock rename to tests/pipfile/binder-folder-lock/binder/Pipfile.lock diff --git a/tests/venv/pipfile/binder-folder-lock/verify b/tests/pipfile/binder-folder-lock/verify similarity index 100% rename from tests/venv/pipfile/binder-folder-lock/verify rename to tests/pipfile/binder-folder-lock/verify diff --git a/tests/venv/pipfile/binder-folder/Pipfile b/tests/pipfile/binder-folder/Pipfile similarity index 100% rename from tests/venv/pipfile/binder-folder/Pipfile rename to tests/pipfile/binder-folder/Pipfile diff --git a/tests/venv/pipfile/binder-folder/README.rst b/tests/pipfile/binder-folder/README.rst similarity index 100% rename from tests/venv/pipfile/binder-folder/README.rst rename to tests/pipfile/binder-folder/README.rst diff --git a/tests/venv/pipfile/binder-folder/binder/Pipfile b/tests/pipfile/binder-folder/binder/Pipfile similarity index 100% rename from tests/venv/pipfile/binder-folder/binder/Pipfile rename to tests/pipfile/binder-folder/binder/Pipfile diff --git a/tests/venv/pipfile/binder-folder/verify b/tests/pipfile/binder-folder/verify similarity index 100% rename from tests/venv/pipfile/binder-folder/verify rename to tests/pipfile/binder-folder/verify diff --git a/tests/venv/pipfile/environment-yml/Pipfile b/tests/pipfile/environment-yml/Pipfile similarity index 100% rename from tests/venv/pipfile/environment-yml/Pipfile rename to tests/pipfile/environment-yml/Pipfile diff --git a/tests/venv/pipfile/environment-yml/README.rst b/tests/pipfile/environment-yml/README.rst similarity index 100% rename from tests/venv/pipfile/environment-yml/README.rst rename to tests/pipfile/environment-yml/README.rst diff --git a/tests/venv/pipfile/environment-yml/environment.yml b/tests/pipfile/environment-yml/environment.yml similarity index 100% rename from tests/venv/pipfile/environment-yml/environment.yml rename to tests/pipfile/environment-yml/environment.yml diff --git a/tests/venv/pipfile/environment-yml/verify b/tests/pipfile/environment-yml/verify similarity index 100% rename from tests/venv/pipfile/environment-yml/verify rename to tests/pipfile/environment-yml/verify diff --git a/tests/venv/pipfile/pipfile-lock/Pipfile b/tests/pipfile/pipfile-lock/Pipfile similarity index 100% rename from tests/venv/pipfile/pipfile-lock/Pipfile rename to tests/pipfile/pipfile-lock/Pipfile diff --git a/tests/venv/pipfile/pipfile-lock/Pipfile.lock b/tests/pipfile/pipfile-lock/Pipfile.lock similarity index 100% rename from tests/venv/pipfile/pipfile-lock/Pipfile.lock rename to tests/pipfile/pipfile-lock/Pipfile.lock diff --git a/tests/venv/pipfile/pipfile-lock/README.rst b/tests/pipfile/pipfile-lock/README.rst similarity index 100% rename from tests/venv/pipfile/pipfile-lock/README.rst rename to tests/pipfile/pipfile-lock/README.rst diff --git a/tests/venv/pipfile/pipfile-lock/verify b/tests/pipfile/pipfile-lock/verify similarity index 100% rename from tests/venv/pipfile/pipfile-lock/verify rename to tests/pipfile/pipfile-lock/verify diff --git a/tests/venv/pipfile/py36/Pipfile b/tests/pipfile/py36/Pipfile similarity index 100% rename from tests/venv/pipfile/py36/Pipfile rename to tests/pipfile/py36/Pipfile diff --git a/tests/venv/pipfile/py36/Pipfile.lock b/tests/pipfile/py36/Pipfile.lock similarity index 100% rename from tests/venv/pipfile/py36/Pipfile.lock rename to tests/pipfile/py36/Pipfile.lock diff --git a/tests/venv/pipfile/py36/README.rst b/tests/pipfile/py36/README.rst similarity index 100% rename from tests/venv/pipfile/py36/README.rst rename to tests/pipfile/py36/README.rst diff --git a/tests/venv/pipfile/py36/runtime.txt b/tests/pipfile/py36/runtime.txt similarity index 100% rename from tests/venv/pipfile/py36/runtime.txt rename to tests/pipfile/py36/runtime.txt diff --git a/tests/venv/pipfile/py36/verify b/tests/pipfile/py36/verify similarity index 100% rename from tests/venv/pipfile/py36/verify rename to tests/pipfile/py36/verify diff --git a/tests/venv/pipfile/requirements-txt/Pipfile b/tests/pipfile/requirements-txt/Pipfile similarity index 100% rename from tests/venv/pipfile/requirements-txt/Pipfile rename to tests/pipfile/requirements-txt/Pipfile diff --git a/tests/venv/pipfile/requirements-txt/README.rst b/tests/pipfile/requirements-txt/README.rst similarity index 100% rename from tests/venv/pipfile/requirements-txt/README.rst rename to tests/pipfile/requirements-txt/README.rst diff --git a/tests/venv/pipfile/requirements-txt/requirements.txt b/tests/pipfile/requirements-txt/requirements.txt similarity index 100% rename from tests/venv/pipfile/requirements-txt/requirements.txt rename to tests/pipfile/requirements-txt/requirements.txt diff --git a/tests/venv/pipfile/requirements-txt/verify b/tests/pipfile/requirements-txt/verify similarity index 100% rename from tests/venv/pipfile/requirements-txt/verify rename to tests/pipfile/requirements-txt/verify diff --git a/tests/venv/pipfile/setup-py-explicit/Pipfile b/tests/pipfile/setup-py-explicit/Pipfile similarity index 100% rename from tests/venv/pipfile/setup-py-explicit/Pipfile rename to tests/pipfile/setup-py-explicit/Pipfile diff --git a/tests/venv/pipfile/setup-py-explicit/README.rst b/tests/pipfile/setup-py-explicit/README.rst similarity index 100% rename from tests/venv/pipfile/setup-py-explicit/README.rst rename to tests/pipfile/setup-py-explicit/README.rst diff --git a/tests/venv/pipfile/setup-py-explicit/dummy/__init__.py b/tests/pipfile/setup-py-explicit/dummy/__init__.py similarity index 100% rename from tests/venv/pipfile/setup-py-explicit/dummy/__init__.py rename to tests/pipfile/setup-py-explicit/dummy/__init__.py diff --git a/tests/venv/pipfile/setup-py-explicit/setup.py b/tests/pipfile/setup-py-explicit/setup.py similarity index 100% rename from tests/venv/pipfile/setup-py-explicit/setup.py rename to tests/pipfile/setup-py-explicit/setup.py diff --git a/tests/venv/pipfile/setup-py-explicit/verify b/tests/pipfile/setup-py-explicit/verify similarity index 100% rename from tests/venv/pipfile/setup-py-explicit/verify rename to tests/pipfile/setup-py-explicit/verify diff --git a/tests/venv/pipfile/setup-py-implicit/Pipfile b/tests/pipfile/setup-py-implicit/Pipfile similarity index 100% rename from tests/venv/pipfile/setup-py-implicit/Pipfile rename to tests/pipfile/setup-py-implicit/Pipfile diff --git a/tests/venv/pipfile/setup-py-implicit/README.rst b/tests/pipfile/setup-py-implicit/README.rst similarity index 100% rename from tests/venv/pipfile/setup-py-implicit/README.rst rename to tests/pipfile/setup-py-implicit/README.rst diff --git a/tests/venv/pipfile/setup-py-implicit/dummy/__init__.py b/tests/pipfile/setup-py-implicit/dummy/__init__.py similarity index 100% rename from tests/venv/pipfile/setup-py-implicit/dummy/__init__.py rename to tests/pipfile/setup-py-implicit/dummy/__init__.py diff --git a/tests/venv/pipfile/setup-py-implicit/setup.py b/tests/pipfile/setup-py-implicit/setup.py similarity index 100% rename from tests/venv/pipfile/setup-py-implicit/setup.py rename to tests/pipfile/setup-py-implicit/setup.py diff --git a/tests/venv/pipfile/setup-py-implicit/verify b/tests/pipfile/setup-py-implicit/verify similarity index 100% rename from tests/venv/pipfile/setup-py-implicit/verify rename to tests/pipfile/setup-py-implicit/verify From c25aa81c2afb7cf096f0cb2241f11a07af082f8b Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 12 May 2019 15:09:14 +0200 Subject: [PATCH 22/51] extract pipfile: copy PythonBuildPack --- repo2docker/buildpacks/pipfile/__init__.py | 143 +++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 repo2docker/buildpacks/pipfile/__init__.py diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py new file mode 100644 index 000000000..441f1a3c6 --- /dev/null +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -0,0 +1,143 @@ +"""Generates Dockerfiles based on an input matrix based on Python.""" +import os +import re + +from ..conda import CondaBuildPack + +class PythonBuildPack(CondaBuildPack): + """Setup Python for use with a repository.""" + + @property + def python_version(self): + """ + Detect the Python version declared in a `Pipfile.lock`, `Pipfile`, or + `runtime.txt`. Will return 'x.y' if version is found (e.g '3.6'), or a + Falsy empty string '' if not found. + """ + + if hasattr(self, '_python_version'): + return self._python_version + + files_to_search_in_order = [ + { + 'path': self.binder_path('Pipfile.lock'), + 'pattern': r'\s*\"python_(?:full_)?version\": \"?([0-9a-z\.]*)\"?', # ' "python_version": "3.6"' + }, + { + 'path': self.binder_path('Pipfile'), + 'pattern': r'python_(?:full_)?version\s*=+\s*\"?([0-9a-z\.]*)\"?', # 'python_version = "3.6"' + }, + { + 'path': self.binder_path('runtime.txt'), + 'pattern': r'\s*python-([0-9a-z\.]*)\s*', # 'python-3.6' + }, + ] + + py_version = None + for file in files_to_search_in_order: + try: + with open(file['path']) as f: + for line in f: + match = re.match(file['pattern'], line) + if not match: + continue + py_version = match.group(1) + break + except FileNotFoundError: + pass + if py_version: + break + + # extract major.minor + if py_version: + if len(py_version) == 1: + self._python_version = self.major_pythons.get(py_version[0]) + else: + # return major.minor + self._python_version = '.'.join(py_version.split('.')[:2]) + return self._python_version + else: + # use the default Python + self._python_version = self.major_pythons['3'] + return self._python_version + + def get_assemble_scripts(self): + """Return series of build-steps specific to this repository. + """ + # If we have a runtime.txt & that's set to python-2.7, + # requirements.txt will be installed in the *kernel* env + # and requirements3.txt (if it exists) + # will be installed in the python 3 notebook server env. + assemble_scripts = super().get_assemble_scripts() + + if self.py2: + # using python 2 kernel, + # requirements3.txt allows installation in the notebook server env + nb_requirements_file = self.binder_path('requirements3.txt') + if os.path.exists(nb_requirements_file): + assemble_scripts.append(( + '${NB_USER}', + # want the $NB_PYHTON_PREFIX environment variable, not for + # Python's string formatting to try and replace this + '${{NB_PYTHON_PREFIX}}/bin/pip install --no-cache-dir -r "{}"'.format(nb_requirements_file) + )) + + # install Pipfile.lock, Pipfile, or requirements.txt in the kernel env + pipenv = '${KERNEL_PYTHON_PREFIX}/bin/pipenv' + pipfile = self.binder_path('Pipfile') + pipfile_lock = self.binder_path('Pipfile.lock') + if os.path.exists(pipfile_lock) or os.path.exists(pipfile): + working_directory = 'binder' if os.path.exists('binder') else '.' + assemble_scripts.append(( + '${NB_USER}', + 'pip install pipenv' + )) + if not os.path.exists(pipfile_lock): + assemble_scripts.append(( + '${NB_USER}', + '(cd {} && {} lock --python {})'.format(working_directory, pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') + )) + assemble_scripts.append(( + '${NB_USER}', + '(cd {} && {} install --ignore-pipfile --deploy --system --dev --python {})'.format(working_directory, pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') + )) + else: + # KERNEL_PYTHON_PREFIX is the env with the kernel, + # whether it's distinct from the notebook or the same. + pip = '${KERNEL_PYTHON_PREFIX}/bin/pip' + requirements_file = self.binder_path('requirements.txt') + setup_py = 'setup.py' + if os.path.exists(requirements_file): + assemble_scripts.append(( + '${NB_USER}', + 'pip install "pip<19" && ' + \ + '{} install --no-cache-dir -r "{}"'.format(pip, requirements_file) + )) + # setup.py exists *and* binder dir is not used + if not os.path.exists('binder') and os.path.exists(setup_py): + assemble_scripts.append(( + '${NB_USER}', + '{} install --no-cache-dir .'.format(pip) + )) + + return assemble_scripts + + def detect(self): + """Check if current repo should be built with the Python buildpack. + """ + pipfile = self.binder_path('Pipfile') + pipfile_lock = self.binder_path('Pipfile.lock') + requirements_txt = self.binder_path('requirements.txt') + runtime_txt = self.binder_path('runtime.txt') + setup_py = 'setup.py' + + if os.path.exists(runtime_txt): + with open(runtime_txt) as f: + runtime = f.read().strip() + if runtime.startswith("python-"): + return True + else: + return False + if not os.path.exists('binder') and os.path.exists(setup_py): + return True + return os.path.exists(pipfile) or os.path.exists(pipfile_lock) or os.path.exists(requirements_txt) From 66e63f66ac78886f0ef62d9cbd83d2ee0896d019 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 12 May 2019 15:14:51 +0200 Subject: [PATCH 23/51] extract pipfile: reset PythonBuildPack --- repo2docker/buildpacks/python/__init__.py | 114 ++++++---------------- 1 file changed, 32 insertions(+), 82 deletions(-) diff --git a/repo2docker/buildpacks/python/__init__.py b/repo2docker/buildpacks/python/__init__.py index 441f1a3c6..1686ff3ca 100644 --- a/repo2docker/buildpacks/python/__init__.py +++ b/repo2docker/buildpacks/python/__init__.py @@ -1,66 +1,39 @@ """Generates Dockerfiles based on an input matrix based on Python.""" import os -import re from ..conda import CondaBuildPack + class PythonBuildPack(CondaBuildPack): """Setup Python for use with a repository.""" @property def python_version(self): - """ - Detect the Python version declared in a `Pipfile.lock`, `Pipfile`, or - `runtime.txt`. Will return 'x.y' if version is found (e.g '3.6'), or a - Falsy empty string '' if not found. - """ - if hasattr(self, '_python_version'): return self._python_version - files_to_search_in_order = [ - { - 'path': self.binder_path('Pipfile.lock'), - 'pattern': r'\s*\"python_(?:full_)?version\": \"?([0-9a-z\.]*)\"?', # ' "python_version": "3.6"' - }, - { - 'path': self.binder_path('Pipfile'), - 'pattern': r'python_(?:full_)?version\s*=+\s*\"?([0-9a-z\.]*)\"?', # 'python_version = "3.6"' - }, - { - 'path': self.binder_path('runtime.txt'), - 'pattern': r'\s*python-([0-9a-z\.]*)\s*', # 'python-3.6' - }, - ] - - py_version = None - for file in files_to_search_in_order: - try: - with open(file['path']) as f: - for line in f: - match = re.match(file['pattern'], line) - if not match: - continue - py_version = match.group(1) - break - except FileNotFoundError: - pass - if py_version: - break + try: + with open(self.binder_path('runtime.txt')) as f: + runtime = f.read().strip() + except FileNotFoundError: + runtime = '' - # extract major.minor - if py_version: - if len(py_version) == 1: - self._python_version = self.major_pythons.get(py_version[0]) - else: - # return major.minor - self._python_version = '.'.join(py_version.split('.')[:2]) - return self._python_version - else: + if not runtime.startswith('python-'): + # not a Python runtime (e.g. R, which subclasses this) # use the default Python self._python_version = self.major_pythons['3'] return self._python_version + py_version_info = runtime.split('-', 1)[1].split('.') + py_version = '' + if len(py_version_info) == 1: + py_version = self.major_pythons[py_version_info[0]] + else: + # get major.minor + py_version = '.'.join(py_version_info[:2]) + self._python_version = py_version + return self._python_version + def get_assemble_scripts(self): """Return series of build-steps specific to this repository. """ @@ -69,7 +42,10 @@ def get_assemble_scripts(self): # and requirements3.txt (if it exists) # will be installed in the python 3 notebook server env. assemble_scripts = super().get_assemble_scripts() - + setup_py = 'setup.py' + # KERNEL_PYTHON_PREFIX is the env with the kernel, + # whether it's distinct from the notebook or the same. + pip = '${KERNEL_PYTHON_PREFIX}/bin/pip' if self.py2: # using python 2 kernel, # requirements3.txt allows installation in the notebook server env @@ -82,51 +58,25 @@ def get_assemble_scripts(self): '${{NB_PYTHON_PREFIX}}/bin/pip install --no-cache-dir -r "{}"'.format(nb_requirements_file) )) - # install Pipfile.lock, Pipfile, or requirements.txt in the kernel env - pipenv = '${KERNEL_PYTHON_PREFIX}/bin/pipenv' - pipfile = self.binder_path('Pipfile') - pipfile_lock = self.binder_path('Pipfile.lock') - if os.path.exists(pipfile_lock) or os.path.exists(pipfile): - working_directory = 'binder' if os.path.exists('binder') else '.' + # install requirements.txt in the kernel env + requirements_file = self.binder_path('requirements.txt') + if os.path.exists(requirements_file): assemble_scripts.append(( '${NB_USER}', - 'pip install pipenv' + '{} install --no-cache-dir -r "{}"'.format(pip, requirements_file) )) - if not os.path.exists(pipfile_lock): - assemble_scripts.append(( - '${NB_USER}', - '(cd {} && {} lock --python {})'.format(working_directory, pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') - )) + + # setup.py exists *and* binder dir is not used + if not self.binder_dir and os.path.exists(setup_py): assemble_scripts.append(( '${NB_USER}', - '(cd {} && {} install --ignore-pipfile --deploy --system --dev --python {})'.format(working_directory, pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') + '{} install --no-cache-dir .'.format(pip) )) - else: - # KERNEL_PYTHON_PREFIX is the env with the kernel, - # whether it's distinct from the notebook or the same. - pip = '${KERNEL_PYTHON_PREFIX}/bin/pip' - requirements_file = self.binder_path('requirements.txt') - setup_py = 'setup.py' - if os.path.exists(requirements_file): - assemble_scripts.append(( - '${NB_USER}', - 'pip install "pip<19" && ' + \ - '{} install --no-cache-dir -r "{}"'.format(pip, requirements_file) - )) - # setup.py exists *and* binder dir is not used - if not os.path.exists('binder') and os.path.exists(setup_py): - assemble_scripts.append(( - '${NB_USER}', - '{} install --no-cache-dir .'.format(pip) - )) - return assemble_scripts def detect(self): """Check if current repo should be built with the Python buildpack. """ - pipfile = self.binder_path('Pipfile') - pipfile_lock = self.binder_path('Pipfile.lock') requirements_txt = self.binder_path('requirements.txt') runtime_txt = self.binder_path('runtime.txt') setup_py = 'setup.py' @@ -138,6 +88,6 @@ def detect(self): return True else: return False - if not os.path.exists('binder') and os.path.exists(setup_py): + if not self.binder_dir and os.path.exists(setup_py): return True - return os.path.exists(pipfile) or os.path.exists(pipfile_lock) or os.path.exists(requirements_txt) + return os.path.exists(requirements_txt) From 258271f7808409dc89e775c491fd2fef2afe5711 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 12 May 2019 15:36:42 +0200 Subject: [PATCH 24/51] extract pipfile: refine PipfileBuildPack --- repo2docker/buildpacks/pipfile/__init__.py | 60 ++++++++-------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 441f1a3c6..f4156ec52 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -4,8 +4,8 @@ from ..conda import CondaBuildPack -class PythonBuildPack(CondaBuildPack): - """Setup Python for use with a repository.""" +class PipfileBuildPack(CondaBuildPack): + """Setup Python with pipfile for use with a repository.""" @property def python_version(self): @@ -82,62 +82,42 @@ def get_assemble_scripts(self): '${{NB_PYTHON_PREFIX}}/bin/pip install --no-cache-dir -r "{}"'.format(nb_requirements_file) )) - # install Pipfile.lock, Pipfile, or requirements.txt in the kernel env + # install Pipfile.lock or fallback to installing Pipfile pipenv = '${KERNEL_PYTHON_PREFIX}/bin/pipenv' pipfile = self.binder_path('Pipfile') pipfile_lock = self.binder_path('Pipfile.lock') - if os.path.exists(pipfile_lock) or os.path.exists(pipfile): - working_directory = 'binder' if os.path.exists('binder') else '.' + working_directory = 'binder' if os.path.exists('binder') else '.' + assemble_scripts.append(( + '${NB_USER}', + 'pip install pipenv' + )) + if os.path.exists(pipfile_lock): assemble_scripts.append(( '${NB_USER}', - 'pip install pipenv' + '(cd {} && {} install --ignore-pipfile --deploy --system --dev --python {})'.format(working_directory, pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') )) - if not os.path.exists(pipfile_lock): - assemble_scripts.append(( - '${NB_USER}', - '(cd {} && {} lock --python {})'.format(working_directory, pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') - )) + elif os.path.exists(pipfile): assemble_scripts.append(( '${NB_USER}', - '(cd {} && {} install --ignore-pipfile --deploy --system --dev --python {})'.format(working_directory, pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') + '(cd {} && {} lock --python {})'.format(working_directory, pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') )) else: - # KERNEL_PYTHON_PREFIX is the env with the kernel, - # whether it's distinct from the notebook or the same. - pip = '${KERNEL_PYTHON_PREFIX}/bin/pip' - requirements_file = self.binder_path('requirements.txt') - setup_py = 'setup.py' - if os.path.exists(requirements_file): - assemble_scripts.append(( - '${NB_USER}', - 'pip install "pip<19" && ' + \ - '{} install --no-cache-dir -r "{}"'.format(pip, requirements_file) - )) - # setup.py exists *and* binder dir is not used - if not os.path.exists('binder') and os.path.exists(setup_py): - assemble_scripts.append(( - '${NB_USER}', - '{} install --no-cache-dir .'.format(pip) - )) + raise Exception("Neither Pipfile.lock or Pipfile was found but assumed to be available.") return assemble_scripts def detect(self): """Check if current repo should be built with the Python buildpack. """ - pipfile = self.binder_path('Pipfile') - pipfile_lock = self.binder_path('Pipfile.lock') - requirements_txt = self.binder_path('requirements.txt') + # first make sure python is not explicitly unwanted runtime_txt = self.binder_path('runtime.txt') - setup_py = 'setup.py' - if os.path.exists(runtime_txt): with open(runtime_txt) as f: runtime = f.read().strip() - if runtime.startswith("python-"): - return True - else: + if not runtime.startswith("python-"): return False - if not os.path.exists('binder') and os.path.exists(setup_py): - return True - return os.path.exists(pipfile) or os.path.exists(pipfile_lock) or os.path.exists(requirements_txt) + + pipfile = self.binder_path('Pipfile') + pipfile_lock = self.binder_path('Pipfile.lock') + + return os.path.exists(pipfile) or os.path.exists(pipfile_lock) From 42787d28f7fd4d2745735768aaab9f88d91d98d3 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 12 May 2019 15:51:28 +0200 Subject: [PATCH 25/51] extract pipfile: add to ordered list --- repo2docker/app.py | 12 ++++++++++-- repo2docker/buildpacks/__init__.py | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/repo2docker/app.py b/repo2docker/app.py index d951094e6..0b521a503 100644 --- a/repo2docker/app.py +++ b/repo2docker/app.py @@ -30,8 +30,15 @@ from . import __version__ from .buildpacks import ( - PythonBuildPack, DockerBuildPack, LegacyBinderDockerBuildPack, - CondaBuildPack, JuliaProjectTomlBuildPack, JuliaRequireBuildPack, RBuildPack, NixBuildPack + CondaBuildPack, + DockerBuildPack, + JuliaProjectTomlBuildPack, + JuliaRequireBuildPack, + LegacyBinderDockerBuildPack, + NixBuildPack, + PipfileBuildPack, + PythonBuildPack, + RBuildPack, ) from . import contentproviders from .utils import ByteSpecification, chdir @@ -91,6 +98,7 @@ def _default_log_level(self): NixBuildPack, RBuildPack, CondaBuildPack, + PipfileBuildPack, PythonBuildPack, ], config=True, diff --git a/repo2docker/buildpacks/__init__.py b/repo2docker/buildpacks/__init__.py index 73b47bf3c..10fe89a4e 100644 --- a/repo2docker/buildpacks/__init__.py +++ b/repo2docker/buildpacks/__init__.py @@ -1,5 +1,6 @@ from .base import BuildPack, BaseImage from .python import PythonBuildPack +from .pipfile import PipfileBuildPack from .conda import CondaBuildPack from .julia import JuliaProjectTomlBuildPack from .julia import JuliaRequireBuildPack From 9faeaefcf467e67ea73eedce855221464fce0bee Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 12 May 2019 17:26:52 +0200 Subject: [PATCH 26/51] extract pipfile: get binder_dir right finally While trying to update the buildpack for changes in the PR that added support for using a .binder directory I regressed to faulty logic. This PR fixes that, adds some comments to avoid it, and get's things right enough to manage to get the tests to succeed. --- repo2docker/buildpacks/pipfile/__init__.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index f4156ec52..6da567edf 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -84,25 +84,25 @@ def get_assemble_scripts(self): # install Pipfile.lock or fallback to installing Pipfile pipenv = '${KERNEL_PYTHON_PREFIX}/bin/pipenv' + python = '${KERNEL_PYTHON_PREFIX}/bin/python' pipfile = self.binder_path('Pipfile') pipfile_lock = self.binder_path('Pipfile.lock') - working_directory = 'binder' if os.path.exists('binder') else '.' + working_directory = self.binder_dir or '.' assemble_scripts.append(( '${NB_USER}', 'pip install pipenv' )) - if os.path.exists(pipfile_lock): + # if Pipfile.lock isn't found, Pipfile is used to create one + if not os.path.exists(pipfile_lock): assemble_scripts.append(( '${NB_USER}', - '(cd {} && {} install --ignore-pipfile --deploy --system --dev --python {})'.format(working_directory, pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') + '(cd {} && {} lock --python {})'.format(working_directory, pipenv, python) )) - elif os.path.exists(pipfile): - assemble_scripts.append(( - '${NB_USER}', - '(cd {} && {} lock --python {})'.format(working_directory, pipenv, '${KERNEL_PYTHON_PREFIX}/bin/python') - )) - else: - raise Exception("Neither Pipfile.lock or Pipfile was found but assumed to be available.") + # install Pipfile.lock + assemble_scripts.append(( + '${NB_USER}', + '(cd {} && {} install --ignore-pipfile --deploy --system --dev --python {})'.format(working_directory, pipenv, python) + )) return assemble_scripts From 5367f805411d6df5bdb721ac268244850de076a9 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 12 May 2019 17:45:17 +0200 Subject: [PATCH 27/51] Test Pipfile in binder-dir with Setup.py --- .../setup-py-explicit-in-binder-dir/.binder/Pipfile | 8 ++++++++ .../setup-py-explicit-in-binder-dir/README.rst | 5 +++++ .../dummy/__init__.py | 2 ++ .../pipfile/setup-py-explicit-in-binder-dir/setup.py | 12 ++++++++++++ tests/pipfile/setup-py-explicit-in-binder-dir/verify | 6 ++++++ 5 files changed, 33 insertions(+) create mode 100644 tests/pipfile/setup-py-explicit-in-binder-dir/.binder/Pipfile create mode 100644 tests/pipfile/setup-py-explicit-in-binder-dir/README.rst create mode 100644 tests/pipfile/setup-py-explicit-in-binder-dir/dummy/__init__.py create mode 100644 tests/pipfile/setup-py-explicit-in-binder-dir/setup.py create mode 100755 tests/pipfile/setup-py-explicit-in-binder-dir/verify diff --git a/tests/pipfile/setup-py-explicit-in-binder-dir/.binder/Pipfile b/tests/pipfile/setup-py-explicit-in-binder-dir/.binder/Pipfile new file mode 100644 index 000000000..447541a77 --- /dev/null +++ b/tests/pipfile/setup-py-explicit-in-binder-dir/.binder/Pipfile @@ -0,0 +1,8 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +there = "*" +dummy = {path="..", editable=true} diff --git a/tests/pipfile/setup-py-explicit-in-binder-dir/README.rst b/tests/pipfile/setup-py-explicit-in-binder-dir/README.rst new file mode 100644 index 000000000..af01af38a --- /dev/null +++ b/tests/pipfile/setup-py-explicit-in-binder-dir/README.rst @@ -0,0 +1,5 @@ +Python - Pipfile + setup.py +--------------------------- + +The Pipfile asked the local package in the parent directory to be installed with +``setup.py``, was it? diff --git a/tests/pipfile/setup-py-explicit-in-binder-dir/dummy/__init__.py b/tests/pipfile/setup-py-explicit-in-binder-dir/dummy/__init__.py new file mode 100644 index 000000000..012898812 --- /dev/null +++ b/tests/pipfile/setup-py-explicit-in-binder-dir/dummy/__init__.py @@ -0,0 +1,2 @@ +def dummy(): + pass diff --git a/tests/pipfile/setup-py-explicit-in-binder-dir/setup.py b/tests/pipfile/setup-py-explicit-in-binder-dir/setup.py new file mode 100644 index 000000000..d503ec263 --- /dev/null +++ b/tests/pipfile/setup-py-explicit-in-binder-dir/setup.py @@ -0,0 +1,12 @@ +from setuptools import setup, find_packages + +setup( + name='Dummy', + version='1.0.0', + url='https://git-place.org/dummy/dummy.git', + author='Dummy Name', + author_email='dummy@my-email.com', + description='Dummy package for testing purposes only', + packages=find_packages(), + install_requires=['pypi-pkg-test==0.0.4'], +) diff --git a/tests/pipfile/setup-py-explicit-in-binder-dir/verify b/tests/pipfile/setup-py-explicit-in-binder-dir/verify new file mode 100755 index 000000000..4c6eaf1e0 --- /dev/null +++ b/tests/pipfile/setup-py-explicit-in-binder-dir/verify @@ -0,0 +1,6 @@ +#!/usr/bin/env python +import there +import dummy + +# This package should be available, as it was a dependency for dummy +import pypi_pkg_test From 6de7a8c97abd7b3709387640644b6ee58e5b277e Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 4 Jun 2019 09:14:32 +0200 Subject: [PATCH 28/51] Black formatting applied --- repo2docker/buildpacks/pipfile/__init__.py | 86 +++++++++++-------- .../setup-py-explicit-in-binder-dir/setup.py | 14 +-- tests/pipfile/setup-py-explicit/setup.py | 14 +-- tests/pipfile/setup-py-implicit/setup.py | 14 +-- 4 files changed, 69 insertions(+), 59 deletions(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 6da567edf..2ff861454 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -4,6 +4,7 @@ from ..conda import CondaBuildPack + class PipfileBuildPack(CondaBuildPack): """Setup Python with pipfile for use with a repository.""" @@ -15,30 +16,30 @@ def python_version(self): Falsy empty string '' if not found. """ - if hasattr(self, '_python_version'): + if hasattr(self, "_python_version"): return self._python_version files_to_search_in_order = [ { - 'path': self.binder_path('Pipfile.lock'), - 'pattern': r'\s*\"python_(?:full_)?version\": \"?([0-9a-z\.]*)\"?', # ' "python_version": "3.6"' + "path": self.binder_path("Pipfile.lock"), + "pattern": r"\s*\"python_(?:full_)?version\": \"?([0-9a-z\.]*)\"?", # ' "python_version": "3.6"' }, { - 'path': self.binder_path('Pipfile'), - 'pattern': r'python_(?:full_)?version\s*=+\s*\"?([0-9a-z\.]*)\"?', # 'python_version = "3.6"' + "path": self.binder_path("Pipfile"), + "pattern": r"python_(?:full_)?version\s*=+\s*\"?([0-9a-z\.]*)\"?", # 'python_version = "3.6"' }, { - 'path': self.binder_path('runtime.txt'), - 'pattern': r'\s*python-([0-9a-z\.]*)\s*', # 'python-3.6' + "path": self.binder_path("runtime.txt"), + "pattern": r"\s*python-([0-9a-z\.]*)\s*", # 'python-3.6' }, ] py_version = None for file in files_to_search_in_order: try: - with open(file['path']) as f: + with open(file["path"]) as f: for line in f: - match = re.match(file['pattern'], line) + match = re.match(file["pattern"], line) if not match: continue py_version = match.group(1) @@ -54,11 +55,11 @@ def python_version(self): self._python_version = self.major_pythons.get(py_version[0]) else: # return major.minor - self._python_version = '.'.join(py_version.split('.')[:2]) + self._python_version = ".".join(py_version.split(".")[:2]) return self._python_version else: # use the default Python - self._python_version = self.major_pythons['3'] + self._python_version = self.major_pythons["3"] return self._python_version def get_assemble_scripts(self): @@ -73,36 +74,45 @@ def get_assemble_scripts(self): if self.py2: # using python 2 kernel, # requirements3.txt allows installation in the notebook server env - nb_requirements_file = self.binder_path('requirements3.txt') + nb_requirements_file = self.binder_path("requirements3.txt") if os.path.exists(nb_requirements_file): - assemble_scripts.append(( - '${NB_USER}', - # want the $NB_PYHTON_PREFIX environment variable, not for - # Python's string formatting to try and replace this - '${{NB_PYTHON_PREFIX}}/bin/pip install --no-cache-dir -r "{}"'.format(nb_requirements_file) - )) + assemble_scripts.append( + ( + "${NB_USER}", + # want the $NB_PYHTON_PREFIX environment variable, not for + # Python's string formatting to try and replace this + '${{NB_PYTHON_PREFIX}}/bin/pip install --no-cache-dir -r "{}"'.format( + nb_requirements_file + ), + ) + ) # install Pipfile.lock or fallback to installing Pipfile - pipenv = '${KERNEL_PYTHON_PREFIX}/bin/pipenv' - python = '${KERNEL_PYTHON_PREFIX}/bin/python' - pipfile = self.binder_path('Pipfile') - pipfile_lock = self.binder_path('Pipfile.lock') - working_directory = self.binder_dir or '.' - assemble_scripts.append(( - '${NB_USER}', - 'pip install pipenv' - )) + pipenv = "${KERNEL_PYTHON_PREFIX}/bin/pipenv" + python = "${KERNEL_PYTHON_PREFIX}/bin/python" + pipfile = self.binder_path("Pipfile") + pipfile_lock = self.binder_path("Pipfile.lock") + working_directory = self.binder_dir or "." + assemble_scripts.append(("${NB_USER}", "pip install pipenv")) # if Pipfile.lock isn't found, Pipfile is used to create one if not os.path.exists(pipfile_lock): - assemble_scripts.append(( - '${NB_USER}', - '(cd {} && {} lock --python {})'.format(working_directory, pipenv, python) - )) + assemble_scripts.append( + ( + "${NB_USER}", + "(cd {} && {} lock --python {})".format( + working_directory, pipenv, python + ), + ) + ) # install Pipfile.lock - assemble_scripts.append(( - '${NB_USER}', - '(cd {} && {} install --ignore-pipfile --deploy --system --dev --python {})'.format(working_directory, pipenv, python) - )) + assemble_scripts.append( + ( + "${NB_USER}", + "(cd {} && {} install --ignore-pipfile --deploy --system --dev --python {})".format( + working_directory, pipenv, python + ), + ) + ) return assemble_scripts @@ -110,14 +120,14 @@ def detect(self): """Check if current repo should be built with the Python buildpack. """ # first make sure python is not explicitly unwanted - runtime_txt = self.binder_path('runtime.txt') + runtime_txt = self.binder_path("runtime.txt") if os.path.exists(runtime_txt): with open(runtime_txt) as f: runtime = f.read().strip() if not runtime.startswith("python-"): return False - pipfile = self.binder_path('Pipfile') - pipfile_lock = self.binder_path('Pipfile.lock') + pipfile = self.binder_path("Pipfile") + pipfile_lock = self.binder_path("Pipfile.lock") return os.path.exists(pipfile) or os.path.exists(pipfile_lock) diff --git a/tests/pipfile/setup-py-explicit-in-binder-dir/setup.py b/tests/pipfile/setup-py-explicit-in-binder-dir/setup.py index d503ec263..c67a722a7 100644 --- a/tests/pipfile/setup-py-explicit-in-binder-dir/setup.py +++ b/tests/pipfile/setup-py-explicit-in-binder-dir/setup.py @@ -1,12 +1,12 @@ from setuptools import setup, find_packages setup( - name='Dummy', - version='1.0.0', - url='https://git-place.org/dummy/dummy.git', - author='Dummy Name', - author_email='dummy@my-email.com', - description='Dummy package for testing purposes only', + name="Dummy", + version="1.0.0", + url="https://git-place.org/dummy/dummy.git", + author="Dummy Name", + author_email="dummy@my-email.com", + description="Dummy package for testing purposes only", packages=find_packages(), - install_requires=['pypi-pkg-test==0.0.4'], + install_requires=["pypi-pkg-test==0.0.4"], ) diff --git a/tests/pipfile/setup-py-explicit/setup.py b/tests/pipfile/setup-py-explicit/setup.py index d503ec263..c67a722a7 100644 --- a/tests/pipfile/setup-py-explicit/setup.py +++ b/tests/pipfile/setup-py-explicit/setup.py @@ -1,12 +1,12 @@ from setuptools import setup, find_packages setup( - name='Dummy', - version='1.0.0', - url='https://git-place.org/dummy/dummy.git', - author='Dummy Name', - author_email='dummy@my-email.com', - description='Dummy package for testing purposes only', + name="Dummy", + version="1.0.0", + url="https://git-place.org/dummy/dummy.git", + author="Dummy Name", + author_email="dummy@my-email.com", + description="Dummy package for testing purposes only", packages=find_packages(), - install_requires=['pypi-pkg-test==0.0.4'], + install_requires=["pypi-pkg-test==0.0.4"], ) diff --git a/tests/pipfile/setup-py-implicit/setup.py b/tests/pipfile/setup-py-implicit/setup.py index d503ec263..c67a722a7 100644 --- a/tests/pipfile/setup-py-implicit/setup.py +++ b/tests/pipfile/setup-py-implicit/setup.py @@ -1,12 +1,12 @@ from setuptools import setup, find_packages setup( - name='Dummy', - version='1.0.0', - url='https://git-place.org/dummy/dummy.git', - author='Dummy Name', - author_email='dummy@my-email.com', - description='Dummy package for testing purposes only', + name="Dummy", + version="1.0.0", + url="https://git-place.org/dummy/dummy.git", + author="Dummy Name", + author_email="dummy@my-email.com", + description="Dummy package for testing purposes only", packages=find_packages(), - install_requires=['pypi-pkg-test==0.0.4'], + install_requires=["pypi-pkg-test==0.0.4"], ) From c30337097efb8467ab069ba6e09509feeb6e37ac Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 18 Jun 2019 00:38:06 +0200 Subject: [PATCH 29/51] Autoformatting applied --- tests/pipfile/pipfile-lock/verify | 4 +++- tests/pipfile/requirements-txt/verify | 4 +++- tests/pipfile/setup-py-implicit/verify | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/pipfile/pipfile-lock/verify b/tests/pipfile/pipfile-lock/verify index 9c1142f28..3ff758eab 100755 --- a/tests/pipfile/pipfile-lock/verify +++ b/tests/pipfile/pipfile-lock/verify @@ -8,4 +8,6 @@ except ImportError: # We want an ImportError to be thrown for this test to pass pass else: - raise Exception("'numpy' shouldn't have been installed! It was listed in Pipfile but not in the Pipfile.lock.") + raise Exception( + "'numpy' shouldn't have been installed! It was listed in Pipfile but not in the Pipfile.lock." + ) diff --git a/tests/pipfile/requirements-txt/verify b/tests/pipfile/requirements-txt/verify index 49e31463f..a2c82b81c 100755 --- a/tests/pipfile/requirements-txt/verify +++ b/tests/pipfile/requirements-txt/verify @@ -8,4 +8,6 @@ except ImportError: # We want an ImportError to be thrown for this test to pass pass else: - raise Exception("'numpy' shouldn't have been installed! It was listed in requirements.txt but not in the Pipfile that has precedence.") + raise Exception( + "'numpy' shouldn't have been installed! It was listed in requirements.txt but not in the Pipfile that has precedence." + ) diff --git a/tests/pipfile/setup-py-implicit/verify b/tests/pipfile/setup-py-implicit/verify index d994d9218..3f90de46c 100755 --- a/tests/pipfile/setup-py-implicit/verify +++ b/tests/pipfile/setup-py-implicit/verify @@ -8,4 +8,6 @@ except ImportError: # We want an ImportError to be thrown for this test to pass pass else: - raise Exception("'dummy' and its dependency 'pypi_pkg_test' shouldn't have been installed! A Pipfile was present without explicit instructions to install the local package 'dummy'.") + raise Exception( + "'dummy' and its dependency 'pypi_pkg_test' shouldn't have been installed! A Pipfile was present without explicit instructions to install the local package 'dummy'." + ) From 8153fd9b4da7bd65c1b60c4cd6bbdef9ff5da6af Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sat, 22 Jun 2019 16:03:44 +0200 Subject: [PATCH 30/51] Fix typo Co-Authored-By: Tim Head --- repo2docker/buildpacks/pipfile/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 2ff861454..4bb028b7c 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -117,7 +117,7 @@ def get_assemble_scripts(self): return assemble_scripts def detect(self): - """Check if current repo should be built with the Python buildpack. + """Check if current repo should be built with the Pipfile buildpack. """ # first make sure python is not explicitly unwanted runtime_txt = self.binder_path("runtime.txt") From a8c232e6a580ecea0871f74dd6cfb3c4e36b7d7d Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sat, 22 Jun 2019 17:35:35 +0200 Subject: [PATCH 31/51] Adjust copied notes to the Pipfile buildpack --- repo2docker/buildpacks/pipfile/__init__.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 4bb028b7c..3e2916680 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -65,10 +65,14 @@ def python_version(self): def get_assemble_scripts(self): """Return series of build-steps specific to this repository. """ - # If we have a runtime.txt & that's set to python-2.7, - # requirements.txt will be installed in the *kernel* env - # and requirements3.txt (if it exists) - # will be installed in the python 3 notebook server env. + # If we have either Pipfile.lock, Pipfile, or runtime.txt declare the + # use of Python 2, Python 2.7 will be made available in the *kernel* + # environment. The notebook servers environment on the other hand + # requires Python 3 but may require something additional installed in it + # still such as `nbgitpuller`. For this purpose, a "requirements3.txt" + # file will be used to install dependencies for the notebook servers + # environment, if Python 2 had been specified for the kernel + # environment. assemble_scripts = super().get_assemble_scripts() if self.py2: From c9fd0a99c8269ac6fc3218d304449bb03f157afb Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sat, 22 Jun 2019 17:51:48 +0200 Subject: [PATCH 32/51] Clarify Pipfile's use of relative paths --- repo2docker/buildpacks/pipfile/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 3e2916680..060f5ed6f 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -96,6 +96,9 @@ def get_assemble_scripts(self): python = "${KERNEL_PYTHON_PREFIX}/bin/python" pipfile = self.binder_path("Pipfile") pipfile_lock = self.binder_path("Pipfile.lock") + # let pipenv work relative to the dir that has the Pipfile that can + # contain relative references such as: + # my_package = {path=".", editable=true} working_directory = self.binder_dir or "." assemble_scripts.append(("${NB_USER}", "pip install pipenv")) # if Pipfile.lock isn't found, Pipfile is used to create one From 2189777198723fa80907c99cb7009943a4d9b308 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sat, 22 Jun 2019 17:55:23 +0200 Subject: [PATCH 33/51] Fix Pipfile buildpack's docstring --- repo2docker/buildpacks/pipfile/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 060f5ed6f..c0262e847 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -1,4 +1,7 @@ -"""Generates Dockerfiles based on an input matrix based on Python.""" +"""Buildpack for git repos with Pipfile.lock or Pipfile within them. `pipenv` +will be used to install the dependencies but we will manually install declared +Python versions instead of using PyEnv.""" + import os import re @@ -96,8 +99,8 @@ def get_assemble_scripts(self): python = "${KERNEL_PYTHON_PREFIX}/bin/python" pipfile = self.binder_path("Pipfile") pipfile_lock = self.binder_path("Pipfile.lock") - # let pipenv work relative to the dir that has the Pipfile that can - # contain relative references such as: + # let pipenv work relative to the dir that has the Pipfile, it is + # important as they can contain relative references such as: # my_package = {path=".", editable=true} working_directory = self.binder_dir or "." assemble_scripts.append(("${NB_USER}", "pip install pipenv")) From 7bb5a92ff895fb68ffc8cd7b8c1e9d5f350f3ca1 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sat, 22 Jun 2019 18:07:06 +0200 Subject: [PATCH 34/51] Fix Pipfile buildpacks python version detection --- repo2docker/buildpacks/pipfile/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index c0262e847..4db27481f 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -25,11 +25,11 @@ def python_version(self): files_to_search_in_order = [ { "path": self.binder_path("Pipfile.lock"), - "pattern": r"\s*\"python_(?:full_)?version\": \"?([0-9a-z\.]*)\"?", # ' "python_version": "3.6"' + "pattern": r"\s*[\",\']python_(?:full_)?version[\",\']: [\",\']?([0-9a-z\.]*)[\",\']?", # ' "python_version": "3.6"' }, { "path": self.binder_path("Pipfile"), - "pattern": r"python_(?:full_)?version\s*=+\s*\"?([0-9a-z\.]*)\"?", # 'python_version = "3.6"' + "pattern": r"python_(?:full_)?version\s*=+\s*[\",\']?([0-9a-z\.]*)[\",\']?", # 'python_version = "3.6"' }, { "path": self.binder_path("runtime.txt"), From ebed50486106d1605c5672d7f8ac7e3a36f6e6ec Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 23 Jun 2019 05:44:54 +0200 Subject: [PATCH 35/51] semver back to Pipfile.lock --- Pipfile.lock | 494 ++++++++++++++++++++++++++++----------------------- 1 file changed, 276 insertions(+), 218 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 457870cc8..8c85e04c8 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -16,10 +16,10 @@ "default": { "certifi": { "hashes": [ - "sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7", - "sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033" + "sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939", + "sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695" ], - "version": "==2018.11.29" + "version": "==2019.6.16" }, "chardet": { "hashes": [ @@ -30,24 +30,17 @@ }, "decorator": { "hashes": [ - "sha256:33cd704aea07b4c28b3eb2c97d288a06918275dac0ecebdaf1bc8a48d98adb9e", - "sha256:cabb249f4710888a2fc0e13e9a16c343d932033718ff62e1e9bc93a9d3a9122b" + "sha256:86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de", + "sha256:f069f3a01830ca754ba5258fde2278454a0b5b79e0d7f5c13b3b97e57d4acff6" ], - "version": "==4.3.2" + "version": "==4.4.0" }, "docker": { "hashes": [ - "sha256:2840ffb9dc3ef6d00876bde476690278ab13fa1f8ba9127ef855ac33d00c3152", - "sha256:5831256da3477723362bc71a8df07b8cd8493e4a4a60cebd45580483edbe48ae" + "sha256:acf51b5e3e0d056925c3b780067a6f753c915fffaa46c5f2d79eb0fc1cbe6a01", + "sha256:cc5b2e94af6a2b1e1ed9d7dcbdc77eff56c36081757baf9ada6e878ea0213164" ], - "version": "==3.7.0" - }, - "docker-pycreds": { - "hashes": [ - "sha256:6ce3270bcaf404cc4c3e27e4b6c70d3521deae82fb508767870fdbf772d584d4", - "sha256:7266112468627868005106ec19cd0d722702d2b7d5912a28e19b826c3d37af49" - ], - "version": "==0.4.0" + "version": "==4.0.2" }, "escapism": { "hashes": [ @@ -72,50 +65,49 @@ }, "jinja2": { "hashes": [ - "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd", - "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4" + "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", + "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" ], - "version": "==2.10" + "version": "==2.10.1" }, "markupsafe": { "hashes": [ - "sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432", - "sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b", - "sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9", - "sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af", - "sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834", - "sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd", - "sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d", - "sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7", - "sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b", - "sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3", - "sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c", - "sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2", - "sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7", - "sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36", - "sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1", - "sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e", - "sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1", - "sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c", - "sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856", - "sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550", - "sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492", - "sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672", - "sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401", - "sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6", - "sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6", - "sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c", - "sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd", - "sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1" - ], - "version": "==1.1.0" + "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", + "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", + "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", + "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", + "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", + "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", + "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", + "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", + "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", + "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", + "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", + "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", + "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", + "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", + "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + ], + "version": "==1.1.1" }, "python-json-logger": { "hashes": [ - "sha256:3e000053837500f9eb28d6228d7cb99fabfc1874d34b40c08289207292abaf2e", - "sha256:cf2caaf34bd2eff394915b6242de4d0245de79971712439380ece6f149748cde" + "sha256:b7a31162f2a01965a5efb94453ce69230ed208468b0bbc7fdfc56e6d8df2e281" ], - "version": "==0.1.10" + "version": "==0.1.11" }, "repo2docker": { "editable": true, @@ -123,37 +115,40 @@ }, "requests": { "hashes": [ - "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e", - "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b" + "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", + "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" ], - "version": "==2.21.0" + "version": "==2.22.0" }, "ruamel.yaml": { "hashes": [ - "sha256:0289a685479d059b94683cd6cb47ffb790c05c20a6c4da395361025d52493d0a", - "sha256:0adf1d9b8e88dc6b151a3199b1dd7be0c8ee10d6c2ebd2a9e2a13224f4481cdf", - "sha256:13657c26780bba5824764cddb0f2933217fd59cfcca0e2ee1b2f759e7e58ef8e", - "sha256:3815f688de7316fcd3ba5ceda642e902044c5c1a8fb5e4dc245d99db3eb3121b", - "sha256:4e61c0b96805d1e2ec53cb1698ca6086a47aa1e1d09857144eb60216e7894ce3", - "sha256:4f0d57ead5414456cb899c3746a8d30f566c22bb90c97da76f76e79147cb2d61", - "sha256:51916929902ff054e189d29bc418788a5dc3a4e89a89065beed694f537383ca3", - "sha256:5b7ea0ee24680157666f730f3a8c173f386c66e8c103458af20d97276e7e54d3", - "sha256:6b1b1ee0a028b9cdc1bc3ec1f75480fc0d3fbcc9e0212a716b129b6f26e34587", - "sha256:6db27f789c7efdbc59b8650c37a09dde0db019560bc19a07c905b65158a18bba", - "sha256:7a8c8f825fd52f3586d583f621cdf3a03b9dc8833933ae401554b246b48026d5", - "sha256:7ab0c27094ef27a21e0094dc671c456bd4a62811c14e27407ae8bc3aa8cc8111", - "sha256:8e06bcf212b45dffe6c2415693c32b4c7d4ff55c03268a3033217f7a673d07ba", - "sha256:9826e3c85549b3fc87786466a7a96dcadec59802a9ed077b905349ef1cac7b14", - "sha256:ac56193c47a31c9efa151064a9e921865cdad0f7a991d229e7197e12fe8e0cd7", - "sha256:aef88ec2927b0454709026a761918c02b69e5df9c061b49634d7993c0848580d", - "sha256:d8591fdfd076d8121a456aaff0bbea6d5753023896f4559b710d4e56d1ac6418", - "sha256:e033423fd6b4ddfd47f0f5ebe81e896129d85fd5219c5e66effb4de06a1fea7a", - "sha256:e05017af8c1164fee33aa2677df7eaeb6d2fa76e22baf7960f9e8f1b04657151", - "sha256:e4cd2ccd4d455206826a7c59fda13a9008ae994de66a7b0df2c0bb81121fab01", - "sha256:e4f525efdecc075e6b0d96df0ae4bd2ad17c7280ebe66035f468c5c3da53fe0d", - "sha256:fd5f09c399cdc92586b54ee28f68f23f1d5649177d7ceb22ec975b5e69e1b722" - ], - "version": "==0.15.88" + "sha256:17dbf6b7362e7aee8494f7a0f5cffd44902a6331fe89ef0853b855a7930ab845", + "sha256:23731c9efb79f3f5609dedffeb6c5c47a68125fd3d4b157d9fc71b1cd49076a9", + "sha256:2bbdd598ae57bac20968cf9028cc67d37d83bdb7942a94b9478110bc72193148", + "sha256:34586084cdd60845a3e1bece2b58f0a889be25450db8cc0ea143ddf0f40557a2", + "sha256:35957fedbb287b01313bb5c556ffdc70c0277c3500213b5e73dfd8716f748d77", + "sha256:414cb87a40974a575830b406ffab4ab8c6cbd82eeb73abd2a9d1397c1f0223e1", + "sha256:428775be75db68d908b17e4e8dda424c410222f170dc173246aa63e972d094b3", + "sha256:514f670f7d36519bda504d507edfe63e3c20489f86c86d42bc4d9a6dbdf82c7b", + "sha256:5cb962c1ac6887c5da29138fbbe3b4b7705372eb54e599907fa63d4cd743246d", + "sha256:5f6e30282cf70fb7754e1a5f101e27b5240009766376e131b31ab49f14fe81be", + "sha256:86f8e010af6af0b4f42de2d0d9b19cb441e61d3416082186f9dd03c8552d13ad", + "sha256:8d47ed1e557d546bd2dfe54f504d7274274602ff7a0652cde84c258ad6c2d96d", + "sha256:98668876720bce1ac08562d8b93a564a80e3397e442c7ea19cebdcdf73da7f74", + "sha256:9e1f0ddc18d8355dcf5586a5d90417df56074f237812b8682a93b62cca9d2043", + "sha256:a7bc812a72a79d6b7dbb96fa5bee3950464b65ec055d3abc4db6572f2373a95c", + "sha256:b72e13f9f206ee103247b07afd5a39c8b1aa98e8eba80ddba184d030337220ba", + "sha256:bcff8ea9d916789e85e24beed8830c157fb8bc7c313e554733a8151540e66c01", + "sha256:c76e78b3bab652069b8d6f7889b0e72f3455c2b854b2e0a8818393d149ad0a0d" + ], + "version": "==0.15.97" + }, + "semver": { + "hashes": [ + "sha256:41c9aa26c67dc16c54be13074c352ab666bce1fa219c7110e8f03374cd4206b0", + "sha256:5b09010a66d9a3837211bb7ae5a20d10ba88f8cb49e92cb139a69ef90d5060d8" + ], + "version": "==2.8.1" }, "six": { "hashes": [ @@ -162,6 +157,13 @@ ], "version": "==1.12.0" }, + "toml": { + "hashes": [ + "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", + "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e" + ], + "version": "==0.10.0" + }, "traitlets": { "hashes": [ "sha256:9c4bd2d267b7153df9152698efb1050a5d84982d3384a37b2c1f7723ba3e7835", @@ -171,17 +173,17 @@ }, "urllib3": { "hashes": [ - "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39", - "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22" + "sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1", + "sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232" ], - "version": "==1.24.1" + "version": "==1.25.3" }, "websocket-client": { "hashes": [ - "sha256:8c8bf2d4f800c3ed952df206b18c28f7070d9e3dcbd6ca6291127574f57ee786", - "sha256:e51562c91ddb8148e791f0155fdb01325d99bb52c4cdbb291aee7a3563fd0849" + "sha256:1151d5fb3a62dc129164292e1227655e4bbc5dd5340a5165dfae61128ec50aa9", + "sha256:1fd5520878b68b84b5748bb30e592b10d0a91529d5383f74f4964e72b297fd3a" ], - "version": "==0.54.0" + "version": "==0.56.0" } }, "develop": { @@ -195,11 +197,11 @@ }, "alabaster-jupyterhub": { "hashes": [ - "sha256:8525ff6f6cbdc1b2506df4b14e5f5d657dfdf6fbba6eb8e8a7c3275640810e34", - "sha256:b95edd7899a23cc0d4fcd9eb8946aa5d4e599d42e13e6b729aa0b1a7ec740c51" + "sha256:00911ff8828996c44dadc1aa234853b98d91c6a0c25153dde4b2c241cd0851c7", + "sha256:787c7a895f2fdfab5adc1478bd6925a287cee6dcf12ac8ccf565c6856969a4ef" ], "index": "pypi", - "version": "==0.1.4" + "version": "==0.1.8" }, "atomicwrites": { "hashes": [ @@ -210,24 +212,24 @@ }, "attrs": { "hashes": [ - "sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69", - "sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb" + "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", + "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" ], - "version": "==18.2.0" + "version": "==19.1.0" }, "babel": { "hashes": [ - "sha256:6778d85147d5d85345c14a26aada5e478ab04e39b078b0745ee6870c2b5cf669", - "sha256:8cba50f48c529ca3fa18cf81fa9403be176d374ac4d60738b839122dfaaa3d23" + "sha256:af92e6106cb7c55286b25b38ad7695f8b4efb36a90ba483d7f7a6628c46158ab", + "sha256:e86135ae101e31e2c8ec20a4e0c5220f4eed12487d5cf3f78be7e98d3a57fc28" ], - "version": "==2.6.0" + "version": "==2.7.0" }, "certifi": { "hashes": [ - "sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7", - "sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033" + "sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939", + "sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695" ], - "version": "==2018.11.29" + "version": "==2019.6.16" }, "chardet": { "hashes": [ @@ -238,46 +240,46 @@ }, "commonmark": { "hashes": [ - "sha256:9f6dda7876b2bb88dd784440166f4bc8e56cb2b2551264051123bacb0b6c1d8a", - "sha256:abcbc854e0eae5deaf52ae5e328501b78b4a0758bf98ac8bb792fce993006084" + "sha256:14c3df31e8c9c463377e287b2a1eefaa6019ab97b22dad36e2f32be59d61d68d", + "sha256:867fc5db078ede373ab811e16b6789e9d033b15ccd7296f370ca52d1ee792ce0" ], - "version": "==0.8.1" + "version": "==0.9.0" }, "coverage": { "hashes": [ - "sha256:09e47c529ff77bf042ecfe858fb55c3e3eb97aac2c87f0349ab5a7efd6b3939f", - "sha256:0a1f9b0eb3aa15c990c328535655847b3420231af299386cfe5efc98f9c250fe", - "sha256:0cc941b37b8c2ececfed341444a456912e740ecf515d560de58b9a76562d966d", - "sha256:10e8af18d1315de936d67775d3a814cc81d0747a1a0312d84e27ae5610e313b0", - "sha256:1b4276550b86caa60606bd3572b52769860a81a70754a54acc8ba789ce74d607", - "sha256:1e8a2627c48266c7b813975335cfdea58c706fe36f607c97d9392e61502dc79d", - "sha256:2b224052bfd801beb7478b03e8a66f3f25ea56ea488922e98903914ac9ac930b", - "sha256:447c450a093766744ab53bf1e7063ec82866f27bcb4f4c907da25ad293bba7e3", - "sha256:46101fc20c6f6568561cdd15a54018bb42980954b79aa46da8ae6f008066a30e", - "sha256:4710dc676bb4b779c4361b54eb308bc84d64a2fa3d78e5f7228921eccce5d815", - "sha256:510986f9a280cd05189b42eee2b69fecdf5bf9651d4cd315ea21d24a964a3c36", - "sha256:5535dda5739257effef56e49a1c51c71f1d37a6e5607bb25a5eee507c59580d1", - "sha256:5a7524042014642b39b1fcae85fb37556c200e64ec90824ae9ecf7b667ccfc14", - "sha256:5f55028169ef85e1fa8e4b8b1b91c0b3b0fa3297c4fb22990d46ff01d22c2d6c", - "sha256:6694d5573e7790a0e8d3d177d7a416ca5f5c150742ee703f3c18df76260de794", - "sha256:6831e1ac20ac52634da606b658b0b2712d26984999c9d93f0c6e59fe62ca741b", - "sha256:77f0d9fa5e10d03aa4528436e33423bfa3718b86c646615f04616294c935f840", - "sha256:828ad813c7cdc2e71dcf141912c685bfe4b548c0e6d9540db6418b807c345ddd", - "sha256:85a06c61598b14b015d4df233d249cd5abfa61084ef5b9f64a48e997fd829a82", - "sha256:8cb4febad0f0b26c6f62e1628f2053954ad2c555d67660f28dfb1b0496711952", - "sha256:a5c58664b23b248b16b96253880b2868fb34358911400a7ba39d7f6399935389", - "sha256:aaa0f296e503cda4bc07566f592cd7a28779d433f3a23c48082af425d6d5a78f", - "sha256:ab235d9fe64833f12d1334d29b558aacedfbca2356dfb9691f2d0d38a8a7bfb4", - "sha256:b3b0c8f660fae65eac74fbf003f3103769b90012ae7a460863010539bb7a80da", - "sha256:bab8e6d510d2ea0f1d14f12642e3f35cefa47a9b2e4c7cea1852b52bc9c49647", - "sha256:c45297bbdbc8bb79b02cf41417d63352b70bcb76f1bbb1ee7d47b3e89e42f95d", - "sha256:d19bca47c8a01b92640c614a9147b081a1974f69168ecd494687c827109e8f42", - "sha256:d64b4340a0c488a9e79b66ec9f9d77d02b99b772c8b8afd46c1294c1d39ca478", - "sha256:da969da069a82bbb5300b59161d8d7c8d423bc4ccd3b410a9b4d8932aeefc14b", - "sha256:ed02c7539705696ecb7dc9d476d861f3904a8d2b7e894bd418994920935d36bb", - "sha256:ee5b8abc35b549012e03a7b1e86c09491457dba6c94112a2482b18589cc2bdb9" - ], - "version": "==4.5.2" + "sha256:3684fabf6b87a369017756b551cef29e505cb155ddb892a7a29277b978da88b9", + "sha256:39e088da9b284f1bd17c750ac672103779f7954ce6125fd4382134ac8d152d74", + "sha256:3c205bc11cc4fcc57b761c2da73b9b72a59f8d5ca89979afb0c1c6f9e53c7390", + "sha256:465ce53a8c0f3a7950dfb836438442f833cf6663d407f37d8c52fe7b6e56d7e8", + "sha256:48020e343fc40f72a442c8a1334284620f81295256a6b6ca6d8aa1350c763bbe", + "sha256:5296fc86ab612ec12394565c500b412a43b328b3907c0d14358950d06fd83baf", + "sha256:5f61bed2f7d9b6a9ab935150a6b23d7f84b8055524e7be7715b6513f3328138e", + "sha256:68a43a9f9f83693ce0414d17e019daee7ab3f7113a70c79a3dd4c2f704e4d741", + "sha256:6b8033d47fe22506856fe450470ccb1d8ba1ffb8463494a15cfc96392a288c09", + "sha256:7ad7536066b28863e5835e8cfeaa794b7fe352d99a8cded9f43d1161be8e9fbd", + "sha256:7bacb89ccf4bedb30b277e96e4cc68cd1369ca6841bde7b005191b54d3dd1034", + "sha256:839dc7c36501254e14331bcb98b27002aa415e4af7ea039d9009409b9d2d5420", + "sha256:8f9a95b66969cdea53ec992ecea5406c5bd99c9221f539bca1e8406b200ae98c", + "sha256:932c03d2d565f75961ba1d3cec41ddde00e162c5b46d03f7423edcb807734eab", + "sha256:988529edadc49039d205e0aa6ce049c5ccda4acb2d6c3c5c550c17e8c02c05ba", + "sha256:998d7e73548fe395eeb294495a04d38942edb66d1fa61eb70418871bc621227e", + "sha256:9de60893fb447d1e797f6bf08fdf0dbcda0c1e34c1b06c92bd3a363c0ea8c609", + "sha256:9e80d45d0c7fcee54e22771db7f1b0b126fb4a6c0a2e5afa72f66827207ff2f2", + "sha256:a545a3dfe5082dc8e8c3eb7f8a2cf4f2870902ff1860bd99b6198cfd1f9d1f49", + "sha256:a5d8f29e5ec661143621a8f4de51adfb300d7a476224156a39a392254f70687b", + "sha256:aca06bfba4759bbdb09bf52ebb15ae20268ee1f6747417837926fae990ebc41d", + "sha256:bb23b7a6fd666e551a3094ab896a57809e010059540ad20acbeec03a154224ce", + "sha256:bfd1d0ae7e292105f29d7deaa9d8f2916ed8553ab9d5f39ec65bcf5deadff3f9", + "sha256:c62ca0a38958f541a73cf86acdab020c2091631c137bd359c4f5bddde7b75fd4", + "sha256:c709d8bda72cf4cd348ccec2a4881f2c5848fd72903c185f363d361b2737f773", + "sha256:c968a6aa7e0b56ecbd28531ddf439c2ec103610d3e2bf3b75b813304f8cb7723", + "sha256:df785d8cb80539d0b55fd47183264b7002077859028dfe3070cf6359bf8b2d9c", + "sha256:f406628ca51e0ae90ae76ea8398677a921b36f0bd71aab2099dfed08abd0322f", + "sha256:f46087bbd95ebae244a0eda01a618aff11ec7a069b15a3ef8f6b520db523dcf1", + "sha256:f8019c5279eb32360ca03e9fac40a12667715546eed5c5eb59eb381f2f501260", + "sha256:fc5f4d209733750afd2714e9109816a29500718b32dd9a5db01c0cb3a019b96a" + ], + "version": "==4.5.3" }, "docutils": { "hashes": [ @@ -307,53 +309,60 @@ ], "version": "==1.1.0" }, + "importlib-metadata": { + "hashes": [ + "sha256:6dfd58dfe281e8d240937776065dd3624ad5469c835248219bd16cf2e12dbeb7", + "sha256:cb6ee23b46173539939964df59d3d72c3e0c1b5d54b84f1d8a7e912fe43612db" + ], + "version": "==0.18" + }, "jinja2": { "hashes": [ - "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd", - "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4" + "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", + "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" ], - "version": "==2.10" + "version": "==2.10.1" }, "markupsafe": { "hashes": [ - "sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432", - "sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b", - "sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9", - "sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af", - "sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834", - "sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd", - "sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d", - "sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7", - "sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b", - "sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3", - "sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c", - "sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2", - "sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7", - "sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36", - "sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1", - "sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e", - "sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1", - "sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c", - "sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856", - "sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550", - "sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492", - "sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672", - "sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401", - "sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6", - "sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6", - "sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c", - "sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd", - "sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1" - ], - "version": "==1.1.0" + "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", + "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", + "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", + "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", + "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", + "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", + "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", + "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", + "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", + "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", + "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", + "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", + "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", + "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", + "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + ], + "version": "==1.1.1" }, "more-itertools": { "hashes": [ - "sha256:0125e8f60e9e031347105eb1682cef932f5e97d7b9a1a28d9bf00c22a5daef40", - "sha256:590044e3942351a1bdb1de960b739ff4ce277960f2425ad4509446dbace8d9d1" + "sha256:2112d2ca570bb7c3e53ea1a35cd5df42bb0fd10c45f0fb97178679c3c03d64c7", + "sha256:c3e4748ba1aad8dba30a4886b0b1a2004f9a863837b8654e7059eebf727afa5a" ], "markers": "python_version > '2.7'", - "version": "==6.0.0" + "version": "==7.0.0" }, "packaging": { "hashes": [ @@ -364,71 +373,71 @@ }, "pluggy": { "hashes": [ - "sha256:8ddc32f03971bfdf900a81961a48ccf2fb677cf7715108f85295c67405798616", - "sha256:980710797ff6a041e9a73a5787804f848996ecaa6f8a1b1e08224a5894f2074a" + "sha256:0825a152ac059776623854c1543d65a4ad408eb3d33ee114dff91e57ec6ae6fc", + "sha256:b9817417e95936bf75d85d3f8767f7df6cdde751fc40aed3bb3074cbcb77757c" ], - "version": "==0.8.1" + "version": "==0.12.0" }, "py": { "hashes": [ - "sha256:bf92637198836372b520efcba9e020c330123be8ce527e535d185ed4b6f45694", - "sha256:e76826342cefe3c3d5f7e8ee4316b80d1dd8a300781612ddbc765c17ba25a6c6" + "sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", + "sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53" ], - "version": "==1.7.0" + "version": "==1.8.0" }, "pygments": { "hashes": [ - "sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a", - "sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d" + "sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127", + "sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297" ], - "version": "==2.3.1" + "version": "==2.4.2" }, "pyparsing": { "hashes": [ - "sha256:66c9268862641abcac4a96ba74506e594c884e3f57690a696d21ad8210ed667a", - "sha256:f6c5ef0d7480ad048c054c37632c67fca55299990fff127850181659eea33fc3" + "sha256:1873c03321fc118f4e9746baf201ff990ceb915f433f23b395f5580d1840cb2a", + "sha256:9b6323ef4ab914af344ba97510e966d64ba91055d6b9afa6b30799340e89cc03" ], - "version": "==2.3.1" + "version": "==2.4.0" }, "pytest": { "hashes": [ - "sha256:067a1d4bf827ffdd56ad21bd46674703fce77c5957f6c1eef731f6146bfcef1c", - "sha256:9687049d53695ad45cf5fdc7bbd51f0c49f1ea3ecfc4b7f3fde7501b541f17f4" + "sha256:4a784f1d4f2ef198fe9b7aef793e9fa1a3b2f84e822d9b3a64a181293a572d45", + "sha256:926855726d8ae8371803f7b2e6ec0a69953d9c6311fa7c3b6c1b929ff92d27da" ], "index": "pypi", - "version": "==4.3.0" + "version": "==4.6.3" }, "pytest-cov": { "hashes": [ - "sha256:0ab664b25c6aa9716cbf203b17ddb301932383046082c081b9848a0edf5add33", - "sha256:230ef817450ab0699c6cc3c9c8f7a829c34674456f2ed8df1fe1d39780f7c87f" + "sha256:2b097cde81a302e1047331b48cadacf23577e431b61e9c6f49a1170bbe3d3da6", + "sha256:e00ea4fdde970725482f1f35630d12f074e121a23801aabf2ae154ec6bdd343a" ], "index": "pypi", - "version": "==2.6.1" + "version": "==2.7.1" }, "pytz": { "hashes": [ - "sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9", - "sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c" + "sha256:303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda", + "sha256:d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141" ], - "version": "==2018.9" + "version": "==2019.1" }, "pyyaml": { "hashes": [ - "sha256:3d7da3009c0f3e783b2c873687652d83b1bbfd5c88e9813fb7e5b03c0dd3108b", - "sha256:3ef3092145e9b70e3ddd2c7ad59bdd0252a94dfe3949721633e41344de00a6bf", - "sha256:40c71b8e076d0550b2e6380bada1f1cd1017b882f7e16f09a65be98e017f211a", - "sha256:558dd60b890ba8fd982e05941927a3911dc409a63dcb8b634feaa0cda69330d3", - "sha256:a7c28b45d9f99102fa092bb213aa12e0aaf9a6a1f5e395d36166639c1f96c3a1", - "sha256:aa7dd4a6a427aed7df6fb7f08a580d68d9b118d90310374716ae90b710280af1", - "sha256:bc558586e6045763782014934bfaf39d48b8ae85a2713117d16c39864085c613", - "sha256:d46d7982b62e0729ad0175a9bc7e10a566fc07b224d2c79fafb5e032727eaa04", - "sha256:d5eef459e30b09f5a098b9cea68bebfeb268697f78d647bd255a085371ac7f3f", - "sha256:e01d3203230e1786cd91ccfdc8f8454c8069c91bee3962ad93b87a4b2860f537", - "sha256:e170a9e6fcfd19021dd29845af83bb79236068bf5fd4df3327c1be18182b2531" + "sha256:57acc1d8533cbe51f6662a55434f0dbecfa2b9eaf115bede8f6fd00115a0c0d3", + "sha256:588c94b3d16b76cfed8e0be54932e5729cc185caffaa5a451e7ad2f7ed8b4043", + "sha256:68c8dd247f29f9a0d09375c9c6b8fdc64b60810ebf07ba4cdd64ceee3a58c7b7", + "sha256:70d9818f1c9cd5c48bb87804f2efc8692f1023dac7f1a1a5c61d454043c1d265", + "sha256:86a93cccd50f8c125286e637328ff4eef108400dd7089b46a7be3445eecfa391", + "sha256:a0f329125a926876f647c9fa0ef32801587a12328b4a3c741270464e3e4fa778", + "sha256:a3c252ab0fa1bb0d5a3f6449a4826732f3eb6c0270925548cac342bc9b22c225", + "sha256:b4bb4d3f5e232425e25dda21c070ce05168a786ac9eda43768ab7f3ac2770955", + "sha256:cd0618c5ba5bda5f4039b9398bb7fb6a317bb8298218c3de25c47c4740e4b95e", + "sha256:ceacb9e5f8474dcf45b940578591c7f3d960e82f926c707788a570b51ba59190", + "sha256:fe6a88094b64132c4bb3b631412e90032e8cfe9745a58370462240b8cb7553cd" ], "index": "pypi", - "version": "==3.13" + "version": "==5.1.1" }, "recommonmark": { "hashes": [ @@ -440,10 +449,10 @@ }, "requests": { "hashes": [ - "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e", - "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b" + "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", + "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" ], - "version": "==2.21.0" + "version": "==2.22.0" }, "six": { "hashes": [ @@ -461,11 +470,18 @@ }, "sphinx": { "hashes": [ - "sha256:b53904fa7cb4b06a39409a492b949193a1b68cc7241a1a8ce9974f86f0d24287", - "sha256:c1c00fc4f6e8b101a0d037065043460dffc2d507257f2f11acaed71fd2b0c83c" + "sha256:22538e1bbe62b407cf5a8aabe1bb15848aa66bb79559f42f5202bbce6b757a69", + "sha256:f9a79e746b87921cabc3baa375199c6076d1270cee53915dbd24fdbeaaacc427" ], "index": "pypi", - "version": "==1.8.4" + "version": "==2.1.2" + }, + "sphinxcontrib-applehelp": { + "hashes": [ + "sha256:edaa0ab2b2bc74403149cb0209d6775c96de797dfd5b5e2a71981309efab3897", + "sha256:fb8dee85af95e5c30c91f10e7eb3c8967308518e0f7488a2828ef7bc191d0d5d" + ], + "version": "==1.0.1" }, "sphinxcontrib-autoprogram": { "hashes": [ @@ -475,27 +491,69 @@ "index": "pypi", "version": "==0.1.5" }, - "sphinxcontrib-websupport": { + "sphinxcontrib-devhelp": { "hashes": [ - "sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd", - "sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9" + "sha256:6c64b077937330a9128a4da74586e8c2130262f014689b4b89e2d08ee7294a34", + "sha256:9512ecb00a2b0821a146736b39f7aeb90759834b07e81e8cc23a9c70bacb9981" ], - "version": "==1.1.0" + "version": "==1.0.1" + }, + "sphinxcontrib-htmlhelp": { + "hashes": [ + "sha256:4670f99f8951bd78cd4ad2ab962f798f5618b17675c35c5ac3b2132a14ea8422", + "sha256:d4fd39a65a625c9df86d7fa8a2d9f3cd8299a3a4b15db63b50aac9e161d8eff7" + ], + "version": "==1.0.2" + }, + "sphinxcontrib-jsmath": { + "hashes": [ + "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", + "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8" + ], + "version": "==1.0.1" + }, + "sphinxcontrib-qthelp": { + "hashes": [ + "sha256:513049b93031beb1f57d4daea74068a4feb77aa5630f856fcff2e50de14e9a20", + "sha256:79465ce11ae5694ff165becda529a600c754f4bc459778778c7017374d4d406f" + ], + "version": "==1.0.2" + }, + "sphinxcontrib-serializinghtml": { + "hashes": [ + "sha256:c0efb33f8052c04fd7a26c0a07f1678e8512e0faec19f4aa8f2473a8b81d5227", + "sha256:db6615af393650bf1151a6cd39120c29abaf93cc60db8c48eb2dddbfdc3a9768" + ], + "version": "==1.1.3" }, "urllib3": { "hashes": [ - "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39", - "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22" + "sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1", + "sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232" ], - "version": "==1.24.1" + "version": "==1.25.3" + }, + "wcwidth": { + "hashes": [ + "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", + "sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c" + ], + "version": "==0.1.7" }, "wheel": { "hashes": [ - "sha256:66a8fd76f28977bb664b098372daef2b27f60dc4d1688cfab7b37a09448f0e9d", - "sha256:8eb4a788b3aec8abf5ff68d4165441bc57420c9f64ca5f471f58c3969fe08668" + "sha256:5e79117472686ac0c4aef5bad5172ea73a1c2d1646b808c35926bd26bdfb0c08", + "sha256:62fcfa03d45b5b722539ccbc07b190e4bfff4bb9e3a4d470dd9f6a0981002565" ], "index": "pypi", - "version": "==0.33.1" + "version": "==0.33.4" + }, + "zipp": { + "hashes": [ + "sha256:8c1019c6aad13642199fbe458275ad6a84907634cc9f0989877ccc4a2840139d", + "sha256:ca943a7e809cc12257001ccfb99e3563da9af99d52f261725e96dfe0f9275bc3" + ], + "version": "==0.5.1" } } } From 578fca9273805653b92edd72755c46702662c0fa Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 23 Jun 2019 05:45:25 +0200 Subject: [PATCH 36/51] Add test for using py2 with pipfile --- .../py2-with-server-and-kernel-req/Pipfile | 13 ++++ .../Pipfile.lock | 59 +++++++++++++++++++ .../py2-with-server-and-kernel-req/README.rst | 7 +++ .../requirements3.txt | 3 + .../py2-with-server-and-kernel-req/verify | 57 ++++++++++++++++++ 5 files changed, 139 insertions(+) create mode 100644 tests/pipfile/py2-with-server-and-kernel-req/Pipfile create mode 100644 tests/pipfile/py2-with-server-and-kernel-req/Pipfile.lock create mode 100644 tests/pipfile/py2-with-server-and-kernel-req/README.rst create mode 100644 tests/pipfile/py2-with-server-and-kernel-req/requirements3.txt create mode 100755 tests/pipfile/py2-with-server-and-kernel-req/verify diff --git a/tests/pipfile/py2-with-server-and-kernel-req/Pipfile b/tests/pipfile/py2-with-server-and-kernel-req/Pipfile new file mode 100644 index 000000000..d2e8ffbcc --- /dev/null +++ b/tests/pipfile/py2-with-server-and-kernel-req/Pipfile @@ -0,0 +1,13 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +numpy = "*" + +[dev-packages] +parse = "*" + +[requires] +python_version = "2.7" diff --git a/tests/pipfile/py2-with-server-and-kernel-req/Pipfile.lock b/tests/pipfile/py2-with-server-and-kernel-req/Pipfile.lock new file mode 100644 index 000000000..baf6cabfc --- /dev/null +++ b/tests/pipfile/py2-with-server-and-kernel-req/Pipfile.lock @@ -0,0 +1,59 @@ +{ + "_meta": { + "hash": { + "sha256": "77f8627bb6f7914babc301ec0de3e35d7382677167cab27e1a00cc30b37f4e5f" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "2.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.python.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "numpy": { + "hashes": [ + "sha256:0778076e764e146d3078b17c24c4d89e0ecd4ac5401beff8e1c87879043a0633", + "sha256:141c7102f20abe6cf0d54c4ced8d565b86df4d3077ba2343b61a6db996cefec7", + "sha256:14270a1ee8917d11e7753fb54fc7ffd1934f4d529235beec0b275e2ccf00333b", + "sha256:27e11c7a8ec9d5838bc59f809bfa86efc8a4fd02e58960fa9c49d998e14332d5", + "sha256:2a04dda79606f3d2f760384c38ccd3d5b9bb79d4c8126b67aff5eb09a253763e", + "sha256:3c26010c1b51e1224a3ca6b8df807de6e95128b0908c7e34f190e7775455b0ca", + "sha256:52c40f1a4262c896420c6ea1c6fda62cf67070e3947e3307f5562bd783a90336", + "sha256:6e4f8d9e8aa79321657079b9ac03f3cf3fd067bf31c1cca4f56d49543f4356a5", + "sha256:7242be12a58fec245ee9734e625964b97cf7e3f2f7d016603f9e56660ce479c7", + "sha256:7dc253b542bfd4b4eb88d9dbae4ca079e7bf2e2afd819ee18891a43db66c60c7", + "sha256:94f5bd885f67bbb25c82d80184abbf7ce4f6c3c3a41fbaa4182f034bba803e69", + "sha256:a89e188daa119ffa0d03ce5123dee3f8ffd5115c896c2a9d4f0dbb3d8b95bfa3", + "sha256:ad3399da9b0ca36e2f24de72f67ab2854a62e623274607e37e0ce5f5d5fa9166", + "sha256:b0348be89275fd1d4c44ffa39530c41a21062f52299b1e3ee7d1c61f060044b8", + "sha256:b5554368e4ede1856121b0dfa35ce71768102e4aa55e526cb8de7f374ff78722", + "sha256:cbddc56b2502d3f87fda4f98d948eb5b11f36ff3902e17cb6cc44727f2200525", + "sha256:d79f18f41751725c56eceab2a886f021d70fd70a6188fd386e29a045945ffc10", + "sha256:dc2ca26a19ab32dc475dbad9dfe723d3a64c835f4c23f625c2b6566ca32b9f29", + "sha256:dd9bcd4f294eb0633bb33d1a74febdd2b9018b8b8ed325f861fffcd2c7660bb8", + "sha256:e8baab1bc7c9152715844f1faca6744f2416929de10d7639ed49555a85549f52", + "sha256:ec31fe12668af687b99acf1567399632a7c47b0e17cfb9ae47c098644ef36797", + "sha256:f12b4f7e2d8f9da3141564e6737d79016fe5336cc92de6814eba579744f65b0a", + "sha256:f58ac38d5ca045a377b3b377c84df8175ab992c970a53332fa8ac2373df44ff7" + ], + "index": "pypi", + "version": "==1.16.4" + } + }, + "develop": { + "parse": { + "hashes": [ + "sha256:1b68657434d371e5156048ca4a0c5aea5afc6ca59a2fea4dd1a575354f617142", + "sha256:7cc123e89f39b7374bd6fd1cbe4e1a6616a9ce328163fbe9caef474d6aba380c" + ], + "index": "pypi", + "version": "==1.12.0" + } + } +} diff --git a/tests/pipfile/py2-with-server-and-kernel-req/README.rst b/tests/pipfile/py2-with-server-and-kernel-req/README.rst new file mode 100644 index 000000000..9c2ed73f3 --- /dev/null +++ b/tests/pipfile/py2-with-server-and-kernel-req/README.rst @@ -0,0 +1,7 @@ +Python 2 - Pipfile and requirements3.txt +---------------------------------------- + +- We should get Python 2 setup for the Kernel + - with 'numpy' installed installed through Pipfile as listed in 'packages' + - with 'parse' installed installed through Pipfile as listed in 'dev-packages' +- We should get Python 3 setup for the Notebook Server, with 'nbgitpuller' installed through requirements3.txt diff --git a/tests/pipfile/py2-with-server-and-kernel-req/requirements3.txt b/tests/pipfile/py2-with-server-and-kernel-req/requirements3.txt new file mode 100644 index 000000000..87e197c3a --- /dev/null +++ b/tests/pipfile/py2-with-server-and-kernel-req/requirements3.txt @@ -0,0 +1,3 @@ +# install this in the environment in which the notebook server +# is running nbgitpuller does not work with Python 2 +nbgitpuller==0.6.1 diff --git a/tests/pipfile/py2-with-server-and-kernel-req/verify b/tests/pipfile/py2-with-server-and-kernel-req/verify new file mode 100755 index 000000000..a821b6ca9 --- /dev/null +++ b/tests/pipfile/py2-with-server-and-kernel-req/verify @@ -0,0 +1,57 @@ +#!/usr/bin/env python2 +import os +import sys + + +# Verify - kernel's Python: use Python 2 +print(sys.version_info) +assert sys.version_info[:2] == (2, 7) + + +# Verify - notebook server's Python: 'numpy' isn't installed +status_code = os.system("python3 -c 'import numpy'") +if status_code == 0: + raise Exception( + "notebook server's Python: 'numpy' IS installed" + ) + +# Verify - notebook server's Python: 'parse' isn't installed +status_code = os.system("python3 -c 'import parse'") +if status_code == 0: + raise Exception( + "notebook server's Python: 'parse' IS installed" + ) + +# Verify - notebook server's Python: 'nbgitpuller' is installed +status_code = os.system("python3 -c 'import nbgitpuller'") +if not status_code == 0: + raise Exception( + "notebook server's Python: 'nbgitpuller' ISN'T installed" + ) + + +# Verify - kernel's Python: 'nbgitpuller' isn't installed +try: + import nbgitpuller +except ImportError: + pass +else: + raise Exception( + "kernel's Python: 'nbgitpuller' IS installed" + ) + +# Verify - kernel's Python: 'numpy' is installed +try: + import numpy +except ImportError: + raise Exception( + "kernel's Python: 'numpy' ISN'T installed --- We probably setup a virtual env through pipenv but failed to enter it." + ) + +# Verify - kernel's Python: 'parse' is installed +try: + import parse +except ImportError: + raise Exception( + "kernel's Python: 'parse' ISN'T installed" + ) From fe2d9b9e0d92ddad39efd995931b119fe1e04be1 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 23 Jun 2019 06:29:15 +0200 Subject: [PATCH 37/51] Pipfile support for Python 2 as well --- repo2docker/buildpacks/pipfile/__init__.py | 62 +++++++++++++--------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 4db27481f..6780fead2 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -78,48 +78,62 @@ def get_assemble_scripts(self): # environment. assemble_scripts = super().get_assemble_scripts() + if self.py2: - # using python 2 kernel, - # requirements3.txt allows installation in the notebook server env + # using Python 2 as a kernel, but Python 3 for the notebook server + + # requirements3.txt allows for packages to be installed to the + # notebook servers Python environment nb_requirements_file = self.binder_path("requirements3.txt") if os.path.exists(nb_requirements_file): assemble_scripts.append( ( "${NB_USER}", - # want the $NB_PYHTON_PREFIX environment variable, not for - # Python's string formatting to try and replace this - '${{NB_PYTHON_PREFIX}}/bin/pip install --no-cache-dir -r "{}"'.format( + 'pip install --no-cache-dir -r "{}"'.format( nb_requirements_file ), ) ) - # install Pipfile.lock or fallback to installing Pipfile - pipenv = "${KERNEL_PYTHON_PREFIX}/bin/pipenv" - python = "${KERNEL_PYTHON_PREFIX}/bin/python" + pipfile = self.binder_path("Pipfile") pipfile_lock = self.binder_path("Pipfile.lock") - # let pipenv work relative to the dir that has the Pipfile, it is - # important as they can contain relative references such as: - # my_package = {path=".", editable=true} + + # A Pipfile(.lock) can contain relative references, so we need to be + # mindful about where we invoke pipenv as that will dictate where .` + # referes to. + # [packages] + # my_package_example = {path=".", editable=true} working_directory = self.binder_dir or "." + + # install pipenv to install dependencies within Pipfile.lock or Pipfile assemble_scripts.append(("${NB_USER}", "pip install pipenv")) - # if Pipfile.lock isn't found, Pipfile is used to create one - if not os.path.exists(pipfile_lock): - assemble_scripts.append( - ( - "${NB_USER}", - "(cd {} && {} lock --python {})".format( - working_directory, pipenv, python - ), - ) - ) - # install Pipfile.lock + + # NOTES: + # - Without prioritizing the PATH to KERNEL_PYTHON_PREFIX over + # NB_SERVER_PYTHON_PREFIX, 'pipenv' draws the wrong conclusion about + # what Python environment is the '--system' environment. + # - The --system flag allows us to avoid wrapping ourself in yet + # another virtual environment that we also then need to enter. + # This flag is only available within the `install` subcommand of + # `pipenv`. + # - The `--skip-lock` will not run the `lock` subcommand again as + # part of the `install` command. This allows a preexisting .lock + # file to remain intact and be used directly. This allows us to + # prioritize usage of .lock files that makes sense for + # reproducibility. + # - The `--ignore-pipfile` requires a .lock file to be around as if + # there isn't, no other option remain. assemble_scripts.append( ( "${NB_USER}", - "(cd {} && {} install --ignore-pipfile --deploy --system --dev --python {})".format( - working_directory, pipenv, python + """(\\ + cd {working_directory} && \\ + PATH="${{KERNEL_PYTHON_PREFIX}}/bin:$PATH" \\ + pipenv install {install_option} --system --dev \\ + )""".format( + working_directory=working_directory, + install_option="--skip-lock" if not os.path.exists(pipfile_lock) else "--ignore-pipfile", ), ) ) From e5160e4b3ff2782b8c517c2f0c21da5681ba788c Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 23 Jun 2019 06:38:31 +0200 Subject: [PATCH 38/51] Autoformatting --- repo2docker/buildpacks/pipfile/__init__.py | 8 ++++---- .../py2-with-server-and-kernel-req/verify | 20 +++++-------------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 6780fead2..2ff93021e 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -78,10 +78,9 @@ def get_assemble_scripts(self): # environment. assemble_scripts = super().get_assemble_scripts() - if self.py2: # using Python 2 as a kernel, but Python 3 for the notebook server - + # requirements3.txt allows for packages to be installed to the # notebook servers Python environment nb_requirements_file = self.binder_path("requirements3.txt") @@ -95,7 +94,6 @@ def get_assemble_scripts(self): ) ) - pipfile = self.binder_path("Pipfile") pipfile_lock = self.binder_path("Pipfile.lock") @@ -133,7 +131,9 @@ def get_assemble_scripts(self): pipenv install {install_option} --system --dev \\ )""".format( working_directory=working_directory, - install_option="--skip-lock" if not os.path.exists(pipfile_lock) else "--ignore-pipfile", + install_option="--skip-lock" + if not os.path.exists(pipfile_lock) + else "--ignore-pipfile", ), ) ) diff --git a/tests/pipfile/py2-with-server-and-kernel-req/verify b/tests/pipfile/py2-with-server-and-kernel-req/verify index a821b6ca9..7246be615 100755 --- a/tests/pipfile/py2-with-server-and-kernel-req/verify +++ b/tests/pipfile/py2-with-server-and-kernel-req/verify @@ -11,23 +11,17 @@ assert sys.version_info[:2] == (2, 7) # Verify - notebook server's Python: 'numpy' isn't installed status_code = os.system("python3 -c 'import numpy'") if status_code == 0: - raise Exception( - "notebook server's Python: 'numpy' IS installed" - ) + raise Exception("notebook server's Python: 'numpy' IS installed") # Verify - notebook server's Python: 'parse' isn't installed status_code = os.system("python3 -c 'import parse'") if status_code == 0: - raise Exception( - "notebook server's Python: 'parse' IS installed" - ) + raise Exception("notebook server's Python: 'parse' IS installed") # Verify - notebook server's Python: 'nbgitpuller' is installed status_code = os.system("python3 -c 'import nbgitpuller'") if not status_code == 0: - raise Exception( - "notebook server's Python: 'nbgitpuller' ISN'T installed" - ) + raise Exception("notebook server's Python: 'nbgitpuller' ISN'T installed") # Verify - kernel's Python: 'nbgitpuller' isn't installed @@ -36,9 +30,7 @@ try: except ImportError: pass else: - raise Exception( - "kernel's Python: 'nbgitpuller' IS installed" - ) + raise Exception("kernel's Python: 'nbgitpuller' IS installed") # Verify - kernel's Python: 'numpy' is installed try: @@ -52,6 +44,4 @@ except ImportError: try: import parse except ImportError: - raise Exception( - "kernel's Python: 'parse' ISN'T installed" - ) + raise Exception("kernel's Python: 'parse' ISN'T installed") From 61a00f7929c92176f6044fbea2bffbeb889a6131 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Mon, 24 Jun 2019 07:35:31 +0200 Subject: [PATCH 39/51] Improve code readability --- repo2docker/buildpacks/pipfile/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 2ff93021e..a17474462 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -131,9 +131,9 @@ def get_assemble_scripts(self): pipenv install {install_option} --system --dev \\ )""".format( working_directory=working_directory, - install_option="--skip-lock" - if not os.path.exists(pipfile_lock) - else "--ignore-pipfile", + install_option="--ignore-pipfile" + if os.path.exists(pipfile_lock) + else "--skip-lock", ), ) ) From 6ec9a15037a1801285014a05f5929519b008cf06 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Mon, 24 Jun 2019 08:19:01 +0200 Subject: [PATCH 40/51] Iterate on Pipfile documentation --- docs/source/config_files.rst | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/docs/source/config_files.rst b/docs/source/config_files.rst index 65af2d80b..5c1211eb5 100644 --- a/docs/source/config_files.rst +++ b/docs/source/config_files.rst @@ -59,17 +59,16 @@ though ``repo2docker`` support is best with Python 3.7, 3.6, 3.5 and 2.7. ``Pipfile`` and/or ``Pipfile.lock`` - Install a Python environment ================================================================== -``Pipfile`` and/or ``Pipfile.lock`` specifies a list of Python packages that -should be installed in your environment. ``pipenv install --dev`` will be run to -install the dependencies where the existence of a ``Pipfile.lock`` will make the -``Pipfile`` be ignored. - -.. note:: - - `pipenv `_ and `virtualenv - `_ and associated ``requirements.txt`` - files are both managed by the Python Packaging Authority PyPA, where pipenv - and ``Pipfile`` and ``Pipfile.lock`` seem to be the modern solution. +`pipenv `_ allows you to manage a virtual +environment Python dependencies. When using ``pipenv``, you end up with +``Pipfile`` and ``Pipfile.lock`` files. The lock file contains explicit details +about the packages that has been installed that met the criteria within the +``Pipfile``. + +If both ``Pipfile`` and ``Pipfile.lock`` are found by repo2docker, the former +will be ignored in favor of the lock file. Also note that these files +distinguish packages and development packages and that repo2docker will install +both kinds. .. _requirements.txt: From 1bc0a6b206482fa01ec530662d5034b9c889ab01 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Mon, 24 Jun 2019 08:34:22 +0200 Subject: [PATCH 41/51] Pipfile changelog entry --- docs/source/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 241d710b2..963fbe324 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -12,6 +12,8 @@ New features ------------ - Increased minimum Python version supported for running `repo2docker` itself to Python 3.5 in :pr:`684` by :user:`betatim`. +- Support for `Pipfile` and `Pipfile.lock` implemented in :pr:`649` by + :user:`consideratio`. API changes ----------- From efff66b81ba6f22815c6087c250d2efe162d712e Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 25 Jun 2019 09:17:04 +0200 Subject: [PATCH 42/51] Fix typo Co-Authored-By: Tim Head --- tests/pipfile/py2-with-server-and-kernel-req/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pipfile/py2-with-server-and-kernel-req/README.rst b/tests/pipfile/py2-with-server-and-kernel-req/README.rst index 9c2ed73f3..80bbd6638 100644 --- a/tests/pipfile/py2-with-server-and-kernel-req/README.rst +++ b/tests/pipfile/py2-with-server-and-kernel-req/README.rst @@ -2,6 +2,6 @@ Python 2 - Pipfile and requirements3.txt ---------------------------------------- - We should get Python 2 setup for the Kernel - - with 'numpy' installed installed through Pipfile as listed in 'packages' + - with 'numpy' installed through Pipfile as listed in 'packages' - with 'parse' installed installed through Pipfile as listed in 'dev-packages' - We should get Python 3 setup for the Notebook Server, with 'nbgitpuller' installed through requirements3.txt From 0ff737df1be043c2251802d84c24de10564c91af Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 25 Jun 2019 09:17:30 +0200 Subject: [PATCH 43/51] Fix typo Co-Authored-By: Tim Head --- tests/pipfile/py2-with-server-and-kernel-req/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pipfile/py2-with-server-and-kernel-req/README.rst b/tests/pipfile/py2-with-server-and-kernel-req/README.rst index 80bbd6638..597ad82cf 100644 --- a/tests/pipfile/py2-with-server-and-kernel-req/README.rst +++ b/tests/pipfile/py2-with-server-and-kernel-req/README.rst @@ -3,5 +3,5 @@ Python 2 - Pipfile and requirements3.txt - We should get Python 2 setup for the Kernel - with 'numpy' installed through Pipfile as listed in 'packages' - - with 'parse' installed installed through Pipfile as listed in 'dev-packages' + - with 'parse' installed through Pipfile as listed in 'dev-packages' - We should get Python 3 setup for the Notebook Server, with 'nbgitpuller' installed through requirements3.txt From e5d2d4dd85f82620f59b3dcc25196016aefa05f1 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 25 Jun 2019 16:29:18 +0200 Subject: [PATCH 44/51] Make the python environment explicit during pip install --- repo2docker/buildpacks/pipfile/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index a17474462..82792fa8d 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -88,7 +88,7 @@ def get_assemble_scripts(self): assemble_scripts.append( ( "${NB_USER}", - 'pip install --no-cache-dir -r "{}"'.format( + '${{NB_PYTHON_PREFIX}}/pip install --no-cache-dir -r "{}"'.format( nb_requirements_file ), ) From 8eae91bc67e2f7db260702f9d32cb7f016a2d7bc Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 25 Jun 2019 16:32:47 +0200 Subject: [PATCH 45/51] Install pipenv in the kernel environ --- repo2docker/buildpacks/pipfile/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 82792fa8d..a6997e108 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -105,7 +105,7 @@ def get_assemble_scripts(self): working_directory = self.binder_dir or "." # install pipenv to install dependencies within Pipfile.lock or Pipfile - assemble_scripts.append(("${NB_USER}", "pip install pipenv")) + assemble_scripts.append(("${NB_USER}", "${KERNEL_PYTHON_PREFIX}/pip install pipenv")) # NOTES: # - Without prioritizing the PATH to KERNEL_PYTHON_PREFIX over From 09558802d16c46727dad8c384d56ba2f9b19645f Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 25 Jun 2019 16:34:15 +0200 Subject: [PATCH 46/51] Formatting opinion The '//' will render to '/' in the Dockerfile that allows the RUN command to continue on a new line. I initially added a '//' within a python string on a blank line in order to format things within the Python file to look potentially nicer, but this is of little importance and I have now removed it again. --- repo2docker/buildpacks/pipfile/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index a6997e108..5d6c4d365 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -125,8 +125,7 @@ def get_assemble_scripts(self): assemble_scripts.append( ( "${NB_USER}", - """(\\ - cd {working_directory} && \\ + """(cd {working_directory} && \\ PATH="${{KERNEL_PYTHON_PREFIX}}/bin:$PATH" \\ pipenv install {install_option} --system --dev \\ )""".format( From b4249db4ad8aff470238c208c443c9ec10a107a9 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 25 Jun 2019 16:39:48 +0200 Subject: [PATCH 47/51] Pin pipenv utilized to version: 2018.11.26 --- repo2docker/buildpacks/pipfile/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 5d6c4d365..7b9e33866 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -105,7 +105,7 @@ def get_assemble_scripts(self): working_directory = self.binder_dir or "." # install pipenv to install dependencies within Pipfile.lock or Pipfile - assemble_scripts.append(("${NB_USER}", "${KERNEL_PYTHON_PREFIX}/pip install pipenv")) + assemble_scripts.append(("${NB_USER}", "${KERNEL_PYTHON_PREFIX}/pip install pipenv=2018.11.26")) # NOTES: # - Without prioritizing the PATH to KERNEL_PYTHON_PREFIX over From 6d508ac5e264646c733958b679a460e069b9c83b Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 25 Jun 2019 16:57:11 +0200 Subject: [PATCH 48/51] Autoformatting --- repo2docker/buildpacks/pipfile/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 7b9e33866..fc922c27e 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -105,7 +105,9 @@ def get_assemble_scripts(self): working_directory = self.binder_dir or "." # install pipenv to install dependencies within Pipfile.lock or Pipfile - assemble_scripts.append(("${NB_USER}", "${KERNEL_PYTHON_PREFIX}/pip install pipenv=2018.11.26")) + assemble_scripts.append( + ("${NB_USER}", "${KERNEL_PYTHON_PREFIX}/pip install pipenv=2018.11.26") + ) # NOTES: # - Without prioritizing the PATH to KERNEL_PYTHON_PREFIX over From 7dbee81af6802218faa88b49613b0038b0027e37 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 25 Jun 2019 17:18:10 +0200 Subject: [PATCH 49/51] Syntax typo fix --- repo2docker/buildpacks/pipfile/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index fc922c27e..9eb8bc1d1 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -106,7 +106,7 @@ def get_assemble_scripts(self): # install pipenv to install dependencies within Pipfile.lock or Pipfile assemble_scripts.append( - ("${NB_USER}", "${KERNEL_PYTHON_PREFIX}/pip install pipenv=2018.11.26") + ("${NB_USER}", "${KERNEL_PYTHON_PREFIX}/pip install pipenv==2018.11.26") ) # NOTES: From 397cb939bc1da46ba16ed20da9f04dce6e21eac8 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 25 Jun 2019 19:02:17 +0200 Subject: [PATCH 50/51] Correct path typo and add note about '//' --- repo2docker/buildpacks/pipfile/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 9eb8bc1d1..8d0b7c45d 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -88,7 +88,7 @@ def get_assemble_scripts(self): assemble_scripts.append( ( "${NB_USER}", - '${{NB_PYTHON_PREFIX}}/pip install --no-cache-dir -r "{}"'.format( + '${{NB_PYTHON_PREFIX}}/bin/pip install --no-cache-dir -r "{}"'.format( nb_requirements_file ), ) @@ -106,7 +106,7 @@ def get_assemble_scripts(self): # install pipenv to install dependencies within Pipfile.lock or Pipfile assemble_scripts.append( - ("${NB_USER}", "${KERNEL_PYTHON_PREFIX}/pip install pipenv==2018.11.26") + ("${NB_USER}", "${KERNEL_PYTHON_PREFIX}/bin/pip install pipenv==2018.11.26") ) # NOTES: From ec7f20e1a86796590489f88e148c9f1fdb785420 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 25 Jun 2019 21:21:46 +0200 Subject: [PATCH 51/51] Add inline comment about '\' --- repo2docker/buildpacks/pipfile/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/repo2docker/buildpacks/pipfile/__init__.py b/repo2docker/buildpacks/pipfile/__init__.py index 8d0b7c45d..e91e63aa5 100644 --- a/repo2docker/buildpacks/pipfile/__init__.py +++ b/repo2docker/buildpacks/pipfile/__init__.py @@ -124,6 +124,10 @@ def get_assemble_scripts(self): # reproducibility. # - The `--ignore-pipfile` requires a .lock file to be around as if # there isn't, no other option remain. + # - The '\\' will is within a Python """ """ string render to a '\'. A + # Dockerfile where this later is read within, will thanks to the '\' + # let the RUN command continue on the next line. So it is only added + # to avoid forcing us to write it all on a single line. assemble_scripts.append( ( "${NB_USER}",