Loupe/build-aux/generate-news.py

142 lines
3.5 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
import os
import os.path
import sys
release_names = []
BASE_DIR = 'news.d'
OUT_FILE = 'NEWS'
HEADING = ''
def main():
changelog = Changelog(BASE_DIR, HEADING)
changelog.load()
with open(OUT_FILE, 'w') as f:
f.write(changelog.format())
class Release:
def __init__(self, name):
self.name = name
self.released = "Unreleased"
self.security = []
self.added = []
self.fixed = []
self.changed = []
self.removed = []
self.deprecated = []
def add(self, entry: os.DirEntry):
with open(entry) as f:
content = f.read().strip()
if entry.name == "released":
self.released = content
return
entry_type = entry.name.split('-')[0]
match entry_type:
case 'security':
store = self.security
case 'added':
store = self.added
case 'fixed':
store = self.fixed
case 'changed':
store = self.changed
case 'removed':
store = self.removed
case 'deprecated':
store = self.deprecated
case _:
print(f'WARNING: Unknown entry type "{entry_type}" in "{self.name}"', file=sys.stderr)
return;
with open(entry) as f:
store.append(content)
def sections(self):
categories = []
if self.security:
categories.append(("Security", self.security))
if self.added:
categories.append(("Added", self.added))
if self.fixed:
categories.append(("Fixed", self.fixed))
if self.changed:
categories.append(("Changed", self.changed))
if self.removed:
categories.append(("Removed", self.removed))
if self.deprecated:
categories.append(("Deprecated", self.deprecated))
return categories
def format(self):
heading =f"{self.name} ({self.released})"
s = f"## {heading}\n"
for (section, items) in self.sections():
s += f"\n### {section}\n\n"
for item in sorted(items):
s += f"- {item}\n"
return s
def __lt__(self, other):
return self.name < other.name
class Changelog:
def __init__(self, path, heading):
self.path = path
self.heading = heading
self.previous = ""
self.releases = []
def load(self):
with os.scandir(BASE_DIR) as it:
for entry in it:
if entry.is_dir():
release_names.append(entry.name)
elif entry.is_file() and entry.name == "previous":
with open(entry.path) as f:
self.previous = f.read()
for release_name in release_names:
release = Release(release_name)
self.add(release)
with os.scandir(os.path.join(BASE_DIR, release_name)) as it:
for entry in it:
if entry.is_file():
release.add(entry)
def add(self, release: Release):
self.releases.append(release)
def format(self):
s = ""
if self.heading:
s += f'# {self.heading}\n'
for release in reversed(sorted(self.releases)):
if s != "":
s += "\n"
s += release.format()
if self.previous:
s += '\n'
s += self.previous
return s
main()