3232from easybuild .base .generaloption import simple_option
3333from easybuild .base .rest import RestClient
3434from easybuild .tools .build_log import EasyBuildError
35- from easybuild .tools .github import GITHUB_API_URL , HTTP_STATUS_OK , GITHUB_EASYCONFIGS_REPO
35+ from easybuild .tools .github import GITHUB_API_URL , HTTP_STATUS_OK , GITHUB_EASYCONFIGS_REPO , GITHUB_EASYBLOCKS_REPO
3636from easybuild .tools .github import GITHUB_EB_MAIN , fetch_github_token
3737from easybuild .tools .options import EasyBuildOptions
38+ from easybuild .tools .py2vs3 import HTTPError , URLError
3839
3940HTTP_DELETE_OK = 204
4041
@@ -49,6 +50,7 @@ def main():
4950 'closed-pr' : ('Delete all gists from closed pull-requests' , None , 'store_true' , True , 'p' ),
5051 'all' : ('Delete all gists from Easybuild ' , None , 'store_true' , False , 'a' ),
5152 'orphans' : ('Delete all gists without a pull-request' , None , 'store_true' , False , 'o' ),
53+ 'dry-run' : ("Only show which gists will be deleted but don't actually delete them" , None , 'store_true' , False ),
5254 }
5355
5456 go = simple_option (options )
@@ -58,6 +60,7 @@ def main():
5860 raise EasyBuildError ("Please tell me what to do?" )
5961
6062 if go .options .github_user is None :
63+ EasyBuildOptions .DEFAULT_LOGLEVEL = None # Don't overwrite log level
6164 eb_go = EasyBuildOptions (envvar_prefix = 'EASYBUILD' , go_args = [])
6265 username = eb_go .options .github_user
6366 log .debug ("Fetch github username from easybuild, found: %s" , username )
@@ -88,51 +91,88 @@ def main():
8891 break
8992
9093 log .info ("Found %s gists" , len (all_gists ))
91- regex = re .compile (r"(EasyBuild test report|EasyBuild log for failed build).*?(?:PR #(?P<PR>[0-9]+))?\)?$" )
94+ re_eb_gist = re .compile (r"(EasyBuild test report|EasyBuild log for failed build)(.*?)$" )
95+ re_pr_nr = re .compile (r"(EB )?PR #([0-9]+)" )
9296
9397 pr_cache = {}
9498 num_deleted = 0
9599
96100 for gist in all_gists :
97101 if not gist ["description" ]:
98102 continue
99- re_pr_num = regex .search (gist ["description" ])
100- delete_gist = False
101-
102- if re_pr_num :
103- log .debug ("Found a Easybuild gist (id=%s)" , gist ["id" ])
104- pr_num = re_pr_num .group ("PR" )
105- if go .options .all :
106- delete_gist = True
107- elif pr_num and go .options .closed_pr :
108- log .debug ("Found Easybuild test report for PR #%s" , pr_num )
109-
110- if pr_num not in pr_cache :
111- status , pr = gh .repos [GITHUB_EB_MAIN ][GITHUB_EASYCONFIGS_REPO ].pulls [pr_num ].get ()
103+
104+ gist_match = re_eb_gist .search (gist ["description" ])
105+
106+ if not gist_match :
107+ log .debug ("Found a non-Easybuild gist (id=%s)" , gist ["id" ])
108+ continue
109+
110+ log .debug ("Found an Easybuild gist (id=%s)" , gist ["id" ])
111+
112+ pr_data = gist_match .group (2 )
113+
114+ pr_nrs_matches = re_pr_nr .findall (pr_data )
115+
116+ if go .options .all :
117+ delete_gist = True
118+ elif not pr_nrs_matches :
119+ log .debug ("Found Easybuild test report without PR (id=%s)." , gist ["id" ])
120+ delete_gist = go .options .orphans
121+ elif go .options .closed_pr :
122+ # All PRs must be closed
123+ delete_gist = True
124+ for pr_nr_match in pr_nrs_matches :
125+ eb_str , pr_num = pr_nr_match
126+ if eb_str or GITHUB_EASYBLOCKS_REPO in pr_data :
127+ repo = GITHUB_EASYBLOCKS_REPO
128+ else :
129+ repo = GITHUB_EASYCONFIGS_REPO
130+
131+ cache_key = "%s-%s" % (repo , pr_num )
132+
133+ if cache_key not in pr_cache :
134+ try :
135+ status , pr = gh .repos [GITHUB_EB_MAIN ][repo ].pulls [pr_num ].get ()
136+ except HTTPError as e :
137+ status , pr = e .code , e .msg
112138 if status != HTTP_STATUS_OK :
113139 raise EasyBuildError ("Failed to get pull-request #%s: error code %s, message = %s" ,
114140 pr_num , status , pr )
115- pr_cache [pr_num ] = pr ["state" ]
116-
117- if pr_cache [pr_num ] == "closed" :
118- log .debug ("Found report from closed PR #%s (id=%s)" , pr_num , gist ["id" ])
119- delete_gist = True
120-
121- elif not pr_num and go .options .orphans :
122- log .debug ("Found Easybuild test report without PR (id=%s)" , gist ["id" ])
123- delete_gist = True
141+ pr_cache [cache_key ] = pr ["state" ]
142+
143+ if pr_cache [cache_key ] == "closed" :
144+ log .debug ("Found report from closed %s PR #%s (id=%s)" , repo , pr_num , gist ["id" ])
145+ elif delete_gist :
146+ if len (pr_nrs_matches ) > 1 :
147+ log .debug ("Found at least 1 PR, that is not closed yet: %s/%s (id=%s)" ,
148+ repo , pr_num , gist ["id" ])
149+ delete_gist = False
150+ else :
151+ delete_gist = True
124152
125153 if delete_gist :
126- status , del_gist = gh .gists [gist ["id" ]].delete ()
154+ if go .options .dry_run :
155+ log .info ("DRY-RUN: Delete gist with id=%s" , gist ["id" ])
156+ num_deleted += 1
157+ continue
158+ try :
159+ status , del_gist = gh .gists [gist ["id" ]].delete ()
160+ except HTTPError as e :
161+ status , del_gist = e .code , e .msg
162+ except URLError as e :
163+ status , del_gist = None , e .reason
127164
128165 if status != HTTP_DELETE_OK :
129- raise EasyBuildError ("Unable to remove gist (id=%s): error code %s, message = %s" ,
130- gist ["id" ], status , del_gist )
166+ log . warning ("Unable to remove gist (id=%s): error code %s, message = %s" ,
167+ gist ["id" ], status , del_gist )
131168 else :
132- log .info ("Delete gist with id=%s" , gist ["id" ])
169+ log .info ("Deleted gist with id=%s" , gist ["id" ])
133170 num_deleted += 1
134171
135- log .info ("Deleted %s gists" , num_deleted )
172+ if go .options .dry_run :
173+ log .info ("DRY-RUN: Would delete %s gists" , num_deleted )
174+ else :
175+ log .info ("Deleted %s gists" , num_deleted )
136176
137177
138178if __name__ == '__main__' :
0 commit comments