diff options
author | Pierre Sassoulas <pierre.sassoulas@gmail.com> | 2021-06-29 19:04:46 +0200 |
---|---|---|
committer | Pierre Sassoulas <pierre.sassoulas@gmail.com> | 2021-06-29 21:13:47 +0200 |
commit | 58a4af34b5db6b437ab8db4e574c256ce1296fa6 (patch) | |
tree | b6acd8f3ab74f43dbd2cc770579af192df08f7c8 | |
parent | 31afab238f71275becea9a5ac52f822c2616e799 (diff) | |
download | pylint-git-58a4af34b5db6b437ab8db4e574c256ce1296fa6.tar.gz |
Upgrade the release script using what was done in astroid
-rw-r--r-- | script/bump_changelog.py | 159 |
1 files changed, 119 insertions, 40 deletions
diff --git a/script/bump_changelog.py b/script/bump_changelog.py index e51653056..08c0c69ac 100644 --- a/script/bump_changelog.py +++ b/script/bump_changelog.py @@ -4,76 +4,155 @@ """ This script permits to upgrade the changelog in astroid or pylint when releasing a version. """ +# pylint: disable=logging-fstring-interpolation import argparse +import enum +import logging from datetime import datetime from pathlib import Path +from typing import List DEFAULT_CHANGELOG_PATH = Path("ChangeLog") -err = "in the changelog, fix that first!" -TBA_ERROR_MSG = "More than one release date 'TBA' %s" % err -NEW_VERSION_ERROR_MSG = "The text for this version '{version}' did not exists %s" % err -NEXT_VERSION_ERROR_MSG = ( - "The text for the next version '{version}' already exists %s" % err -) +RELEASE_DATE_TEXT = "Release date: TBA" +WHATS_NEW_TEXT = "What's New in Pylint" TODAY = datetime.now() -WHATS_NEW_TEXT = "What's New in astroid" FULL_WHATS_NEW_TEXT = WHATS_NEW_TEXT + " {version}?" -RELEASE_DATE_TEXT = "Release Date: TBA" -NEW_RELEASE_DATE_MESSAGE = "Release Date: {}".format(TODAY.strftime("%Y-%m-%d")) +NEW_RELEASE_DATE_MESSAGE = "Release date: {}".format(TODAY.strftime("%Y-%m-%d")) def main() -> None: parser = argparse.ArgumentParser(__doc__) parser.add_argument("version", help="The version we want to release") + parser.add_argument( + "-v", "--verbose", action="store_true", default=False, help="Logging or not" + ) args = parser.parse_args() - if "dev" not in args.version: - version = args.version - next_version = get_next_version(version) - run(version, next_version) + if args.verbose: + logging.basicConfig(level=logging.DEBUG) + logging.debug(f"Launching bump_changelog with args: {args}") + if "dev" in args.version: + return + with open(DEFAULT_CHANGELOG_PATH) as f: + content = f.read() + content = transform_content(content, args.version) + with open(DEFAULT_CHANGELOG_PATH, "w") as f: + f.write(content) + +class VersionType(enum.Enum): + MAJOR = 0 + MINOR = 1 + PATCH = 2 -def get_next_version(version: str) -> str: + +def get_next_version(version: str, version_type: VersionType) -> str: new_version = version.split(".") - patch = new_version[2] - reminder = None - if "-" in patch: - patch, reminder = patch.split("-") - patch = str(int(patch) + 1) - new_version[2] = patch if reminder is None else f"{patch}-{reminder}" + part_to_increase = new_version[version_type.value] + if "-" in part_to_increase: + part_to_increase = part_to_increase.split("-")[0] + for i in range(version_type.value, 3): + new_version[i] = "0" + new_version[version_type.value] = str(int(part_to_increase) + 1) return ".".join(new_version) -def run(version: str, next_version: str) -> None: - with open(DEFAULT_CHANGELOG_PATH) as f: - content = f.read() - content = transform_content(content, version, next_version) - with open(DEFAULT_CHANGELOG_PATH, "w") as f: - f.write(content) +def get_next_versions(version: str, version_type: VersionType) -> List[str]: + + if version_type == VersionType.PATCH: + # "2.6.1" => ["2.6.2"] + return [get_next_version(version, VersionType.PATCH)] + if version_type == VersionType.MINOR: + # "2.6.0" => ["2.7.0", "2.6.1"] + assert version.endswith(".0"), f"{version} does not look like a minor version" + else: + # "3.0.0" => ["3.1.0", "3.0.1"] + assert version.endswith(".0.0"), f"{version} does not look like a major version" + next_minor_version = get_next_version(version, VersionType.MINOR) + next_patch_version = get_next_version(version, VersionType.PATCH) + logging.debug(f"Getting the new version for {version} - {version_type.name}") + return [next_minor_version, next_patch_version] -def transform_content(content: str, version: str, next_version: str) -> str: - wn_new_version = FULL_WHATS_NEW_TEXT.format(version=version) - wn_next_version = FULL_WHATS_NEW_TEXT.format(version=next_version) +def get_version_type(version: str) -> VersionType: + if version.endswith("0.0"): + version_type = VersionType.MAJOR + elif version.endswith("0"): + version_type = VersionType.MINOR + else: + version_type = VersionType.PATCH + return version_type + + +def get_whats_new( + version: str, add_date: bool = False, change_date: bool = False +) -> str: + whats_new_text = FULL_WHATS_NEW_TEXT.format(version=version) + result = [whats_new_text, "=" * len(whats_new_text)] + if add_date and change_date: + result += [NEW_RELEASE_DATE_MESSAGE] + elif add_date: + result += [RELEASE_DATE_TEXT] + elif change_date: + raise ValueError("Can't use change_date=True with add_date=False") + logging.debug( + f"version='{version}', add_date='{add_date}', change_date='{change_date}': {result}" + ) + return "\n".join(result) + + +def get_all_whats_new(version: str, version_type: VersionType) -> str: + result = "" + for version_ in get_next_versions(version, version_type=version_type): + result += get_whats_new(version_, add_date=True) + "\n" * 4 + return result + + +def transform_content(content: str, version: str) -> str: + version_type = get_version_type(version) + next_version = get_next_version(version, version_type) + old_date = get_whats_new(version, add_date=True) + new_date = get_whats_new(version, add_date=True, change_date=True) + next_version_with_date = get_all_whats_new(version, version_type) + do_checks(content, next_version, version, version_type) + index = content.find(old_date) + logging.debug(f"Replacing\n'{old_date}'\nby\n'{new_date}'\n") + content = content.replace(old_date, new_date) + end_content = content[index:] + content = content[:index] + logging.debug(f"Adding:\n'{next_version_with_date}'\n") + content += next_version_with_date + end_content + return content + + +def do_checks(content, next_version, version, version_type): + err = "in the changelog, fix that first!" + NEW_VERSION_ERROR_MSG = ( + "The text for this version '{version}' did not exists %s" % err + ) + NEXT_VERSION_ERROR_MSG = ( + "The text for the next version '{version}' already exists %s" % err + ) + wn_next_version = get_whats_new(next_version) + wn_this_version = get_whats_new(version) # There is only one field where the release date is TBA - assert content.count(RELEASE_DATE_TEXT) == 1, TBA_ERROR_MSG + if version_type in [VersionType.MAJOR, VersionType.MINOR]: + assert ( + content.count(RELEASE_DATE_TEXT) <= 1 + ), f"There should be only one release date 'TBA' ({version}) {err}" + else: + next_minor_version = get_next_version(version, VersionType.MINOR) + assert ( + content.count(RELEASE_DATE_TEXT) <= 2 + ), f"There should be only two release dates 'TBA' ({version} and {next_minor_version}) {err}" # There is already a release note for the version we want to release - assert content.count(wn_new_version) == 1, NEW_VERSION_ERROR_MSG.format( + assert content.count(wn_this_version) == 1, NEW_VERSION_ERROR_MSG.format( version=version ) # There is no release notes for the next version assert content.count(wn_next_version) == 0, NEXT_VERSION_ERROR_MSG.format( version=next_version ) - index = content.find(WHATS_NEW_TEXT) - content = content.replace(RELEASE_DATE_TEXT, NEW_RELEASE_DATE_MESSAGE) - end_content = content[index:] - content = content[:index] - content += wn_next_version + "\n" - content += "=" * len(wn_next_version) + "\n" - content += RELEASE_DATE_TEXT + "\n" * 4 - content += end_content - return content if __name__ == "__main__": |