@@ -17,25 +17,38 @@ def organise_prs(prs):
1717 prs_merged = []
1818 # collect the time of merged PRs
1919 merged_at = []
20- # other PRs, open, closed and not merged
21- prs_other = []
20+ # simply closed
21+ prs_closed = []
22+ closed_updated_at = []
23+ # open PRs
24+ prs_open = []
25+ open_updated_at = []
2226
2327 for pr in prs :
2428 if not pr ['merged_at' ]:
25- # that has not been merged
26- prs_other .append (pr )
27- continue
29+ if pr ['state' ] == 'open' :
30+ prs_open .append (pr )
31+ open_updated_at .append (pr ['updated_at' ])
32+ continue
33+ if pr ['state' ] == 'closed' :
34+ prs_closed .append (pr )
35+ closed_updated_at .append (pr ['updated_at' ])
36+ continue
2837 # get the PR itself and the merged timestamp
2938 prs_merged .append (pr )
3039 merged_at .append (pr ['merged_at' ])
3140
3241 # sort the merged PRs by their merged timestamp
3342 prs_merged = [pr for _ , pr in sorted (zip (merged_at , prs_merged ))]
43+ prs_closed = [pr for _ , pr in sorted (zip (closed_updated_at , prs_closed ))]
44+ prs_open = [pr for _ , pr in sorted (zip (open_updated_at , prs_open ))]
3445
35- return prs_merged , prs_other
46+ return {'merged' : prs_merged ,
47+ 'closed' : prs_closed ,
48+ 'open' : prs_open }
3649
3750
38- def get_prs (owner , repo , request_labels , pr_state , per_page = 50 , start_page = 1 , pages = 1 ):
51+ def get_prs (owner , repo , request_labels , pr_state = None , per_page = 50 , start_page = 1 , pages = 1 ):
3952 """
4053 Get PRs according to some selection
4154 """
@@ -44,7 +57,8 @@ def get_prs(owner, repo, request_labels, pr_state, per_page=50, start_page=1, pa
4457
4558 has_error = False
4659 for page in range (start_page , pages + 1 ):
47- url = f'https://api.github.com/repos/{ owner } /{ repo } /pulls?state={ pr_state } &page={ page } &per_page={ per_page } '
60+ pr_state = f'state={ pr_state } &' if pr_state else 'state=all&'
61+ url = f'https://api.github.com/repos/{ owner } /{ repo } /pulls?{ pr_state } page={ page } &per_page={ per_page } '
4862
4963 # Send GET request to GitHub API
5064 response = requests .get (url )
@@ -73,7 +87,7 @@ def get_prs(owner, repo, request_labels, pr_state, per_page=50, start_page=1, pa
7387 break
7488
7589 if has_error :
76- return None , None
90+ return None
7791
7892 # organise PRs into different lists (merged and others)
7993 return organise_prs (prs_return )
@@ -115,59 +129,61 @@ def separate_labels_request_accept(labels, accept_suffix=None):
115129 return labels_request , labels_accept
116130
117131
118- def make_report (prs_merged , prs_other , repo , labels_request , label_accept_suffix , outfile ):
132+ def make_report (all_prs , repo , labels_request , label_accept_suffix , outfile = None ):
119133 """
120134 Make a report
121135
122136 The report consists of one table per label which will be written to a text file.
123137 """
124138 # common header for each single table
125- common_header = '| Requestor | Package | PR | PR title | Merged at | Data or MC |\n | --- | --- | --- | --- | --- | --- |\n '
126- rows_per_label = {label : [] for label in labels_request }
139+ common_header = '| Requestor | Package | PR | PR title | State | Merged at | Data or MC |\n | --- | --- | --- | --- | --- | --- | --- |\n '
140+
141+ if not outfile :
142+ outfile = f'o2dpg_pr_report_{ repo } .md'
127143
128144 with open (outfile , 'w' ) as f :
129145
130- f .write (f'Merged PRs: { len (prs_merged )} \n Other closed PRs: { len (prs_other )} \n Labels: { ", " .join (labels_request )} \n \n ' )
131- f .write ('# List PRs from oldest to recent (merged)\n ' )
146+ f .write (f'# List PRs for { repo } (from oldest to recent)\n ' )
132147
133148 # first put the merged PRs
134- for pr in prs_merged :
135- mc_data = []
136- # collect the labels for which table this PR should be taken into account
137- labels_take = []
138-
139- for label in pr ['labels' ]:
140- label_name = label ['name' ]
141- if label_name .lower () in ('mc' , 'data' ):
142- # get assigned MC or DATA label if this PR has it
143- mc_data .append (label ['name' ])
144- if label_name in labels_request and (not label_accept_suffix or f'{ label_name } -{ label_accept_suffix } ' not in pr ['labels' ]):
145- # check if that label is one that flags a request. If at the same time there is also the corresponding accepted label, don't take this PR into account for the report.
146- labels_take .append (label_name )
147-
148- if not labels_take :
149- # no labels of interest
150- continue
149+ for key , prs in all_prs .items ():
151150
152- # if no specific MC or DATA label, assume valid for both
153- mc_data = ',' .join (mc_data ) if mc_data else 'MC,DATA'
154- for label in labels_take :
155- rows_per_label [label ].append (f'| { pr ["user" ]["login" ]} | { repo } | [PR]({ pr ["html_url" ]} ) | { pr ["title" ]} | { pr ["merged_at" ]} | { mc_data } |\n ' )
151+ rows_per_label = {label : [] for label in labels_request }
156152
157- for label , rows in rows_per_label .items ():
158- if not rows :
159- # nothing to add here
160- continue
161- f .write (f'\n ==> START label { label } <==\n ' )
162- f .write (common_header )
163- for row in rows :
164- f .write (row )
165- f .write (f'==> END label { label } <==\n ' )
153+ f .write (f'\n \n ## PRs in state { key } ' )
154+ for pr in prs :
155+ mc_data = []
156+ # collect the labels for which table this PR should be taken into account
157+ labels_take = []
158+
159+ for label in pr ['labels' ]:
160+ label_name = label ['name' ]
161+ if label_name .lower () in ('mc' , 'data' ):
162+ # get assigned MC or DATA label if this PR has it
163+ mc_data .append (label ['name' ])
164+ if label_name in labels_request and (not label_accept_suffix or f'{ label_name } -{ label_accept_suffix } ' not in pr ['labels' ]):
165+ # check if that label is one that flags a request. If at the same time there is also the corresponding accepted label, don't take this PR into account for the report.
166+ labels_take .append (label_name )
167+
168+ if not labels_take :
169+ # no labels of interest
170+ continue
166171
167- # add all the other commits
168- f .write ('\n # Other PRs (not merged)\n ' )
169- for pr in prs_other :
170- f .write (f'| { pr ["user" ]["login" ]} | { repo } | [PR]({ pr ["html_url" ]} ) | { pr ["title" ]} | not merged | { ", " .join (labels_take )} | { mc_data } |\n ' )
172+ # if no specific MC or DATA label, assume valid for both
173+ mc_data = ',' .join (mc_data ) if mc_data else 'MC,DATA'
174+ merged_at = pr ['merged_at' ] or 'not merged'
175+ state = pr ['state' ]
176+ for label in labels_take :
177+ rows_per_label [label ].append (f'| { pr ["user" ]["login" ]} | { repo } | [PR]({ pr ["html_url" ]} ) | { pr ["title" ]} | { state } | { merged_at } | { mc_data } |\n ' )
178+
179+ for label , rows in rows_per_label .items ():
180+ if not rows :
181+ # nothing to add here
182+ continue
183+ f .write (f'\n \n ### For label { label } \n \n ' )
184+ f .write (common_header )
185+ for row in rows :
186+ f .write (row )
171187
172188 print (f"==> Report written to { outfile } " )
173189
@@ -177,11 +193,11 @@ def make_report(prs_merged, prs_other, repo, labels_request, label_accept_suffix
177193 parser = argparse .ArgumentParser (description = 'Retrieve closed pull requests with a specific label from a GitHub repository' )
178194 parser .add_argument ('--owner' , help = 'GitHub repository owner' , default = 'AliceO2Group' )
179195 parser .add_argument ('--repo' , required = True , help = 'GitHub repository name, e.g. O2DPG or AliceO2' )
180- parser .add_argument ('--pr-state' , dest = 'pr_state' , default = 'closed' , help = 'The state of the PR' )
181- parser .add_argument ('--output' , default = 'o2dpg_pr_report.txt ' )
182- parser .add_argument ('--per-page' , dest = 'per_page' , default = 50 , help = 'How many results per page' )
196+ parser .add_argument ('--pr-state' , dest = 'pr_state' , help = 'The state of the PR' )
197+ parser .add_argument ('--output' , help = 'name of the output file where the report will be written ' )
198+ parser .add_argument ('--per-page' , dest = 'per_page' , default = 100 , help = 'How many results per page' )
183199 parser .add_argument ('--start-page' , dest = 'start_page' , type = int , default = 1 , help = 'Start on this page' )
184- parser .add_argument ('--pages' , type = int , default = 1 , help = 'Number of pages' )
200+ parser .add_argument ('--pages' , type = int , default = 5 , help = 'Number of pages' )
185201 parser .add_argument ('--label-regex' , dest = 'label_regex' , help = 'Provide a regular expression to decide which labels to fetch.' , default = '^async-\w+' )
186202 parser .add_argument ('--label-accepted-suffix' , dest = 'label_accepted_suffix' , help = 'Provide a regular expression to decide which labels to fetch.' , default = 'accept' )
187203 parser .add_argument ('--include-accepted' , action = 'store_true' , help = 'By default, only PRs are fetched where at least one label has no "<label>-accepted" label' )
@@ -193,11 +209,11 @@ def make_report(prs_merged, prs_other, repo, labels_request, label_accept_suffix
193209 labels_request , _ = separate_labels_request_accept (labels , args .label_accepted_suffix )
194210
195211 # Retrieve closed pull requests with the specified label, split into merged and other (closed) PRs
196- prs_merged , prs_other = get_prs (args .owner , args .repo , labels_request , args .pr_state , args .per_page , args .start_page , args .pages )
197- if prs_merged is None :
198- print ('ERROR: There was a problem fetching the info .' )
199- sys .exit (1 )
212+ prs = get_prs (args .owner , args .repo , labels_request , args .pr_state , args .per_page , args .start_page , args .pages )
213+ if not prs :
214+ print ('==> There are no PRs to report .' )
215+ sys .exit (0 )
200216
201- make_report (prs_merged , prs_other , args .repo , labels_request , args .label_accepted_suffix , args .output )
217+ make_report (prs , args .repo , labels_request , args .label_accepted_suffix , args .output )
202218
203219 sys .exit (0 )
0 commit comments