Skip to content

Commit

Permalink
patch.py: Try multi-processing
Browse files Browse the repository at this point in the history
  • Loading branch information
khronokernel committed Aug 26, 2024
1 parent 031eeb7 commit c6f2cc9
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 23 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/patch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ on:
branches:
- main

concurrency:
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}

jobs:
build:
name: CI - Patch latest Sequoia metallib's
Expand Down Expand Up @@ -39,7 +43,7 @@ jobs:

- name: Patch metal libraries
if: steps.fetch.outputs.BACKUP_FOLDER != ''
run: python3 metallib.py --patch ${{ steps.fetch.outputs.BACKUP_FOLDER }}
run: python3 metallib.py --patch ${{ steps.fetch.outputs.BACKUP_FOLDER }} --multiprocessing

- name: Build sys_patch_dict.py
if: steps.fetch.outputs.BACKUP_FOLDER != ''
Expand Down
7 changes: 4 additions & 3 deletions metal_libraries/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def fetch(input: str = "/", output: str = None) -> str:
return MetallibFetch(input, output).backup()


def patch(input: str = "/") -> None:
def patch(input: str = "/", multiprocessing: bool = False) -> None:
"""
Patches all .metallib files in a given path
Expand All @@ -77,7 +77,7 @@ def patch(input: str = "/") -> None:
- None
"""
if Path(input).is_dir():
MetallibPatch().patch_all(input)
MetallibPatch().patch_all(input, multiprocessing)
else:
MetallibPatch().patch(input, input)

Expand Down Expand Up @@ -119,6 +119,7 @@ def main() -> None:
parser.add_argument("-e", "--extract", type=str, help="Extract the system volume from an IPSW.")
parser.add_argument("-f", "--fetch", type=str, help="Fetch Metal libraries from the system volume.")
parser.add_argument("-p", "--patch", type=str, help="Patch Metal libraries.")
parser.add_argument("-m", "--multiprocessing", action="store_true", help="Enable multiprocessing for patching.")
parser.add_argument("-b", "--build-sys-patch", type=str, help="Build a system patch dictionary.")
parser.add_argument("-z", "--build-pkg", type=str, help="Build a macOS package.")
parser.add_argument("-c", "--continuous-integration", action="store_true", help="Run in continuous integration mode.")
Expand All @@ -132,7 +133,7 @@ def main() -> None:
elif args.fetch:
print(fetch(args.fetch))
elif args.patch:
patch(args.patch)
patch(args.patch, args.multiprocessing)
elif args.build_sys_patch:
build_sys_patch(args.build_sys_patch, args.continuous_integration)
elif args.build_pkg:
Expand Down
53 changes: 34 additions & 19 deletions metal_libraries/metallib/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import struct
import tempfile
import subprocess
import multiprocessing

from pathlib import Path
from typing import Optional
Expand Down Expand Up @@ -358,24 +359,38 @@ def _attempt_to_resolve_parent(self, file: Path) -> str:
return parent_file.name


def patch_all(self, input: str) -> None:
def _patch_all_process_individual_file(self, file: Path) -> None:
"""
patch_all()'s multiprocessing helper
"""
for file in Path(input).rglob("**/*.metallib"):
input = file
output = file.with_suffix(".PATCHED")
input_parent = self._attempt_to_resolve_parent(file)
print(f"{'-' * 80}")
print(f"Patching: {input_parent}'s {input.name}")
self.patch(input, output)
if output.exists():
result = subprocess.run(["/bin/mv", output, input], capture_output=True, text=True)
if result.returncode != 0:
log(result)
raise Exception(f"Failed to move {output} to {input}")
else:
# remove the input file if the output file does not exist
result = subprocess.run(["/bin/rm", input], capture_output=True, text=True)
if result.returncode != 0:
log(result)
raise Exception(f"Failed to remove {input}")
input = file
output = file.with_suffix(".PATCHED")
input_parent = self._attempt_to_resolve_parent(file)
print(f"{'-' * 80}")
print(f"Patching: {input_parent}'s {input.name}")
self.patch(input, output)
if output.exists():
result = subprocess.run(["/bin/mv", output, input], capture_output=True, text=True)
if result.returncode != 0:
log(result)
raise Exception(f"Failed to move {output} to {input}")
else:
# remove the input file if the output file does not exist
result = subprocess.run(["/bin/rm", input], capture_output=True, text=True)
if result.returncode != 0:
log(result)
raise Exception(f"Failed to remove {input}")


def patch_all(self, input: str, use_multiprocessing: bool = False) -> None:
"""
Patch all .metallib files in the given directory
"""
if use_multiprocessing is True:
files = list(Path(input).rglob("**/*.metallib"))
with multiprocessing.Pool() as pool:
# Use the pool to process files in parallel
pool.starmap(self._patch_all_process_individual_file, [(file,) for file in files])
else:
for file in Path(input).rglob("**/*.metallib"):
self._patch_all_process_individual_file(file)

0 comments on commit c6f2cc9

Please sign in to comment.