2020-07-18 17:35:13 +08:00
|
|
|
"""Invoke development tasks."""
|
2018-07-14 21:21:31 +08:00
|
|
|
import argparse
|
2020-07-09 05:38:29 +08:00
|
|
|
import os
|
2017-05-10 09:55:27 +08:00
|
|
|
from pathlib import Path
|
2018-10-25 15:01:29 +08:00
|
|
|
from subprocess import call
|
|
|
|
from subprocess import check_call
|
|
|
|
from subprocess import check_output
|
|
|
|
|
|
|
|
from colorama import Fore
|
|
|
|
from colorama import init
|
2017-05-10 09:55:27 +08:00
|
|
|
|
|
|
|
|
2018-07-14 21:21:31 +08:00
|
|
|
def announce(version):
|
2017-05-10 09:55:27 +08:00
|
|
|
"""Generates a new release announcement entry in the docs."""
|
|
|
|
# Get our list of authors
|
2018-05-23 22:48:46 +08:00
|
|
|
stdout = check_output(["git", "describe", "--abbrev=0", "--tags"])
|
|
|
|
stdout = stdout.decode("utf-8")
|
2017-05-10 09:55:27 +08:00
|
|
|
last_version = stdout.strip()
|
|
|
|
|
2020-10-03 04:16:22 +08:00
|
|
|
stdout = check_output(["git", "log", f"{last_version}..HEAD", "--format=%aN"])
|
2018-05-23 22:48:46 +08:00
|
|
|
stdout = stdout.decode("utf-8")
|
2017-05-10 09:55:27 +08:00
|
|
|
|
2021-06-30 21:53:32 +08:00
|
|
|
contributors = {name for name in stdout.splitlines() if not name.endswith("[bot]")}
|
2017-05-10 09:55:27 +08:00
|
|
|
|
2018-06-26 21:35:27 +08:00
|
|
|
template_name = (
|
|
|
|
"release.minor.rst" if version.endswith(".0") else "release.patch.rst"
|
|
|
|
)
|
|
|
|
template_text = (
|
|
|
|
Path(__file__).parent.joinpath(template_name).read_text(encoding="UTF-8")
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
2017-05-10 09:55:27 +08:00
|
|
|
|
2020-10-03 04:16:22 +08:00
|
|
|
contributors_text = "\n".join(f"* {name}" for name in sorted(contributors)) + "\n"
|
2017-05-10 09:55:27 +08:00
|
|
|
text = template_text.format(version=version, contributors=contributors_text)
|
|
|
|
|
2020-10-03 04:16:22 +08:00
|
|
|
target = Path(__file__).parent.joinpath(f"../doc/en/announce/release-{version}.rst")
|
2018-05-23 22:48:46 +08:00
|
|
|
target.write_text(text, encoding="UTF-8")
|
2018-07-14 21:21:31 +08:00
|
|
|
print(f"{Fore.CYAN}[generate.announce] {Fore.RESET}Generated {target.name}")
|
2017-05-10 09:55:27 +08:00
|
|
|
|
|
|
|
# Update index with the new release entry
|
2018-05-23 22:48:46 +08:00
|
|
|
index_path = Path(__file__).parent.joinpath("../doc/en/announce/index.rst")
|
|
|
|
lines = index_path.read_text(encoding="UTF-8").splitlines()
|
|
|
|
indent = " "
|
2017-05-10 09:55:27 +08:00
|
|
|
for index, line in enumerate(lines):
|
2020-10-03 04:16:22 +08:00
|
|
|
if line.startswith(f"{indent}release-"):
|
2017-05-10 09:55:27 +08:00
|
|
|
new_line = indent + target.stem
|
|
|
|
if line != new_line:
|
|
|
|
lines.insert(index, new_line)
|
2018-05-23 22:48:46 +08:00
|
|
|
index_path.write_text("\n".join(lines) + "\n", encoding="UTF-8")
|
2018-07-14 21:21:31 +08:00
|
|
|
print(
|
|
|
|
f"{Fore.CYAN}[generate.announce] {Fore.RESET}Updated {index_path.name}"
|
|
|
|
)
|
2017-05-10 09:55:27 +08:00
|
|
|
else:
|
2018-05-23 22:48:46 +08:00
|
|
|
print(
|
2018-07-14 21:21:31 +08:00
|
|
|
f"{Fore.CYAN}[generate.announce] {Fore.RESET}Skip {index_path.name} (already contains release)"
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
2017-05-10 09:55:27 +08:00
|
|
|
break
|
|
|
|
|
2018-05-23 22:48:46 +08:00
|
|
|
check_call(["git", "add", str(target)])
|
2017-05-16 07:23:04 +08:00
|
|
|
|
|
|
|
|
2020-07-09 05:38:29 +08:00
|
|
|
def regen(version):
|
2017-05-16 07:23:04 +08:00
|
|
|
"""Call regendoc tool to update examples and pytest output in the docs."""
|
2018-07-14 21:21:31 +08:00
|
|
|
print(f"{Fore.CYAN}[generate.regen] {Fore.RESET}Updating docs")
|
2020-07-09 05:38:29 +08:00
|
|
|
check_call(
|
|
|
|
["tox", "-e", "regen"],
|
|
|
|
env={**os.environ, "SETUPTOOLS_SCM_PRETEND_VERSION": version},
|
|
|
|
)
|
2017-05-16 07:23:04 +08:00
|
|
|
|
|
|
|
|
2018-07-14 21:21:31 +08:00
|
|
|
def fix_formatting():
|
|
|
|
"""Runs pre-commit in all files to ensure they are formatted correctly"""
|
|
|
|
print(
|
|
|
|
f"{Fore.CYAN}[generate.fix linting] {Fore.RESET}Fixing formatting using pre-commit"
|
|
|
|
)
|
|
|
|
call(["pre-commit", "run", "--all-files"])
|
2017-05-10 09:55:27 +08:00
|
|
|
|
|
|
|
|
2019-07-13 22:06:56 +08:00
|
|
|
def check_links():
|
|
|
|
"""Runs sphinx-build to check links"""
|
|
|
|
print(f"{Fore.CYAN}[generate.check_links] {Fore.RESET}Checking links")
|
|
|
|
check_call(["tox", "-e", "docs-checklinks"])
|
|
|
|
|
|
|
|
|
2019-11-25 11:06:30 +08:00
|
|
|
def pre_release(version, *, skip_check_links):
|
2018-02-10 06:59:15 +08:00
|
|
|
"""Generates new docs, release announcements and creates a local tag."""
|
2018-07-14 21:21:31 +08:00
|
|
|
announce(version)
|
2020-07-09 05:38:29 +08:00
|
|
|
regen(version)
|
2018-07-14 21:21:31 +08:00
|
|
|
changelog(version, write_out=True)
|
|
|
|
fix_formatting()
|
2019-11-25 11:06:30 +08:00
|
|
|
if not skip_check_links:
|
|
|
|
check_links()
|
2017-05-16 07:23:04 +08:00
|
|
|
|
2020-10-03 04:16:22 +08:00
|
|
|
msg = f"Prepare release version {version}"
|
2018-05-23 22:48:46 +08:00
|
|
|
check_call(["git", "commit", "-a", "-m", msg])
|
2018-02-10 06:59:15 +08:00
|
|
|
|
2017-05-16 07:23:04 +08:00
|
|
|
print()
|
2018-07-14 21:21:31 +08:00
|
|
|
print(f"{Fore.CYAN}[generate.pre_release] {Fore.GREEN}All done!")
|
|
|
|
print()
|
2020-01-17 12:53:54 +08:00
|
|
|
print("Please push your branch and open a PR.")
|
2017-05-10 09:55:27 +08:00
|
|
|
|
2017-05-23 06:06:53 +08:00
|
|
|
|
2018-07-14 21:21:31 +08:00
|
|
|
def changelog(version, write_out=False):
|
2021-05-11 17:52:55 +08:00
|
|
|
addopts = [] if write_out else ["--draft"]
|
2018-05-23 22:48:46 +08:00
|
|
|
check_call(["towncrier", "--yes", "--version", version] + addopts)
|
2018-07-14 21:21:31 +08:00
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
init(autoreset=True)
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument("version", help="Release version")
|
2019-11-25 11:06:30 +08:00
|
|
|
parser.add_argument("--skip-check-links", action="store_true", default=False)
|
2018-07-14 21:21:31 +08:00
|
|
|
options = parser.parse_args()
|
2019-11-25 11:06:30 +08:00
|
|
|
pre_release(options.version, skip_check_links=options.skip_check_links)
|
2018-07-14 21:21:31 +08:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|