import re import textwrap from collections import defaultdict from urllib import request def get_supported_versions(url): with request.urlopen(url) as response: response_content = response.read() content = response_content.decode("utf-8") def parse_supported_versions(content): def cut_by_content(content, cut_from, cut_to): return content.split(cut_from)[1].split(cut_to)[0] def keys_from_content(content): return re.findall(r"(.*?)", content) content = cut_by_content( content, '', "", ) content = cut_by_content(content, '', "") versions = keys_from_content(content) version_dict = dict(zip(versions[::2], versions[1::2])) django_to_python = { version_to_tuple(python_version): [ version_to_tuple(version_string) for version_string in re.findall(r"(?={b},<{c}" for a, b, c in sorted(lines)] return "deps = \n" + textwrap.indent("\n".join(lines), prefix=" ") def build_pypi_classifiers(python_to_django): classifiers = [] all_python_versions = python_to_django.keys() for python_version in all_python_versions: classifiers.append(f'"Programming Language :: Python :: {env_format(python_version, divider=".")}",') all_django_versions = set() for django_versions in python_to_django.values(): for django_version in django_versions: all_django_versions.add(django_version) for django_version in sorted(all_django_versions): classifiers.append(f'"Framework :: Django :: {env_format(django_version, divider=".")}",') return textwrap.indent("classifiers=[\n", prefix=" " * 4) + textwrap.indent("\n".join(classifiers), prefix=" " * 8) def build_readme(python_to_django): print( textwrap.dedent( """\ | Python version | Django version | |----------------|--------------------------| """.rstrip() ) ) lines = [ ( env_format(python_version, divider="."), ", ".join(env_format(version, divider=".") for version in django_versions), ) for python_version, django_versions in python_to_django.items() ] lines = [f"| {a: <14} | {b: <24} |" for a, b in lines] version_lines = "\n".join([version for version in lines]) return version_lines def build_pyenv(python_to_django): lines = [] all_python_versions = python_to_django.keys() for python_version in all_python_versions: lines.append(f'pyenv install -s {env_format(python_version, divider=".")}') lines.append(f'pyenv local {" ".join(env_format(version, divider=".") for version in all_python_versions)}') lines.append("tox -p") return "\n".join(lines) def build_ci_python_versions(python_to_django): # Outputs python-version: ['3.6', '3.7', '3.8', '3.9', '3.10', '3.11'] lines = [ f"'{env_format(python_version, divider='.')}'" for python_version, django_versions in python_to_django.items() ] lines = " " * 8 + f"python-version: [{', '.join(lines)}]" return lines def main(): django_to_python = get_supported_versions("https://docs.djangoproject.com/en/dev/faq/install/") latest_version = get_latest_version("https://www.djangoproject.com/download/") python_to_django = build_python_to_django(django_to_python, latest_version) tox_envlist = build_tox_envlist(python_to_django) print("Add this to tox.ini:\n") print("[tox]") print(tox_envlist) print() gh_actions_envlist = build_gh_actions_envlist(python_to_django) print("[gh-actions]") print(gh_actions_envlist) print() deps_envlist = build_deps_envlist(python_to_django) print("[testenv]") print(deps_envlist) print() print() print("Add this to setup.py:\n") pypi_classifiers = build_pypi_classifiers(python_to_django) print(pypi_classifiers) print() print() print("Add this to the middle of README.md:\n") readme = build_readme(python_to_django) print(readme) print() print() print("And this to the end of README.md:\n") pyenv = build_pyenv(python_to_django) print(pyenv) print() print() print("Add this to tests.yml:\n") ci_python_versions = build_ci_python_versions(python_to_django) print(ci_python_versions) print() print() if __name__ == "__main__": main()