forked from celery/celery
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchangelog_formatter.py
executable file
·130 lines (102 loc) · 2.96 KB
/
changelog_formatter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env python3
import re
import sys
import click
import pyperclip
from colorama import Fore, init
# Initialize colorama for color support in terminal
init(autoreset=True)
# Regular expression pattern to match the required lines
PATTERN = re.compile(r"^\*\s*(.*?)\s+by\s+@[\w-]+\s+in\s+https://github\.com/[\w-]+/[\w-]+/pull/(\d+)")
def read_changes_file(filename):
try:
with open(filename) as f:
return f.readlines()
except FileNotFoundError:
print(f"Error: {filename} file not found.")
sys.exit(1)
def read_from_clipboard():
text = pyperclip.paste()
return text.splitlines()
def process_line(line):
line = line.strip()
# Skip lines containing '[pre-commit.ci]'
if "[pre-commit.ci]" in line:
return None
# Skip lines starting with '## What's Changed'
if line.startswith("## What's Changed"):
return None
# Stop processing if '## New Contributors' is encountered
if line.startswith("## New Contributors"):
return "STOP_PROCESSING"
# Skip lines that don't start with '* '
if not line.startswith("* "):
return None
match = PATTERN.match(line)
if match:
description, pr_number = match.groups()
return f"- {description} (#{pr_number})"
return None
@click.command()
@click.option(
"--source",
"-s",
type=click.Path(exists=True),
help="Source file to read from. If not provided, reads from clipboard.",
)
@click.option(
"--dest",
"-d",
type=click.File("w"),
default="-",
help="Destination file to write to. Defaults to standard output.",
)
@click.option(
"--clipboard",
"-c",
is_flag=True,
help="Read input from clipboard explicitly.",
)
def main(source, dest, clipboard):
# Determine the source of input
if clipboard or (not source and not sys.stdin.isatty()):
# Read from clipboard
lines = read_from_clipboard()
elif source:
# Read from specified file
lines = read_changes_file(source)
else:
# Default: read from clipboard
lines = read_from_clipboard()
output_lines = []
for line in lines:
output_line = process_line(line)
if output_line == "STOP_PROCESSING":
break
if output_line:
output_lines.append(output_line)
output_text = "\n".join(output_lines)
# Prepare the header
version = "x.y.z"
underline = "=" * len(version)
header = f"""
.. _version-{version}:
{version}
{underline}
:release-date: <YYYY-MM-DD>
:release-by: <FULL NAME>
What's Changed
~~~~~~~~~~~~~~
"""
# Combine header and output
final_output = header + output_text
# Write output to destination
if dest.name == "<stdout>":
print(Fore.GREEN + "Copy the following text to Changelog.rst:")
print(Fore.YELLOW + header)
print(Fore.CYAN + output_text)
else:
dest.write(final_output + "\n")
dest.close()
if __name__ == "__main__":
main()