Skip to content

Commit 6455912

Browse files
authored
Merge pull request #47 from sommersoft/patch_dryrun
Add Patch Testing Capability
2 parents f50d1c0 + acb5807 commit 6455912

File tree

1 file changed

+44
-19
lines changed

1 file changed

+44
-19
lines changed

adabot/circuitpython_library_patches.py

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@
3535
" This is necessary when needing to use 'apply' flags not available"
3636
" to 'am' (e.g. '--unidiff-zero'). Only available when using '-p'.",
3737
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")
3844

3945
def get_repo_list():
4046
""" Uses adabot.circuitpython_libraries module to get a list of
@@ -51,16 +57,22 @@ def get_repo_list():
5157

5258
return repo_list
5359

54-
def get_patches():
60+
def get_patches(run_local):
5561
""" Returns the list of patch files located in the adabot/patches
5662
directory.
5763
"""
5864
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)
6476

6577
return return_list
6678

@@ -116,7 +128,7 @@ def apply_patch(repo_directory, patch_filepath, repo, patch, flags, use_apply):
116128
return False
117129
return True
118130

119-
def check_patches(repo, patches, flags, use_apply):
131+
def check_patches(repo, patches, flags, use_apply, dry_run):
120132
""" Gather a list of patches from the `adabot/patches` directory
121133
on the adabot repo. Clone the `repo` and run git apply --check
122134
to test wether it requires any of the gathered patches.
@@ -159,20 +171,24 @@ def check_patches(repo, patches, flags, use_apply):
159171
run_apply = True
160172
except sh.ErrorReturnCode_1 as Err:
161173
run_apply = False
162-
if not b"error" in Err.stderr:
174+
if b"error" not in Err.stderr:
163175
skipped += 1
164176
else:
165177
failed += 1
178+
error_str = str(Err.stderr, encoding="utf-8").replace("\n", " ")
179+
error_start = error_str.rfind("error:") + 7
166180
check_errors.append(dict(repo_name=repo["name"],
167-
patch_name=patch, error=Err.stderr))
181+
patch_name=patch, error=error_str[error_start:]))
168182

169183
except sh.ErrorReturnCode as Err:
170184
run_apply = False
171185
failed += 1
186+
error_str = str(Err.stderr, encoding="utf-8").replace("\n", " ")
187+
error_start = error_str.rfind("error:") + 7
172188
check_errors.append(dict(repo_name=repo["name"],
173-
patch_name=patch, error=Err.stderr))
189+
patch_name=patch, error=error_str[error_start:]))
174190

175-
if run_apply:
191+
if run_apply and not dry_run:
176192
result = apply_patch(repo_directory, patch_filepath, repo["name"],
177193
patch, flags, use_apply)
178194
if result:
@@ -183,11 +199,20 @@ def check_patches(repo, patches, flags, use_apply):
183199
return [applied, skipped, failed]
184200

185201
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)
188214
flags = ["--signoff"]
189215

190-
cli_args = cli_parser.parse_args()
191216
if cli_args.list:
192217
print("Available Patches:", run_patches)
193218
sys.exit()
@@ -206,7 +231,6 @@ def check_patches(repo, patches, flags, use_apply):
206231
if cli_args.use_apply:
207232
if not cli_args.patch:
208233
raise RuntimeError("Must be used with a single patch. See help (-h) for usage.")
209-
use_apply = cli_args.use_apply
210234

211235
print(".... Beginning Patch Updates ....")
212236
print(".... Working directory:", working_directory)
@@ -229,7 +253,7 @@ def check_patches(repo, patches, flags, use_apply):
229253
print(".... Running Patch Checks On", len(repos), "Repos ....")
230254

231255
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)
233257
for k in range(3):
234258
stats[k] += results[k]
235259

@@ -240,14 +264,15 @@ def check_patches(repo, patches, flags, use_apply):
240264
print(".... Patch Check Failure Report ....")
241265
if len(check_errors) > 0:
242266
for error in check_errors:
243-
print(">>", error)
267+
print(">> Repo: {0}\tPatch: {1}\n Error: {2}".format(error["repo_name"],
268+
error["patch_name"], error["error"]))
244269
else:
245270
print("No Failures")
246271
print("\n")
247272
print(".... Patch Apply Failure Report ....")
248273
if len(apply_errors) > 0:
249274
for error in apply_errors:
250-
print(">>", error)
275+
print(">> Repo: {0}\tPatch: {1}\n Error: {2}".format(error["repo_name"],
276+
error["patch_name"], error["error"]))
251277
else:
252278
print("No Failures")
253-

0 commit comments

Comments
 (0)