Skip to content

Commit 8bc68c6

Browse files
committed
refactor: convert into python package
Signed-off-by: Sefa Eyeoglu <[email protected]>
1 parent 5cb65bb commit 8bc68c6

File tree

13 files changed

+200
-171
lines changed

13 files changed

+200
-171
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
__pycache__/
2+
13
.direnv/
24
.pre-commit-config.yaml
35

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# changelog-generator
2+
3+
tbd

changelog_generator/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Prism Launcher changelog-generator main package"""
Lines changed: 54 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
from github import Github
22
from github.Label import Label
33
from github.PullRequest import PullRequest
4+
from github.Repository import Repository
5+
46
from typing import List
57
import re
8+
import os
9+
import argparse
10+
11+
from .ghutil import find_milestone_by_name, get_prs
12+
from .util import pr_link, author_link, human_list
613

7-
REPO = "PrismLauncher/PrismLauncher"
8-
MILESTONE = "8.0"
9-
TOKEN = os.environ["GITHUB_TOKEN"]
1014

1115
LABEL_PREFIX = "changelog:"
1216
MERGED_CATEGORY = "merged"
@@ -20,24 +24,6 @@
2024
]
2125

2226

23-
def pr_link(pr: PullRequest):
24-
return f"[#{pr.number}](https://github.com/{REPO}/pull/{pr.number})"
25-
26-
27-
def author_link(author: str):
28-
return f"[@{author}](https://github.com/{author})"
29-
30-
31-
def human_list(x: List[str]):
32-
if len(x) < 1:
33-
return "WTF??"
34-
elif len(x) == 1:
35-
return x[0]
36-
y = ", ".join(x[:-1])
37-
y += f" and {x[-1]}"
38-
return y
39-
40-
4127
entries = []
4228

4329

@@ -46,6 +32,9 @@ def __init__(self, prs: List[PullRequest], category: str):
4632
self.prs = prs
4733
self.category = category
4834

35+
def merge(self, other: Change):
36+
this.prs += change.prs
37+
4938
def pr(self):
5039
return self.prs[0]
5140

@@ -87,27 +76,38 @@ def categorize_pr(pr: PullRequest):
8776
return Change([pr], category)
8877

8978

90-
if __name__ == "__main__":
91-
output = []
79+
def merge_child_changes(children: List[Change], parents: List[Change]):
80+
for change in merged_changes:
81+
m = re.match(PARENT_PATTERN, change.pr().body)
82+
83+
assert m, f"'{change}' does not define a parent"
84+
85+
parent_number = int(m.group(1))
9286

93-
g = Github(TOKEN)
87+
found_parent = False
88+
for other_change in top_level_changes:
89+
if other_change.number() == parent_number:
90+
other_change.merge(change)
91+
found_parent = True
92+
break
93+
assert (
94+
found_parent
95+
), f"'{change}' parent (#{parent_number}) was not found in this milestone"
9496

95-
repo = g.get_repo(REPO)
9697

97-
release_milestone = None
98+
def generate(repo_name: str, milestone: str, token: str):
99+
g = Github(token)
98100

99-
for milestone in repo.get_milestones():
100-
if milestone.title == MILESTONE:
101-
release_milestone = milestone
102-
break
101+
repo = g.get_repo(repo_name)
103102

104-
issues = repo.get_issues(milestone=release_milestone, state="all")
105-
prs = map(
106-
lambda issue: issue.as_pull_request(),
107-
[*filter(lambda issue: issue.pull_request, issues)],
108-
)
109-
merged_prs = [*filter(lambda pr: pr.merged, prs)]
110-
changes = [*map(categorize_pr, merged_prs)]
103+
release_milestone = find_milestone_by_name(repo, milestone)
104+
105+
assert (
106+
release_milestone is not None
107+
), f"Milestone {milestone} not found in repository {repo.url}"
108+
109+
prs = get_prs(repo, milestone=release_milestone, state="all")
110+
changes = [*map(categorize_pr, prs)]
111111

112112
merged_changes = [
113113
*filter(lambda change: change.category == MERGED_CATEGORY, changes)
@@ -116,24 +116,7 @@ def categorize_pr(pr: PullRequest):
116116
*filter(lambda change: change.category != MERGED_CATEGORY, changes)
117117
]
118118

119-
for change in merged_changes:
120-
m = re.match(PARENT_PATTERN, change.pr().body)
121-
122-
if m is not None:
123-
parent_number = int(m.group(1))
124-
125-
found_parent = False
126-
for other_change in top_level_changes:
127-
if other_change.number() == parent_number:
128-
other_change.prs += change.prs
129-
found_parent = True
130-
break
131-
if not found_parent:
132-
print(
133-
f"'{change}' parent (#{parent_number}) was not found in this milestone"
134-
)
135-
else:
136-
print(f"'{change}' does not define a parent")
119+
merge_child_changes(merged_changes, top_level_changes)
137120

138121
final_changes = sorted(top_level_changes, key=lambda x: x.title())
139122
print("---")
@@ -147,3 +130,19 @@ def categorize_pr(pr: PullRequest):
147130
print(change.changelog_entry())
148131

149132
print()
133+
134+
135+
def main():
136+
parser = argparse.ArgumentParser()
137+
parser.add_argument("repo")
138+
parser.add_argument("milestone")
139+
140+
args = parser.parse_args()
141+
142+
token = os.environ["GITHUB_TOKEN"]
143+
144+
generate(args.repo, args.milestone, token)
145+
146+
147+
if __name__ == "__main__":
148+
main()

changelog_generator/ghutil.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from typing import Generator, List
2+
3+
from github.Milestone import Milestone
4+
from github.PullRequest import PullRequest
5+
from github.Repository import Repository
6+
7+
8+
def find_milestone_by_name(repo: Repository, milestone_name: str) -> Milestone:
9+
for milestone in repo.get_milestones():
10+
if milestone.title == milestone_name:
11+
return milestone
12+
return None
13+
14+
15+
def get_prs(
16+
repo: Repository, only_merged=True, **kwargs
17+
) -> Generator[PullRequest, None, None]:
18+
issues = repo.get_issues(**kwargs)
19+
prs: List[PullRequest] = []
20+
21+
for issue in issues:
22+
if issue.pull_request:
23+
pr = issue.as_pull_request()
24+
if not only_merged or pr.merged:
25+
yield pr

changelog_generator/util.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from typing import Generator, List
2+
3+
from github.PullRequest import PullRequest
4+
5+
6+
def pr_link(pr: PullRequest, repo_path: str = "PrismLauncher/PrismLauncher"):
7+
return f"[#{pr.number}](https://github.com/{repo_path}/pull/{pr.number})"
8+
9+
10+
def author_link(author: str):
11+
return f"[@{author}](https://github.com/{author})"
12+
13+
14+
def human_list(x: List[str]):
15+
if len(x) < 1:
16+
return "WTF??"
17+
elif len(x) == 1:
18+
return x[0]
19+
y = ", ".join(x[:-1])
20+
y += f" and {x[-1]}"
21+
return y

misc/backports.py

Lines changed: 0 additions & 47 deletions
This file was deleted.

misc/generate.py

Lines changed: 0 additions & 61 deletions
This file was deleted.

nix/default.nix

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,26 @@
1-
{...}: {
1+
{
2+
inputs,
3+
self,
4+
...
5+
}: {
26
imports = [
37
./dev.nix
8+
./distribution.nix
49
];
510

11+
_module.args = {
12+
# User-friendly version number.
13+
version = builtins.substring 0 8 self.lastModifiedDate;
14+
};
15+
16+
perSystem = {system, ...}: {
17+
# Nixpkgs instantiated for supported systems with our overlay.
18+
_module.args.pkgs = import inputs.nixpkgs {
19+
inherit system;
20+
overlays = [self.overlays.default];
21+
};
22+
};
23+
624
systems = [
725
"x86_64-linux"
826
"aarch64-linux"

nix/derivation.nix

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
lib,
3+
buildPythonApplication,
4+
poetry-core,
5+
pygithub,
6+
# flake
7+
self,
8+
version,
9+
}: let
10+
inherit (lib.sources) cleanSource;
11+
in
12+
buildPythonApplication {
13+
pname = "changelog-generator";
14+
inherit version;
15+
format = "pyproject";
16+
17+
src = cleanSource self;
18+
19+
nativeBuildInputs = [poetry-core];
20+
21+
propagatedBuildInputs = [pygithub];
22+
23+
pythonImportsCheck = ["changelog_generator"];
24+
25+
meta = with lib; {
26+
description = "Prism Launcher changelog generator";
27+
homepage = "https://github.com/PrismLauncher/changelog-generator";
28+
license = licenses.agpl3Only;
29+
maintainers = with maintainers; [Scrumplex];
30+
};
31+
}

0 commit comments

Comments
 (0)