From 2aca680edadc43e5c1f082f8913b25336d1538b6 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Thu, 23 Jan 2025 18:41:47 +0200 Subject: [PATCH] style: add `make changelog_style` for automatic changelog formatting Added also to `make style`. [no changelog] --- Makefile | 15 ++-- docs/misc/changelog.md | 4 +- tools/{generate-changelog.py => changelog.py} | 70 ++++++++++++++++--- 3 files changed, 69 insertions(+), 20 deletions(-) rename tools/{generate-changelog.py => changelog.py} (76%) diff --git a/Makefile b/Makefile index 122154b151..ba32ffd688 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ C_FILES = $(shell find . -type f -name '*.[ch]' | grep -f ./tools/style.c.inclu style_check: pystyle_check ruststyle_check cstyle_check changelog_check yaml_check docs_summary_check editor_check ## run all style checks -style: pystyle ruststyle cstyle ## apply all code styles (C+Rust+Py) +style: pystyle ruststyle cstyle changelog_style ## apply all code styles (C+Rust+Py+Changelog) pystyle_check: ## run code style check on application sources and tests flake8 --version @@ -52,15 +52,10 @@ pystyle: ## apply code style on application sources and tests make -C python style changelog_check: ## check changelog format - ./tools/generate-changelog.py --check core - ./tools/generate-changelog.py --check core/embed/projects/boardloader - ./tools/generate-changelog.py --check core/embed/projects/bootloader - ./tools/generate-changelog.py --check core/embed/projects/bootloader_ci - ./tools/generate-changelog.py --check core/embed/projects/prodtest - ./tools/generate-changelog.py --check legacy/bootloader - ./tools/generate-changelog.py --check legacy/firmware - ./tools/generate-changelog.py --check legacy/intermediate_fw - ./tools/generate-changelog.py --check python + ./tools/changelog.py check + +changelog_style: ## fix changelog format + ./tools/changelog.py style yaml_check: ## check yaml formatting yamllint . diff --git a/docs/misc/changelog.md b/docs/misc/changelog.md index 35ee39bab0..2ae9fe425d 100644 --- a/docs/misc/changelog.md +++ b/docs/misc/changelog.md @@ -66,12 +66,12 @@ message to exclude that commit from the check. ## Generating changelog at the time of release When it's time to release new version of a repository component the formatted -changelog needs to be generated using the `tools/generate-changelog.py` script. +changelog needs to be generated using the `tools/changelog.py generate` command. It accepts repo subdirectory and the version number as arguments and you can specify the release date if it's different from today's date: ``` -tools/generate-changelog.py --date "20th April 2021" legacy/firmware 1.10.0 +tools/changelog.py generate --date "20th April 2021" legacy/firmware 1.10.0 ``` ## Cherry-picking changes to release branch diff --git a/tools/generate-changelog.py b/tools/changelog.py similarity index 76% rename from tools/generate-changelog.py rename to tools/changelog.py index 151da5cb49..19555793ed 100755 --- a/tools/generate-changelog.py +++ b/tools/changelog.py @@ -7,6 +7,8 @@ import subprocess import click +from typing import Iterator + LINK_RE = re.compile(r"\[#(\d+)\]") ISSUE_URL = "https://github.com/trezor/trezor-firmware/pull/{issue}" @@ -17,6 +19,25 @@ MODELS_RE = re.compile(r"\[([A-Z0-9]{4})(,[A-Z0-9]{4})*\][ ]?") INTERNAL_MODELS = ("T2T1", "T2B1", "T3B1", "T3T1", "D001") INTERNAL_MODELS_SKIP = ("D001",) +ROOT = Path(__file__).parent.parent + +# Source of truth for all managed changelogs in this repository. +# Please extend it when adding a new project with a managed changelog. +KNOWN_PROJECTS = ( + ROOT / "core", + ROOT / "core/embed/projects/boardloader", + ROOT / "core/embed/projects/bootloader", + ROOT / "core/embed/projects/bootloader_ci", + ROOT / "core/embed/projects/prodtest", + ROOT / "legacy/bootloader", + ROOT / "legacy/firmware", + ROOT / "legacy/intermediate_fw", + ROOT / "python", +) + +for project in KNOWN_PROJECTS: + assert project.is_dir(), f"Project {project} does not exist" + IGNORED_FILES = ('.gitignore', '.keep') @@ -118,21 +139,34 @@ def filter_changelog(changelog_file: Path, internal_name: str): destination.write(res) -def check_style(project: Path): - success = True +def _iter_fragments(project: Path) -> Iterator[Path]: fragements_dir = project / ".changelog.d" for fragment in fragements_dir.iterdir(): if fragment.name in IGNORED_FILES: continue + yield fragment + + +def check_fragments_style(project: Path): + success = True + for fragment in _iter_fragments(project): fragment_text = fragment.read_text().rstrip() if not fragment_text.endswith("."): - click.echo(f"Fragment '{fragment}' must end with a period.") + click.echo(f"Changelog '{fragment}' must end with a period.") success = False if not success: - raise click.ClickException("Fragment style check failed.") + raise click.ClickException(f"Changelog style error: {project}") else: - click.echo("Fragment style check passed.") + click.echo(f"Changelog style OK: {project}") + + +def fix_fragments_style(project: Path): + for fragment in _iter_fragments(project): + fragment_text = fragment.read_text().rstrip() + if not fragment_text.endswith("."): + fragment.write_text(fragment_text + ".\n") + click.echo(f"Changelog '{fragment}' style fixed.") def generate_filtered(project: Path, changelog: Path): @@ -145,7 +179,26 @@ def generate_filtered(project: Path, changelog: Path): filter_changelog(changelog, internal_name) -@click.command() +@click.group() +def cli(): + pass + + +@cli.command() +def check(): + """Check the style of all changelog fragments.""" + for project in KNOWN_PROJECTS: + check_fragments_style(project) + + +@cli.command() +def style(): + """Fix the style of all changelog fragments.""" + for project in KNOWN_PROJECTS: + fix_fragments_style(project) + + +@cli.command() @click.argument( "project", type=click.Path(exists=True, dir_okay=True, file_okay=False, resolve_path=True), @@ -160,7 +213,7 @@ def generate_filtered(project: Path, changelog: Path): "--check", is_flag=True, help="Dry run, do not actually create changelog." ) @click.option("--only-models", is_flag=True, help="Only regenerate the model-changelogs from the main one.") -def cli(project, version, date, check, only_models): +def generate(project, version, date, check, only_models): """Generate changelog for given project (core, python, legacy/firmware, legacy/bootloader). @@ -172,7 +225,8 @@ def cli(project, version, date, check, only_models): - Tell git to stage changed files. """ project = Path(project) - check_style(project) + if project not in KNOWN_PROJECTS: + raise click.ClickException(f"Please add '{project}' to `KNOWN_PROJECTS` to be part of our managed changelogs.") changelog = project / "CHANGELOG.md"