Source code for batools.changelog

# Released under the MIT License. See LICENSE for details.
#
"""Generates a pretty html changelog from our markdown."""

import os
import subprocess


[docs] def get_version_changelog(version: str, projroot: str) -> list[str]: """Get changelog text for a given version from CHANGELOG.md.""" import re from efro.error import CleanError changelog_path = os.path.join(projroot, 'CHANGELOG.md') if not os.path.exists(changelog_path): raise CleanError(f'CHANGELOG.md not found at {changelog_path}') with open(changelog_path, 'r', encoding='utf-8') as infile: changelog_content = infile.read() # Regex to find the section for the given version pattern = rf'^###\s+{re.escape(version)}\b.*?\n(.*?)(?=^###\s+|\Z)' match = re.search(pattern, changelog_content, re.DOTALL | re.MULTILINE) if not match: raise CleanError(f'Changelog entry for version {version} not found.') section_text = match.group(1).rstrip() # Convert changelog section into a list of bullet entries, # preserving internal newlines and indentation. lines = section_text.splitlines() entries: list[str] = [] current_entry: list[str] = [] for line in lines: if line.startswith('- '): # Save previous entry if present if current_entry: entries.append('\n'.join(current_entry).rstrip()) current_entry = [] # Strip "- " but preserve rest exactly current_entry.append(line[2:]) else: # Continuation line (including indentation or blank lines) if current_entry: current_entry.append(line) # Add final entry if current_entry: entries.append('\n'.join(current_entry).rstrip()) changelog_list = entries return changelog_list
[docs] def generate(projroot: str) -> None: """Main script entry point.""" # Make sure we start from root dir (one above this script). os.chdir(projroot) out_path = 'build/changelog.html' out_path_tmp = out_path + '.md' # Do some filtering of our raw changelog. with open('CHANGELOG.md', encoding='utf-8') as infile: lines = infile.read().splitlines() # Strip out anything marked internal. lines = [ line for line in lines if not line.strip().startswith('- (internal)') ] with open(out_path_tmp, 'w', encoding='utf-8') as outfile: outfile.write('\n'.join(lines)) subprocess.run( f'pandoc -f markdown {out_path_tmp} > {out_path}', shell=True, check=True, ) print(f'Generated changelog at \'{out_path}\'.') os.unlink(out_path_tmp)
# Docs-generation hack; import some stuff that we likely only forward-declared # in our actual source code so that docs tools can find it. from typing import (Coroutine, Any, Literal, Callable, Generator, Awaitable, Sequence, Self) import asyncio from concurrent.futures import Future from pathlib import Path from enum import Enum