mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 14:50:16 +00:00
Fix local serving of static resource fixtures
Signed-off-by: Dan Ryan <dan@danryan.co>
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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.
@@ -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>
|
||||
Reference in New Issue
Block a user