From f7ee0764e3161211df5698d391e315ee1d80a259 Mon Sep 17 00:00:00 2001 From: Jacob Hayes Date: Wed, 11 Jul 2018 13:24:41 -0500 Subject: [PATCH 1/6] Add pytest default norecursedirs --- pytest.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index 92e72fd59d..80c3e3a399 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,3 +1,4 @@ [pytest] addopts = -n auto -norecursedirs = vendor patched +; Add vendor and patched in addition to the default list of ignored dirs +norecursedirs = .* build dist CVS _darcs {arch} *.egg vendor patched From dd4b4be175757cd9de45650b9f9bc493cdf7f221 Mon Sep 17 00:00:00 2001 From: Jacob Hayes Date: Wed, 11 Jul 2018 13:25:02 -0500 Subject: [PATCH 2/6] Remove explicit sets of PYPI_VENDOR_DIR and let integration conftest do its thing --- .env | 1 - run-tests.bat | 2 +- run-tests.sh | 3 --- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.env b/.env index 189ddda7ea..d77e8f12a7 100644 --- a/.env +++ b/.env @@ -1,2 +1 @@ HELLO=WORLD -PYPI_VENDOR_DIR="./tests/pypi/" \ No newline at end of file diff --git a/run-tests.bat b/run-tests.bat index 4ddcee2bb4..f31a562a73 100644 --- a/run-tests.bat +++ b/run-tests.bat @@ -4,4 +4,4 @@ virtualenv R:\.venv R:\.venv\Scripts\pip install -e . --upgrade --upgrade-strategy=only-if-needed R:\.venv\Scripts\pipenv install --dev -SET RAM_DISK=R:&& SET PYPI_VENDOR_DIR=".\tests\pypi\" && R:\.venv\Scripts\pipenv run pytest -n auto -v tests --tap-stream > report.tap +SET RAM_DISK=R: && R:\.venv\Scripts\pipenv run pytest -n auto -v tests --tap-stream > report.tap diff --git a/run-tests.sh b/run-tests.sh index 493a90a83d..b71fd4fb83 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -4,9 +4,6 @@ set -eo pipefail -# Set the PYPI vendor URL for pytest-pypi. -PYPI_VENDOR_DIR="$(pwd)/tests/pypi/" -export PYPI_VENDOR_DIR export PYTHONIOENCODING="utf-8" export LANG=C.UTF-8 From 3a25846f8805c556cf8a6e8f67fd6def0a57560d Mon Sep 17 00:00:00 2001 From: Jacob Hayes Date: Wed, 11 Jul 2018 13:26:03 -0500 Subject: [PATCH 3/6] Add dev setup and testing section to CONTRIBUTING.md --- CONTRIBUTING.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d7fa45c6cd..bb17336e58 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,3 +55,45 @@ Please be aware of the following things when filing bug reports: If you do not provide all of these things, it will take us much longer to fix your problem. If we ask you to clarify these and you never respond, we will close your issue without fixing it. + +## Development Setup + +To get your development environment setup, run: + +```sh +pip install -e . +pipenv install --dev +``` + +This will install the repo version of Pipenv and then install the development +dependencies. Once that has completed, you can start developing. + +The repo version of Pipenv must be installed over other global versions to +resolve conflicts with the `pipenv` folder being implicitly added to `sys.path`. +See pypa/pipenv#2557 for more details. + +### Testing + +Tests are written in `pytest` style and can be run very simply: + +```sh +pytest +``` + +This will run all Pipenv tests, which can take awhile. To run a subset of the +tests, the standard pytest filters are available, such as: + +- provide a directory or file: `pytest tests/unit` or `pytest tests/unit/test_cmdparse.py` +- provide a keyword expression: `pytest -k test_lock_editable_vcs_without_install` +- provide a nodeid: `pytest tests/unit/test_cmdparse.py::test_parse` +- provide a test marker: `pytest -m lock` + +#### Package Index + +To speed up testing, tests that rely on a package index for locking and +installing use a local server that contains vendored packages in the +`tests/pypi` directory. Each vendored package should have it's own folder +containing the necessary releases. When adding a release for a package, it is +easiest to use either the `.tar.gz` or universal wheels (ex: `py2.py3-none`). If +a `.tar.gz` or universal wheel is not available, add wheels for all available +architectures and platforms. From aaac6c64292f4457dedf7abdf21abd3cd4597e3a Mon Sep 17 00:00:00 2001 From: Jacob Hayes Date: Wed, 11 Jul 2018 15:16:46 -0500 Subject: [PATCH 4/6] Replace test PYPI_VENDOR_DIR envvar with explicit package prep --- tests/integration/conftest.py | 4 +- tests/pytest-pypi/pytest_pypi/app.py | 61 +++++++++++-------- .../pytest_pypi/templates/package.html | 4 +- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index d71f0f89eb..8a8aebe6c1 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -9,6 +9,7 @@ from pipenv.vendor import requests from pipenv.vendor import six from pipenv.vendor import toml +from pytest_pypi.app import prepare_packages as prepare_pypi_packages if six.PY2: class ResourceWarning(Warning): @@ -30,6 +31,8 @@ def check_internet(): WE_HAVE_INTERNET = check_internet() TESTS_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +PYPI_VENDOR_DIR = os.path.join(TESTS_ROOT, 'pypi') +prepare_pypi_packages(PYPI_VENDOR_DIR) def pytest_runtest_setup(item): @@ -68,7 +71,6 @@ def __enter__(self): os.environ['PIPENV_DONT_USE_PYENV'] = '1' os.environ['PIPENV_IGNORE_VIRTUALENVS'] = '1' os.environ['PIPENV_VENV_IN_PROJECT'] = '1' - os.environ['PYPI_VENDOR_DIR'] = os.path.join(TESTS_ROOT, 'pypi') if self.chdir: os.chdir(self.path) return self diff --git a/tests/pytest-pypi/pytest_pypi/app.py b/tests/pytest-pypi/pytest_pypi/app.py index 57a368b852..7ac1bc4b75 100644 --- a/tests/pytest-pypi/pytest_pypi/app.py +++ b/tests/pytest-pypi/pytest_pypi/app.py @@ -4,9 +4,6 @@ import requests from flask import Flask, redirect, abort, render_template, send_file, jsonify -PYPI_VENDOR_DIR = os.environ.get('PYPI_VENDOR_DIR', './pypi') -PYPI_VENDOR_DIR = os.path.abspath(PYPI_VENDOR_DIR) - app = Flask(__name__) session = requests.Session() @@ -14,41 +11,49 @@ class Package(object): - """docstring for Package""" + """Package represents a collection of releases from one or more directories""" def __init__(self, name): super(Package, self).__init__() self.name = name - self._releases = [] + self.releases = {} + self._package_dirs = set() @property - def releases(self): - r = [] - for release in self._releases: - release = release[len(PYPI_VENDOR_DIR):].replace('\\', '/') - r.append(release) - return r + def json(self): + for path in self._package_dirs: + try: + with open(os.path.join(path, 'api.json')) as f: + return json.load(f) + except FileNotFoundError: + pass def __repr__(self): return "/json') def json_for_package(package): try: - with open(os.path.sep.join([PYPI_VENDOR_DIR, package, 'api.json'])) as f: - return jsonify(json.load(f)) + return jsonify(packages[package].json) except Exception: pass r = session.get('https://pypi.org/pypi/{0}/json'.format(package)) return jsonify(r.json()) + if __name__ == '__main__': + PYPI_VENDOR_DIR = os.environ.get('PYPI_VENDOR_DIR', './pypi') + PYPI_VENDOR_DIR = os.path.abspath(PYPI_VENDOR_DIR) + prepare_packages(PYPI_VENDOR_DIR) + app.run() diff --git a/tests/pytest-pypi/pytest_pypi/templates/package.html b/tests/pytest-pypi/pytest_pypi/templates/package.html index 36e70a8826..26ba9eca16 100644 --- a/tests/pytest-pypi/pytest_pypi/templates/package.html +++ b/tests/pytest-pypi/pytest_pypi/templates/package.html @@ -7,8 +7,8 @@

Links for {{ package.name }}

{% for release in package.releases %} - {{ release }} + {{ release }}
{% endfor %} - \ No newline at end of file + From 74de4d6af092ee21d49c5c58138133830eb5d8a8 Mon Sep 17 00:00:00 2001 From: Jacob Hayes Date: Wed, 11 Jul 2018 15:59:39 -0500 Subject: [PATCH 5/6] Remove duplicate dir check --- tests/pytest-pypi/pytest_pypi/app.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/pytest-pypi/pytest_pypi/app.py b/tests/pytest-pypi/pytest_pypi/app.py index 7ac1bc4b75..ba1a543733 100644 --- a/tests/pytest-pypi/pytest_pypi/app.py +++ b/tests/pytest-pypi/pytest_pypi/app.py @@ -41,8 +41,6 @@ def add_release(self, path_to_binary): def prepare_packages(path): """Add packages in path to the registry.""" path = os.path.abspath(path) - if not (os.path.exists(path) and os.path.isdir(path)): - raise ValueError("{} is not a directory!".format(path)) if not (os.path.exists(path) and os.path.isdir(path)): raise ValueError("{} is not a directory!".format(path)) for root, dirs, files in os.walk(path): From f71167853737ac2f22166d5e9529e18ee92f9a7c Mon Sep 17 00:00:00 2001 From: Tzu-ping Chung Date: Fri, 13 Jul 2018 03:14:21 +0800 Subject: [PATCH 6/6] Get virtualenv location from output The Project class's implementation is a fucking mess. Avoid that. --- tests/integration/test_install_basic.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/integration/test_install_basic.py b/tests/integration/test_install_basic.py index e5a481278e..ab6648f42b 100644 --- a/tests/integration/test_install_basic.py +++ b/tests/integration/test_install_basic.py @@ -359,10 +359,16 @@ def test_install_venv_project_directory(PipenvInstance, pypi): os.environ["WORKON_HOME"] = workon_home.name if "PIPENV_VENV_IN_PROJECT" in os.environ: del os.environ["PIPENV_VENV_IN_PROJECT"] + c = p.pipenv("install six") assert c.return_code == 0 - project = Project() - assert Path(project.virtualenv_location).joinpath(".project").exists() + + venv_loc = None + for line in c.err.splitlines(): + if line.startswith("Virtualenv location:"): + venv_loc = Path(line.split(":", 1)[-1].strip()) + assert venv_loc is not None + assert venv_loc.joinpath(".project").exists() @pytest.mark.deploy