Fix local serving of static resource fixtures

Signed-off-by: Dan Ryan <dan@danryan.co>
This commit is contained in:
Dan Ryan
2018-11-22 17:05:57 -05:00
parent a0c3d7d6a6
commit a3b5e8f374
6 changed files with 113 additions and 5 deletions
+25 -1
View File
@@ -12,7 +12,7 @@ from pipenv.vendor import delegator
from pipenv.vendor import requests
from pipenv.vendor import toml
from pipenv.vendor import tomlkit
from pytest_pypi.app import prepare_packages as prepare_pypi_packages
from pytest_pypi.app import prepare_packages as prepare_pypi_packages, prepare_fixtures
from vistir.compat import ResourceWarning, fs_str
from vistir.path import mkdir_p
@@ -71,6 +71,7 @@ TESTS_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PYPI_VENDOR_DIR = os.path.join(TESTS_ROOT, 'pypi')
WE_HAVE_HG = check_for_mercurial()
prepare_pypi_packages(PYPI_VENDOR_DIR)
prepare_fixtures(os.path.join(PYPI_VENDOR_DIR, "fixtures"))
def pytest_runtest_setup(item):
@@ -144,6 +145,9 @@ class _Pipfile(object):
self.document[section][package] = value
self.write()
def add(self, package, value, dev=False):
self.install(package, value, dev=dev)
def loads(self):
self.document = tomlkit.loads(self.path.read_text())
@@ -162,6 +166,25 @@ class _Pipfile(object):
def get_fixture_path(cls, path):
return Path(__file__).absolute().parent.parent / "test_artifacts" / path
@classmethod
def get_url(cls, pkg=None, filename=None):
pypi = os.environ.get("PIPENV_PYPI_URL")
if not pkg and not filename:
return pypi if pypi else "https://pypi.org/"
file_path = filename
if pkg and filename:
file_path = os.path.join(pkg, filename)
if filename and not pkg:
pkg = os.path.basename(filename)
if pypi:
if pkg and not filename:
url = "{0}/artifacts/{1}".format(pypi, pkg)
else:
url = "{0}/artifacts/{1}/{2}".format(pypi, pkg, filename)
return url
if pkg and not filename:
return cls.get_fixture_path(file_path).as_uri()
class _PipenvInstance(object):
"""An instance of a Pipenv Project..."""
@@ -189,6 +212,7 @@ class _PipenvInstance(object):
self.chdir = chdir
if self.pypi:
os.environ['PIPENV_PYPI_URL'] = fs_str('{0}'.format(self.pypi.url))
os.environ['PIPENV_TEST_INDEX'] = fs_str('{0}/simple'.format(self.pypi.url))
if pipfile:
+2 -2
View File
@@ -64,9 +64,9 @@ def test_ssh_vcs_install(PipenvInstance, pip_src_dir, pypi):
@flaky
def test_urls_work(PipenvInstance, pypi, pip_src_dir):
with PipenvInstance(pypi=pypi, chdir=True) as p:
path = p._pipfile.get_fixture_path("django/3.4.x.zip")
path = p._pipfile.get_url("django", "3.4.x.zip")
c = p.pipenv(
"install {0}".format(path.as_uri())
"install {0}".format(path)
)
assert c.return_code == 0
Binary file not shown.
+59 -2
View File
@@ -1,5 +1,6 @@
import os
import json
import sys
import requests
from flask import Flask, redirect, abort, render_template, send_file, jsonify
@@ -8,7 +9,7 @@ app = Flask(__name__)
session = requests.Session()
packages = {}
ARTIFACTS = {}
class Package(object):
"""Package represents a collection of releases from one or more directories"""
@@ -38,6 +39,37 @@ class Package(object):
self._package_dirs.add(path)
class Artifact(object):
"""Represents an artifact for download"""
def __init__(self, name):
super(Artifact, self).__init__()
self.name = name
self.files = {}
self._artifact_dirs = set()
def __repr__(self):
return "<Artifact name={0!r} files={1!r}".format(self.name, len(self.files))
def add_dir(self, path):
path = os.path.abspath(path)
base_path, fn = os.path.split(path)
self.files[fn] = path
self._artifact_dirs.add(base_path)
def prepare_fixtures(path):
path = os.path.abspath(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):
for file in files:
package_name = os.path.basename(root)
if package_name not in ARTIFACTS:
ARTIFACTS[package_name] = Artifact(package_name)
ARTIFACTS[package_name].add_dir(os.path.join(root, file))
def prepare_packages(path):
"""Add packages in path to the registry."""
path = os.path.abspath(path)
@@ -47,7 +79,9 @@ def prepare_packages(path):
for file in files:
if not file.startswith('.') and not file.endswith('.json'):
package_name = os.path.basename(root)
if package_name and package_name == "fixtures":
prepare_fixtures(root)
continue
if package_name not in packages:
packages[package_name] = Package(package_name)
@@ -64,6 +98,11 @@ def simple():
return render_template('simple.html', packages=packages.values())
@app.route('/artifacts')
def artifacts():
return render_template('artifacts.html', artifacts=ARTIFACTS.values())
@app.route('/simple/<package>/')
def simple_package(package):
if package in packages:
@@ -72,6 +111,14 @@ def simple_package(package):
abort(404)
@app.route('/artifacts/<artifact>/')
def simple_artifact(artifact):
if artifact in ARTIFACTS:
return render_template('artifact.html', artifact=ARTIFACTS[artifact])
else:
abort(404)
@app.route('/<package>/<release>')
def serve_package(package, release):
if package in packages:
@@ -83,6 +130,15 @@ def serve_package(package, release):
abort(404)
@app.route('/artifacts/<artifact>/<fn>')
def serve_artifact(artifact, fn):
if artifact in ARTIFACTS:
artifact = ARTIFACTS[artifact]
if fn in artifact.files:
return send_file(artifact.files[fn])
abort(404)
@app.route('/pypi/<package>/json')
def json_for_package(package):
try:
@@ -98,5 +154,6 @@ 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)
prepare_fixtures(os.path.join(PYPI_VENDOR_DIR, "fixtures"))
app.run()
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Links for {{ artifact.name }}</title>
</head>
<body>
<h1>Links for {{ artifact.name }}</h1>
{% for fn in artifact.files %}
<a href="/{{ artifact.name }}/{{ fn }}">{{ fn }}</a>
<br>
{% endfor %}
</body>
</html>
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Artifact Index</title>
</head>
<body>
{% for artifact in artifacts %}
<a href="/artifacts/{{ artifact.name }}/" rel="internal">{{ artifact.name }}</a>
<br>
{% endfor %}
</body>
</html>