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