Source code for pestifer.util.readme_to_changelog_with_dates
# Author: ChatGPT 4o
"""
This script was written to do a one-time conversion of version notes in README.md to a CHANGELOG.md format.
It extracts version information from Git tags and PyPI releases, then formats it into a changelog.
"""
import subprocess
import requests
import re
from pathlib import Path
[docs]
def get_git_tag_dates():
"""
Get the creation dates of Git tags.
This function retrieves the tags from the Git repository, sorts them by creation date,
and returns a dictionary mapping tag names to their creation dates.
The dates are formatted as 'YYYY-MM-DD'.
"""
result = subprocess.run(
["git", "for-each-ref", "--sort=creatordate",
"--format=%(refname:strip=2) %(creatordate:short)", "refs/tags"],
capture_output=True, text=True
)
tag_date_map = {}
for line in result.stdout.strip().splitlines():
if " " in line:
tag, date = line.strip().split(maxsplit=1)
tag_date_map[tag.lstrip("v")] = date
return tag_date_map
[docs]
def get_pypi_release_dates(package_name: str) -> dict:
"""
Get the release dates of a package from PyPI.
This function queries the PyPI JSON API for the specified package,
retrieves the release dates for each version, and returns a dictionary
mapping version numbers to their release dates.
The dates are formatted as 'YYYY-MM-DD'.
"""
url = f"https://pypi.org/pypi/{package_name}/json"#!/usr/bin/env python3
response = requests.get(url)
response.raise_for_status()
data = response.json()
version_dates = {}
for version, files in data.get("releases", {}).items():
if files:
upload_time = files[0].get("upload_time_iso_8601")
if upload_time:
version_dates[version] = upload_time[:10] # YYYY-MM-DD
return version_dates
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Convert README.md version notes to CHANGELOG.md using Git and PyPI")
parser.add_argument("readme", type=Path, help="Path to README.md")
parser.add_argument("--output", type=Path, default=Path("CHANGELOG.md"), help="Path to output CHANGELOG.md")
args = parser.parse_args()
tag_dates = get_git_tag_dates()
pypi_dates = get_pypi_release_dates("pestifer")
combined_dates = {**pypi_dates, **tag_dates} # Git takes precedence
changelog = extract_changelog_from_readme(args.readme, combined_dates)
args.output.write_text(changelog)
print(f"✅ CHANGELOG.md written to: {args.output.resolve()}")