1import os
2import re
3import requests
4import sys
5import textwrap
6
7from html import escape
8
9def clean_line(line: str, in_code_fence: bool) -> str:
10 line = re.sub(r"\(\[(#\d+)\]\([\w|\d\:|\/|\.|\-|_]*\)\)", lambda match: f"[{match.group(1)}]", line)
11 line = re.sub(r"\[(#\d+)\]\([\w|\d\:|\/|\.|\-|_]*\)", lambda match: f"[{match.group(1)}]", line)
12 if not in_code_fence:
13 line = line.strip()
14
15 return escape(line)
16
17
18def convert_body(body: str) -> str:
19 formatted = ""
20
21 in_code_fence = False
22 in_list = False
23 for line in body.splitlines():
24 line = clean_line(line, in_code_fence)
25 if not line:
26 continue
27 if re.search(r'\[[\w|\d|:|\/|\.|\-|_]*\]\([\w|\d|:|\/|\.|\-|_]*\)', line):
28 continue
29 line = re.sub(r"(?<!\`)`([^`\n]+)`(?!`)", lambda match: f"<code>{match.group(1)}</code>", line)
30
31 contains_code_fence = bool(re.search(r"```", line))
32 is_list = bool(re.search(r"^-\s*", line))
33
34 if in_list and not is_list:
35 formatted += "</ul>\n"
36 if (not in_code_fence and contains_code_fence) or (not in_list and is_list):
37 formatted += "<ul>\n"
38 in_list = is_list
39 in_code_fence = contains_code_fence != in_code_fence
40
41 if is_list:
42 line = re.sub(r"^-\s*", "", line)
43 line = f" <li>{line}</li>"
44 elif in_code_fence or contains_code_fence:
45 line = f" <li><code> {line}</code></li>"
46 else:
47 line = f"<p>{line}</p>"
48 formatted += f"{line}\n"
49
50 if (not in_code_fence and contains_code_fence):
51 formatted += "</ul>\n"
52 if in_code_fence or in_list:
53 formatted += "</ul>\n"
54 return formatted
55
56def get_release_info(tag: str):
57 url = f"https://api.github.com/repos/zed-industries/zed/releases/tags/{tag}"
58 response = requests.get(url)
59 if response.status_code == 200:
60 return response.json()
61 else:
62 print(f"Failed to fetch release info for tag '{tag}'. Status code: {response.status_code}")
63 quit()
64
65
66if __name__ == "__main__":
67 os.chdir(sys.path[0])
68
69 if len(sys.argv) != 3:
70 print("Usage: python convert-release-notes.py <tag> <channel>")
71 sys.exit(1)
72
73 tag = sys.argv[1]
74 channel = sys.argv[2]
75
76 release_info = get_release_info(tag)
77 body = convert_body(release_info["body"])
78 version = tag.removeprefix("v").removesuffix("-pre")
79 date = release_info["published_at"]
80
81 release_info_str = f"<release version=\"{version}\" date=\"{date}\">\n"
82 release_info_str += f" <description>\n"
83 release_info_str += textwrap.indent(body, " " * 8)
84 release_info_str += f" </description>\n"
85 release_info_str += f" <url>https://github.com/zed-industries/zed/releases/tag/{tag}</url>\n"
86 release_info_str += "</release>\n"
87
88 channel_releases_file = f"../../crates/zed/resources/flatpak/release-info/{channel}"
89 with open(channel_releases_file) as f:
90 old_release_info = f.read()
91 with open(channel_releases_file, "w") as f:
92 f.write(textwrap.indent(release_info_str, " " * 8) + old_release_info)
93 print(f"Added release notes from {tag} to '{channel_releases_file}'")