2024-04-07 08:32:16 +00:00
|
|
|
#!/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 = ""
|
|
|
|
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)
|
2024-04-20 15:25:23 +00:00
|
|
|
tags = [tag for tag in tags.split("\n") if tag]
|
|
|
|
if len(tags) > 1:
|
2024-04-20 11:17:45 +00:00
|
|
|
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)
|
2024-04-07 08:32:16 +00:00
|
|
|
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()
|