omegafox/scripts/developer.py
daijro c7d634c668 Makefile & dev script additions
- Add Check Patches & Set Checkpoint in dev UI
- Add make diff to view git diff of Camoufox source repo
2024-07-31 03:57:12 -05:00

155 lines
4.6 KiB
Python

#!/usr/bin/env python3
"""
GUI for managing Camoufox patches.
"""
import os
import contextlib
import easygui
from patch import list_files, patch, run
def into_camoufox_dir():
"""Find and cd to the camoufox-* folder (this is located ..)"""
os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
folders = os.listdir('.')
for folder in folders:
if os.path.isdir(folder) and folder.startswith('camoufox-'):
os.chdir(folder)
break
else:
raise FileNotFoundError('No camoufox-* folder found')
@contextlib.contextmanager
def temp_cd(path):
# Temporarily change to a different working directory
_old_cwd = os.getcwd()
os.chdir(os.path.abspath(path))
try:
yield
finally:
os.chdir(_old_cwd)
def reset_camoufox():
with temp_cd('..'):
run('make clean')
def run_patches(reverse=False):
patch_files = list(list_files('../patches', suffix='*.patch'))
if reverse:
title = "Unpatch files"
else:
title = "Patch files"
selected_patches = easygui.multchoicebox(title, "Patches", patch_files)
if not selected_patches:
return
for patch_file in selected_patches:
patch(patch_file, reverse=reverse)
# GUI Choicebox with options
choices = [
"Reset workspace",
"Check patches",
"Set checkpoint",
"Select patches",
"Reverse patches",
"Find broken patches",
"See current workspace",
"Write workspace to patch",
]
"""
GUI Choicebox
"""
def handle_choice(choice):
match choice:
case "Reset workspace":
reset_camoufox()
easygui.msgbox("Reset completed and bootstrap patches applied.", "Reset Complete")
case "Check patches":
# Produces a list of patches that are applied
apply_dict = {}
for patch_file in list_files('../patches', suffix='*.patch'):
result = os.system(f'git apply --check "{patch_file}" > /dev/null 2>&1')
if result == 0:
apply_dict[patch_file] = 'NOT APPLIED'
else:
apply_dict[patch_file] = 'APPLIED'
easygui.textbox(
"Patching Result",
"Patching Result",
'\n'.join(
sorted(
(f'{v}\t{os.path.basename(k)[:-6]}' for k, v in apply_dict.items()),
reverse=True,
key=lambda x: x[0],
)
),
)
case "Set checkpoint":
with temp_cd('..'):
run('make checkpoint')
easygui.msgbox("Checkpoint set.", "Checkpoint Set")
case "Select patches":
run_patches(reverse=False)
easygui.msgbox("Patching completed.", "Patching Complete")
case "Reverse patches":
run_patches(reverse=True)
easygui.msgbox("Unpatching completed.", "Unpatching Complete")
case "Find broken patches":
reset_camoufox()
broken_patches = []
for patch_file in list_files('../patches', suffix='*.patch'):
cmd = rf'patch -p1 -i "{patch_file}" | tee /dev/stderr | sed -r --quiet \'s/^.*saving rejects to file (.*\.rej)$/\\1/p\''
result = os.popen(cmd).read().strip()
print(result)
if result:
broken_patches.append((patch_file, result))
if not broken_patches:
easygui.msgbox("All patches applied successfully", "Patching Result")
else:
message = "Some patches failed to apply:\n\n"
for patch_file, rejects in broken_patches:
message += f"Patch: {patch_file}\nRejects: {rejects}\n\n"
easygui.textbox("Patching Result", "Failed Patches", message)
case "See current workspace":
result = os.popen('git diff').read()
easygui.textbox("Diff", "Diff", result)
case "Write workspace to patch":
# Open a file dialog to select a file to write the diff to
file_path = easygui.filesavebox(
"Select a file to write the diff to", "Write Diff", filetypes="*.patch"
)
if not file_path:
exit()
run(f'git diff > {file_path}')
easygui.msgbox("Diff written to file", "Diff Written")
case _:
print('No choice selected')
if __name__ == "__main__":
into_camoufox_dir()
while choice := easygui.choicebox("Select an option:", "Camoufox Dev Tools", choices):
handle_choice(choice)