[docs]
def build_setup(self):
import re
import ubelt as ub
from xcookie import rc
# from distutils.version import Version
# from packaging.version import parse as Version
pkg_name = self.config['pkg_name']
min_python = self.config['min_python']
# min_py_version = str(self.config['min_python'])
fpath = rc.resource_fpath('setup.py.in')
template_text = fpath.read_text()
parts = re.split('(### xcookie: .*$)', template_text, flags=re.MULTILINE)
lut = {}
for p in parts:
if not p.strip():
continue
if p.startswith('### xcookie: +'):
key = p.split('+')[1]
elif p.startswith('### xcookie: -'):
assert key in lut
else:
assert key not in lut, f'key={key}'
lut[key] = p
parts = []
parts.append(
ub.codeblock(
"""
#!/usr/bin/env python
# Generated by ~/code/xcookie/xcookie/builders/setup.py
# based on part ~/code/xcookie/xcookie/rc/setup.py.in
import sys
import re
from os.path import exists, dirname, join
from setuptools import find_packages
"""
)
)
if 'binpy' in self.tags:
parts.append(lut['IF(binpy)'])
else:
parts.append(
ub.codeblock(
"""
from setuptools import setup
"""
)
)
parts.append(lut['HELPERS'])
parts.append(
ub.codeblock(
f"""
NAME = '{pkg_name}'
INIT_PATH = '{self.rel_mod_dpath}/__init__.py'
VERSION = parse_version(INIT_PATH)
"""
)
)
classifiers = self._project_classifiers()
# if 0:
# setupkw['entry_points'] = {
# # the console_scripts entry point creates the package CLI
# 'console_scripts': [
# 'xcookie = xcookie.__main__:main'
# ]
# }
extras = ['runtime', 'tests', 'optional']
parts.append(
ub.codeblock(
"""
if __name__ == '__main__':
setupkw = {}
setupkw['install_requires'] = parse_requirements('requirements/runtime.txt', versions='loose')
setupkw['extras_require'] = {
"""
)
)
# 'all': parse_requirements('requirements.txt', versions='loose'),
# 'tests': parse_requirements('requirements/tests.txt', versions='loose'),
# 'optional': parse_requirements('requirements/optional.txt', versions='loose'),
# cv2_part = ub.identity(
# '''
# 'headless': parse_requirements('requirements/headless.txt', versions='loose'),
# 'graphics': parse_requirements('requirements/graphics.txt', versions='loose'),
# # Strict versions
# 'headless-strict': parse_requirements('requirements/headless.txt', versions='strict'),
# 'graphics-strict': parse_requirements('requirements/graphics.txt', versions='strict'),
# ''')
if 'cv2' in self.tags:
extras = ['headless', 'graphics']
# parts.append(cv2_part)
# postgresql_part = '''
# 'postgresql': parse_requirements('requirements/postgresql.txt', versions='loose'),
# 'postgresql-strict': parse_requirements('requirements/postgresql.txt', versions='strict'),
# '''
if 'postgresql' in self.tags:
extras += ['postgresql']
# parts.append(postgresql_part)
requirements_dpath = self.repodir / 'requirements'
if requirements_dpath.exists():
# Hack to add in relevant extras
existing_req_files = sorted(requirements_dpath.glob('*.txt'))
extras += [f.stem for f in existing_req_files]
if extras:
extra_keyvalues = {}
extras = ub.oset(extras)
extra_lines = []
extra_keyvalues['all'] = (
"parse_requirements('requirements.txt', versions='loose')"
)
for name in extras:
extra_keyvalues[name] = (
f"parse_requirements('requirements/{name}.txt', versions='loose')"
)
extra_keyvalues['all-strict'] = (
"parse_requirements('requirements.txt', versions='strict')"
)
for name in extras:
extra_keyvalues[name + '-strict'] = (
f"parse_requirements('requirements/{name}.txt', versions='strict')"
)
for name, line in extra_keyvalues.items():
extra_lines.append(f"'{name}': {line},")
parts.append(ub.indent('\n'.join(extra_lines)) + '\n}')
# parts.append(ub.identity(
# '''
# 'all-strict': parse_requirements('requirements.txt', versions='strict'),
# 'runtime-strict': parse_requirements('requirements/runtime.txt', versions='strict'),
# 'tests-strict': parse_requirements('requirements/tests.txt', versions='strict'),
# 'optional-strict': parse_requirements('requirements/optional.txt', versions='strict'),
# }
# '''))
classifier_text = ub.urepr(classifiers)
pyproject_settings = self.config._load_xcookie_pyproject_settings()
# author=static_parse('__author__', INIT_PATH),
# author_email=static_parse('__author_email__', INIT_PATH),
# url=static_parse('__url__', INIT_PATH),
# TODO: Try placing most of this into a setup.cfg instead
setupkw_parts = {}
setupkw_parts['name'] = 'NAME'
setupkw_parts['version'] = 'VERSION'
if isinstance(self.config['author'], list):
setupkw_parts['author'] = repr(', '.join(self.config['author']))
else:
setupkw_parts['author'] = f'{self.config["author"]!r}'
if isinstance(self.config['author_email'], list):
setupkw_parts['author_email'] = repr(
', '.join(self.config['author_email'])
)
else:
setupkw_parts['author_email'] = f'{self.config["author_email"]!r}'
setupkw_parts['url'] = f'{self.config["url"]!r}'
setupkw_parts['description'] = f'{self.config["description"]!r}'
setupkw_parts['long_description'] = 'parse_description()'
setupkw_parts['long_description_content_type'] = "'text/x-rst'"
setupkw_parts['license'] = f'{self.config["license"]!r}'
setupkw_parts['packages'] = (
f'find_packages({self.config["rel_mod_parent_dpath"]!r})'
)
setupkw_parts['python_requires'] = f"'>={min_python}'"
setupkw_parts['classifiers'] = f'{classifier_text}'
package_data = {}
package_data[''] = ['requirements/*.txt']
# HACK: need to determine if we have the modname.rc structure or not
# for now just check if it exists, which wont work the first time.
has_rc_requirements = (self.mod_dpath / 'rc/requirements').exists()
if has_rc_requirements:
setupkw_parts['include_package_data'] = True
package_data[f'{self.mod_name}.rc.requirements'] = ['*.txt']
if self.config['typed']:
package_data[self.mod_name] = ['py.typed', '*.pyi']
if package_data:
setupkw_parts['package_data'] = package_data
if self.config['rel_mod_parent_dpath'] != '.':
# https://codefellows.github.io/sea-python-401d4/lectures/python_packaging_1.html
# We use a key of an empty string to indicate that the directory we are
# pointing to should be considered the root. Then the value is src, telling
# setuptools to use that directory as the root of our source.
setupkw_parts['package_dir'] = ub.urepr(
{'': self.config['rel_mod_parent_dpath']}
)
# hack
if pyproject_settings is None:
pyproject_settings = {}
if 'entry_points' in pyproject_settings:
setupkw_parts['entry_points'] = ub.urepr(
pyproject_settings['entry_points']
)
if 'scripts' in pyproject_settings:
setupkw_parts['scripts'] = ub.urepr(pyproject_settings['scripts'])
if 'package_data' in pyproject_settings:
setupkw_parts.setdefault('package_data', {})
setupkw_parts['package_data'].update(pyproject_settings['package_data'])
for k, v in setupkw_parts.items():
parts.append(ub.indent(f'setupkw[{k!r}] = {v}'))
if 'setuptools' in pyproject_settings:
for k, v in pyproject_settings['setuptools'].items():
parts.append(ub.indent(f'setupkw[{k!r}] = {v!r}'))
parts.append(ub.indent('setup(**setupkw)'))
text = '\n'.join(parts)
# print(text)
from xcookie.util.util_code_format import format_code
text = format_code(text)
return text