import os
import pytest
import re
import shutil
import subprocess
SETUP_TEMPLATE = '''\
from setuptools import setup
setup(
name='{name}',
version='{version}',
description='{name}',
packages=['{pkgdirname}'],
entry_points={{
'console_scripts': [
'{pkgdirname}={pkgdirname}:main'
]
}}
)
'''
# All packages generated via generate_pip_package will have the functions below
INIT_TEMPLATE = '''\
def main():
print('This is {name}')
def hello(actor='world'):
print('Hello {{}}! This is {name}'.format(actor))
'''
HTML_TEMPLATE = '''\
Links for {name}
{name}-{version}.tar.gz
'''
# Creates a simple python source distribution and copies this into a specified
# directory which is to serve as a mock python repository
#
# Args:
# tmpdir (str): Directory in which the source files will be created
# pypi (str): Directory serving as a mock python repository
# name (str): The name of the package to be created
# version (str): The version of the package to be created
#
# Returns:
# None
#
def generate_pip_package(tmpdir, pypi, name, version='0.1'):
# check if package already exists in pypi
pypi_package = os.path.join(pypi, re.sub('[^0-9a-zA-Z]+', '-', name))
if os.path.exists(pypi_package):
return
# create the package source files in tmpdir resulting in a directory
# tree resembling the following structure:
#
# tmpdir
# |-- setup.py
# `-- package
# `-- __init__.py
#
setup_file = os.path.join(tmpdir, 'setup.py')
pkgdirname = re.sub('[^0-9a-zA-Z]+', '', name)
with open(setup_file, 'w') as f:
f.write(
SETUP_TEMPLATE.format(
name=name,
version=version,
pkgdirname=pkgdirname
)
)
os.chmod(setup_file, 0o755)
package = os.path.join(tmpdir, pkgdirname)
os.makedirs(package)
main_file = os.path.join(package, '__init__.py')
with open(main_file, 'w') as f:
f.write(INIT_TEMPLATE.format(name=name))
os.chmod(main_file, 0o644)
# Run sdist with a fresh process
p = subprocess.run(['python3', 'setup.py', 'sdist'], cwd=tmpdir)
assert p.returncode == 0
# create directory for this package in pypi resulting in a directory
# tree resembling the following structure:
#
# pypi
# `-- pypi_package
# |-- index.html
# `-- foo-0.1.tar.gz
#
os.makedirs(pypi_package)
# add an index html page
index_html = os.path.join(pypi_package, 'index.html')
with open(index_html, 'w') as f:
f.write(HTML_TEMPLATE.format(name=name, version=version))
# copy generated tarfile to pypi package
dist_dir = os.path.join(tmpdir, 'dist')
for tar in os.listdir(dist_dir):
tarpath = os.path.join(dist_dir, tar)
shutil.copy(tarpath, pypi_package)
@pytest.fixture
def setup_pypi_repo(tmpdir):
def create_pkgdir(package):
pkgdirname = re.sub('[^0-9a-zA-Z]+', '', package)
pkgdir = os.path.join(str(tmpdir), pkgdirname)
os.makedirs(pkgdir)
return pkgdir
def add_packages(packages, pypi_repo):
for package in packages:
pkgdir = create_pkgdir(package)
generate_pip_package(pkgdir, pypi_repo, package)
return add_packages