diff --git a/resources/validation.py b/resources/validation.py index 186b0281b..32f3360f1 100644 --- a/resources/validation.py +++ b/resources/validation.py @@ -15,8 +15,10 @@ class PatcherValidation: Primarily for Continuous Integration """ - def __init__(self, global_constants: constants.Constants) -> None: + def __init__(self, global_constants: constants.Constants, verify_unused_files: bool = False) -> None: self.constants: constants.Constants = global_constants + self.verify_unused_files = verify_unused_files + self.active_patchset_files = [] self.constants.validate = True @@ -119,6 +121,8 @@ class PatcherValidation: if not Path(source_file).exists(): logging.info(f"File not found: {source_file}") raise Exception(f"Failed to find {source_file}") + if self.verify_unused_files is True: + self.active_patchset_files.append(source_file) logging.info(f"Validating against Darwin {major_kernel}.{minor_kernel}") if not sys_patch_helpers.SysPatchHelpers(self.constants).generate_patchset_plist(patchset, f"OpenCore-Legacy-Patcher-{major_kernel}.{minor_kernel}.plist", None): @@ -141,6 +145,30 @@ class PatcherValidation: raise Exception("Failed to download Universal-Binaries.dmg") logging.info("Validating Root Patch File integrity") + + if Path(self.constants.payload_path / Path("Universal-Binaries_overlay")).exists(): + subprocess.run( + [ + "/bin/rm", "-f", Path(self.constants.payload_path / Path("Universal-Binaries_overlay")) + ], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) + if Path(self.constants.payload_path / Path("Universal-Binaries")).exists(): + output = subprocess.run( + [ + "/usr/bin/hdiutil", "detach", Path(self.constants.payload_path / Path("Universal-Binaries")), + "-force" + ], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) + + if output.returncode != 0: + logging.info("Failed to unmount Universal-Binaries.dmg") + logging.info(f"Output: {output.stdout.decode()}") + logging.info(f"Return Code: {output.returncode}") + + raise Exception("Failed to unmount Universal-Binaries.dmg") + output = subprocess.run( [ "/usr/bin/hdiutil", "attach", "-noverify", f"{self.constants.payload_local_binaries_root_path_dmg}", @@ -165,10 +193,14 @@ class PatcherValidation: for supported_os in [os_data.os_data.big_sur, os_data.os_data.monterey, os_data.os_data.ventura, os_data.os_data.sonoma]: for i in range(0, 10): self._validate_root_patch_files(supported_os, i) + logging.info("Validating SNB Board ID patcher") self.constants.computer.reported_board_id = "Mac-7BA5B2DFE22DDD8C" sys_patch_helpers.SysPatchHelpers(self.constants).snb_board_id_patch(self.constants.payload_local_binaries_root_path) + if self.verify_unused_files is True: + self._find_unused_files() + # unmount the dmg output = subprocess.run( [ @@ -193,6 +225,50 @@ class PatcherValidation: ) + def _find_unused_files(self) -> None: + """ + Find PatcherSupportPkg files that are unused by the patcher + + Note this function is extremely slow, so only manually run when needed + """ + if self.active_patchset_files == []: + return + + unused_files = [] + + for file in Path(self.constants.payload_local_binaries_root_path).rglob("*"): + if file.is_dir(): + continue + + relative_path = Path(file).relative_to(self.constants.payload_local_binaries_root_path) + + if relative_path.name == ".DS_Store": + continue + + if str(relative_path) in [".fseventsd/fseventsd-uuid", ".signed"]: + continue + + is_used = False + for used_file in self.active_patchset_files: + used_relative_path = Path(used_file).relative_to(self.constants.payload_local_binaries_root_path) + if str(relative_path) in str(used_relative_path): + is_used = True + break + if str(used_relative_path) in str(relative_path): + is_used = True + break + + if is_used: + continue + + unused_files.append(relative_path) + + if len(unused_files) > 0: + logging.info("Unused files found:") + for file in unused_files: + logging.info(f" {file}") + + def _validate_configs(self) -> None: """ Validates build modules