lyricdownloader/generate_notes.py

96 lines
5.1 KiB
Python

#!/usr/bin/env python3
"""
This module generates a draft_notes.md to be attached to a Gitea release and
a CHANGELOG.md to be committed into the repo.
It is the python version of this https://stackoverflow.com/a/46033999
"""
import subprocess
import argparse
def full():
with open("CHANGELOG.md", "w+") as fw:
try:
# Get all the tags sorted in decreasing order (the -creatordate is what sorts in decreasing order)
tags = subprocess.check_output(["git", "tag", "--sort=-creatordate"], text=True)
tags = [tag for tag in tags.split("\n") if tag]
# Get the remote url
remote_url = subprocess.check_output(["git", "remote", "get-url", "origin"], text=True)
# Remove the first occurence of the word git starting from the end of the string
remote_url = remote_url[0:remote_url.rfind(".git")]
previous_tag = ""
if len(tags) == 1:
# Extract the date of the commit
tag_date = subprocess.check_output(["git", "log", "-1", f"--pretty=format:'%ad'", "--date=short", f"{tags[0]}"], text=True)
tag_date = tag_date.replace("'", "")
# Get each commit of a tag formatted
formatted_lines = subprocess.check_output(["git", "log", f"{tags[0]}", f'--pretty=format:"* %s [View]({remote_url}/commits/%H)"'], text=True)
if formatted_lines:
fw.write(f"## {tags[0]} ({tag_date})\n\n")
# Remove merge commits or Changelog commits
lines = "\n".join([line.replace("\"", "") for line in formatted_lines.split("\n") if all(["merge" not in line.lower(), "changelog.md" not in line.lower()])])
fw.write(lines)
fw.write("\n\n")
else:
for tag in tags:
if previous_tag:
# Extract the date of the commit
tag_date = subprocess.check_output(["git", "log", "-1", f"--pretty=format:'%ad'", "--date=short", f"{tag}"], text=True)
tag_date = tag_date.replace("'", "")
# Get each commit of a tag formatted
formatted_lines = subprocess.check_output(["git", "log", f"{tag}...{previous_tag}", f'--pretty=format:"* %s [View]({remote_url}/commits/%H)"'], text=True)
if formatted_lines:
fw.write(f"## {tag} ({tag_date})\n\n")
# Remove merge commits or Changelog commits
lines = "\n".join([line.replace("\"", "") for line in formatted_lines.split("\n") if all(["merge" not in line.lower(), "changelog.md" not in line.lower()])])
fw.write(lines)
fw.write("\n\n")
previous_tag = tag
except subprocess.CalledProcessError as e:
print(f"Command failed with return code {e.returncode}")
def draft():
with open("draft_notes.md", "w+") as fw:
try:
# Get the remote url
remote_url = subprocess.check_output(["git", "remote", "get-url", "origin"], text=True)
# Remove the first occurence of the word git starting from the end of the string
remote_url = remote_url[0:remote_url.rfind(".git")]
# Get the current and previous tags
tags = subprocess.check_output(["git", "tag", "--sort=creatordate"], text=True)
tags = [tag for tag in tags.split("\n") if tag]
if len(tags) > 1:
tags.reverse()
current_tag, previous_tag, *_ = tags
formatted_lines = subprocess.check_output(["git", "log", f"{current_tag}...{previous_tag}", f'--pretty=format:"* %s"'], text=True)
lines = "\n".join([line.replace("\"", "") for line in formatted_lines.split("\n") if all(["merge" not in line.lower(), "changelog.md" not in line.lower()])])
fw.write(lines)
fw.write("\n\n")
fw.write(f"Compare between recent changes: [{previous_tag[1:]}...{current_tag[1:]}]({remote_url}/compare/{previous_tag}...{current_tag})")
else:
# first tag
formatted_lines = subprocess.check_output(["git", "log", f'--pretty=format:"* %s"'], text=True)
lines = "\n".join([line.replace("\"", "") for line in formatted_lines.split("\n") if all(["merge" not in line.lower(), "changelog.md" not in line.lower()])])
fw.write(lines)
except subprocess.CalledProcessError as e:
print(f"Command failed with return code {e.returncode}")
def run():
parser = argparse.ArgumentParser(description='Generate changelogs....')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--full", help="Generate full changelog", action="store_true")
group.add_argument("--draft", help="Generate notes with tag", action="store_true")
args = parser.parse_args()
if args.full:
full()
elif args.draft:
draft()
if __name__ == "__main__":
run()