| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- #!/usr/bin/env python3
- import sys
- import os
- from typing import List, Any
- import yaml
- import argparse
- import datetime
- MAX_ENTRIES = 500
- HEADER_RE = r"(?::cl:|🆑) *\r?\n(.+)$"
- ENTRY_RE = r"^ *[*-]? *(\S[^\n\r]+)\r?$"
- CATEGORY_MAIN = "Main"
- # From https://stackoverflow.com/a/37958106/4678631
- class NoDatesSafeLoader(yaml.SafeLoader):
- @classmethod
- def remove_implicit_resolver(cls, tag_to_remove):
- if not 'yaml_implicit_resolvers' in cls.__dict__:
- cls.yaml_implicit_resolvers = cls.yaml_implicit_resolvers.copy()
- for first_letter, mappings in cls.yaml_implicit_resolvers.items():
- cls.yaml_implicit_resolvers[first_letter] = [(tag, regexp)
- for tag, regexp in mappings
- if tag != tag_to_remove]
- # Hrm yes let's make the fucking default of our serialization library to PARSE ISO-8601
- # but then output garbage when re-serializing.
- NoDatesSafeLoader.remove_implicit_resolver('tag:yaml.org,2002:timestamp')
- def main():
- parser = argparse.ArgumentParser()
- parser.add_argument("changelog_file")
- parser.add_argument("parts_dir")
- parser.add_argument("--category", default=CATEGORY_MAIN)
- args = parser.parse_args()
- category = args.category
- with open(args.changelog_file, "r", encoding="utf-8-sig") as f:
- current_data = yaml.load(f, Loader=NoDatesSafeLoader)
- entries_list: List[Any]
- if current_data is None:
- entries_list = []
- else:
- entries_list = current_data["Entries"]
- max_id = max(map(lambda e: e["id"], entries_list), default=0)
- for partname in os.listdir(args.parts_dir):
- if not partname.endswith(".yml"):
- continue
- partpath = os.path.join(args.parts_dir, partname)
- print(partpath)
- with open(partpath, "r", encoding="utf-8-sig") as f:
- partyaml = yaml.load(f, Loader=NoDatesSafeLoader)
- part_category = partyaml.get("category", CATEGORY_MAIN)
- if part_category != category:
- print(f"Skipping: wrong category ({part_category} vs {category})")
- continue
- author = partyaml["author"]
- time = partyaml.get(
- "time", datetime.datetime.now(datetime.timezone.utc).isoformat()
- )
- changes = partyaml["changes"]
- url = partyaml.get("url")
- if not isinstance(changes, list):
- changes = [changes]
- if len(changes):
- # Don't add empty changelog entries...
- max_id += 1
- new_id = max_id
- entries_list.append(
- {"author": author, "time": time, "changes": changes, "id": new_id, "url": url}
- )
- os.remove(partpath)
- print(f"Have {len(entries_list)} changelog entries")
- entries_list.sort(key=lambda e: e["id"])
- overflow = len(entries_list) - MAX_ENTRIES
- if overflow > 0:
- print(f"Removing {overflow} old entries.")
- entries_list = entries_list[overflow:]
- new_data = {"Entries": entries_list}
- for key, value in current_data.items():
- if key != "Entries":
- new_data[key] = value
- with open(args.changelog_file, "w", encoding="utf-8-sig") as f:
- yaml.safe_dump(new_data, f)
- main()
|