35
35
" This is necessary when needing to use 'apply' flags not available"
36
36
" to 'am' (e.g. '--unidiff-zero'). Only available when using '-p'." ,
37
37
action = "store_true" , dest = "use_apply" )
38
+ cli_parser .add_argument ("--dry-run" , help = "Accomplishes a dry run of patches, without applying"
39
+ " them." , action = "store_true" , dest = "dry_run" )
40
+ cli_parser .add_argument ("--local" , help = "Force use of local patches. This skips verification"
41
+ " of patch files in the adabot GitHub repository. MUST use '--dry-run'"
42
+ " with this argument; this guards against applying unapproved patches." ,
43
+ action = "store_true" , dest = "run_local" )
38
44
39
45
def get_repo_list ():
40
46
""" Uses adabot.circuitpython_libraries module to get a list of
@@ -51,16 +57,22 @@ def get_repo_list():
51
57
52
58
return repo_list
53
59
54
- def get_patches ():
60
+ def get_patches (run_local ):
55
61
""" Returns the list of patch files located in the adabot/patches
56
62
directory.
57
63
"""
58
64
return_list = []
59
- contents = requests .get ("https://api.github.com/repos/adafruit/adabot/contents/patches" )
60
- if contents .ok :
61
- for patch in contents .json ():
62
- patch_name = patch ["name" ]
63
- return_list .append (patch_name )
65
+ if not run_local :
66
+ contents = requests .get ("https://api.github.com/repos/adafruit/adabot/contents/patches" )
67
+ if contents .ok :
68
+ for patch in contents .json ():
69
+ patch_name = patch ["name" ]
70
+ return_list .append (patch_name )
71
+ else :
72
+ contents = os .listdir (patch_directory )
73
+ for file in contents :
74
+ if file .endswith (".patch" ):
75
+ return_list .append (file )
64
76
65
77
return return_list
66
78
@@ -116,7 +128,7 @@ def apply_patch(repo_directory, patch_filepath, repo, patch, flags, use_apply):
116
128
return False
117
129
return True
118
130
119
- def check_patches (repo , patches , flags , use_apply ):
131
+ def check_patches (repo , patches , flags , use_apply , dry_run ):
120
132
""" Gather a list of patches from the `adabot/patches` directory
121
133
on the adabot repo. Clone the `repo` and run git apply --check
122
134
to test wether it requires any of the gathered patches.
@@ -159,20 +171,24 @@ def check_patches(repo, patches, flags, use_apply):
159
171
run_apply = True
160
172
except sh .ErrorReturnCode_1 as Err :
161
173
run_apply = False
162
- if not b"error" in Err .stderr :
174
+ if b"error" not in Err .stderr :
163
175
skipped += 1
164
176
else :
165
177
failed += 1
178
+ error_str = str (Err .stderr , encoding = "utf-8" ).replace ("\n " , " " )
179
+ error_start = error_str .rfind ("error:" ) + 7
166
180
check_errors .append (dict (repo_name = repo ["name" ],
167
- patch_name = patch , error = Err . stderr ))
181
+ patch_name = patch , error = error_str [ error_start :] ))
168
182
169
183
except sh .ErrorReturnCode as Err :
170
184
run_apply = False
171
185
failed += 1
186
+ error_str = str (Err .stderr , encoding = "utf-8" ).replace ("\n " , " " )
187
+ error_start = error_str .rfind ("error:" ) + 7
172
188
check_errors .append (dict (repo_name = repo ["name" ],
173
- patch_name = patch , error = Err . stderr ))
189
+ patch_name = patch , error = error_str [ error_start :] ))
174
190
175
- if run_apply :
191
+ if run_apply and not dry_run :
176
192
result = apply_patch (repo_directory , patch_filepath , repo ["name" ],
177
193
patch , flags , use_apply )
178
194
if result :
@@ -183,11 +199,20 @@ def check_patches(repo, patches, flags, use_apply):
183
199
return [applied , skipped , failed ]
184
200
185
201
if __name__ == "__main__" :
186
-
187
- run_patches = get_patches ()
202
+ cli_args = cli_parser .parse_args ()
203
+ use_apply = cli_args .use_apply
204
+ dry_run = cli_args .dry_run
205
+ run_local = cli_args .run_local
206
+ if run_local :
207
+ if dry_run or cli_args .list :
208
+ pass
209
+ else :
210
+ raise RuntimeError ("'--local' can only be used in conjunction with"
211
+ " '--dry-run' or '--list'." )
212
+
213
+ run_patches = get_patches (run_local )
188
214
flags = ["--signoff" ]
189
215
190
- cli_args = cli_parser .parse_args ()
191
216
if cli_args .list :
192
217
print ("Available Patches:" , run_patches )
193
218
sys .exit ()
@@ -206,7 +231,6 @@ def check_patches(repo, patches, flags, use_apply):
206
231
if cli_args .use_apply :
207
232
if not cli_args .patch :
208
233
raise RuntimeError ("Must be used with a single patch. See help (-h) for usage." )
209
- use_apply = cli_args .use_apply
210
234
211
235
print (".... Beginning Patch Updates ...." )
212
236
print (".... Working directory:" , working_directory )
@@ -229,7 +253,7 @@ def check_patches(repo, patches, flags, use_apply):
229
253
print (".... Running Patch Checks On" , len (repos ), "Repos ...." )
230
254
231
255
for repo in repos :
232
- results = check_patches (repo , run_patches , flags , use_apply )
256
+ results = check_patches (repo , run_patches , flags , use_apply , dry_run )
233
257
for k in range (3 ):
234
258
stats [k ] += results [k ]
235
259
@@ -240,14 +264,15 @@ def check_patches(repo, patches, flags, use_apply):
240
264
print (".... Patch Check Failure Report ...." )
241
265
if len (check_errors ) > 0 :
242
266
for error in check_errors :
243
- print (">>" , error )
267
+ print (">> Repo: {0}\t Patch: {1}\n Error: {2}" .format (error ["repo_name" ],
268
+ error ["patch_name" ], error ["error" ]))
244
269
else :
245
270
print ("No Failures" )
246
271
print ("\n " )
247
272
print (".... Patch Apply Failure Report ...." )
248
273
if len (apply_errors ) > 0 :
249
274
for error in apply_errors :
250
- print (">>" , error )
275
+ print (">> Repo: {0}\t Patch: {1}\n Error: {2}" .format (error ["repo_name" ],
276
+ error ["patch_name" ], error ["error" ]))
251
277
else :
252
278
print ("No Failures" )
253
-
0 commit comments