mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-06-20 14:10:51 +10:00
Toolchain: Use docstrings
This commit is contained in:
+135
-72
@@ -1,14 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
# This script's main purpose is to handle the following:
|
# Generate stand alone application for OpenCore-Patcher
|
||||||
# - Download PatcherSupportPkg resources
|
# Copyright (C) 2022-2023 - Mykola Grymalyuk
|
||||||
# - Convert payloads directory into DMG (GUI only)
|
|
||||||
# - Build Binary via Pyinstaller
|
|
||||||
# - Add Launcher.sh (TUI only)
|
|
||||||
# - Patch 'LC_VERSION_MIN_MACOSX' to OS X 10.10
|
|
||||||
# - Add commit data to Info.plist
|
|
||||||
|
|
||||||
# Copyright (C) 2022 - Mykola Grymalyuk
|
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import time
|
import time
|
||||||
@@ -21,24 +14,48 @@ import sys
|
|||||||
|
|
||||||
from resources import constants
|
from resources import constants
|
||||||
|
|
||||||
|
|
||||||
class create_binary:
|
class create_binary:
|
||||||
|
"""
|
||||||
|
Library for creating OpenCore-Patcher application
|
||||||
|
|
||||||
|
This script's main purpose is to handle the following:
|
||||||
|
- Download external dependancies (ex. PatcherSupportPkg)
|
||||||
|
- Convert payloads directory into DMG
|
||||||
|
- Build Binary via Pyinstaller
|
||||||
|
- Patch 'LC_VERSION_MIN_MACOSX' to OS X 10.10
|
||||||
|
- Add commit data to Info.plist
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
start = time.time()
|
start = time.time()
|
||||||
print("- Starting build script")
|
print("- Starting build script")
|
||||||
self.set_cwd()
|
|
||||||
self.args = self.parse_arguments()
|
|
||||||
|
|
||||||
self.preflight_processes()
|
self.args = self._parse_arguments()
|
||||||
self.build_binary()
|
|
||||||
self.postflight_processes()
|
self._set_cwd()
|
||||||
|
|
||||||
|
self._preflight_processes()
|
||||||
|
self._build_binary()
|
||||||
|
self._postflight_processes()
|
||||||
print(f"- Build script completed in {str(round(time.time() - start, 2))} seconds")
|
print(f"- Build script completed in {str(round(time.time() - start, 2))} seconds")
|
||||||
|
|
||||||
def set_cwd(self):
|
|
||||||
|
def _set_cwd(self):
|
||||||
|
"""
|
||||||
|
Initialize current working directory to parent of this script
|
||||||
|
"""
|
||||||
|
|
||||||
os.chdir(Path(__file__).resolve().parent)
|
os.chdir(Path(__file__).resolve().parent)
|
||||||
print(f"- Current Working Directory: \n\t{os.getcwd()}")
|
print(f"- Current Working Directory: \n\t{os.getcwd()}")
|
||||||
|
|
||||||
def parse_arguments(self):
|
|
||||||
|
def _parse_arguments(self):
|
||||||
|
"""
|
||||||
|
Parse arguments passed to script
|
||||||
|
"""
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Builds OpenCore-Patcher binary')
|
parser = argparse.ArgumentParser(description='Builds OpenCore-Patcher binary')
|
||||||
parser.add_argument('--branch', type=str, help='Git branch name')
|
parser.add_argument('--branch', type=str, help='Git branch name')
|
||||||
parser.add_argument('--commit', type=str, help='Git commit URL')
|
parser.add_argument('--commit', type=str, help='Git commit URL')
|
||||||
@@ -47,7 +64,12 @@ class create_binary:
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
return args
|
return args
|
||||||
|
|
||||||
def setup_pathing(self):
|
|
||||||
|
def _setup_pathing(self):
|
||||||
|
"""
|
||||||
|
Initialize pathing for pyinstaller
|
||||||
|
"""
|
||||||
|
|
||||||
python_path = sys.executable
|
python_path = sys.executable
|
||||||
python_binary = python_path.split("/")[-1]
|
python_binary = python_path.split("/")[-1]
|
||||||
python_bin_dir = python_path.strip(python_binary)
|
python_bin_dir = python_path.strip(python_binary)
|
||||||
@@ -69,21 +91,36 @@ class create_binary:
|
|||||||
|
|
||||||
self.pyinstaller_path = pyinstaller_path
|
self.pyinstaller_path = pyinstaller_path
|
||||||
|
|
||||||
def preflight_processes(self):
|
|
||||||
|
def _preflight_processes(self):
|
||||||
|
"""
|
||||||
|
Start preflight processes
|
||||||
|
"""
|
||||||
|
|
||||||
print("- Starting preflight processes")
|
print("- Starting preflight processes")
|
||||||
self.setup_pathing()
|
self._setup_pathing()
|
||||||
self.delete_extra_binaries()
|
self._delete_extra_binaries()
|
||||||
self.download_resources()
|
self._download_resources()
|
||||||
self.generate_payloads_dmg()
|
self._generate_payloads_dmg()
|
||||||
|
|
||||||
|
|
||||||
|
def _postflight_processes(self):
|
||||||
|
"""
|
||||||
|
Start postflight processes
|
||||||
|
"""
|
||||||
|
|
||||||
def postflight_processes(self):
|
|
||||||
print("- Starting postflight processes")
|
print("- Starting postflight processes")
|
||||||
self.patch_load_command()
|
self._patch_load_command()
|
||||||
self.add_commit_data()
|
self._add_commit_data()
|
||||||
self.post_flight_cleanup()
|
self._post_flight_cleanup()
|
||||||
self.mini_validate()
|
self._mini_validate()
|
||||||
|
|
||||||
|
|
||||||
|
def _build_binary(self):
|
||||||
|
"""
|
||||||
|
Build binary via pyinstaller
|
||||||
|
"""
|
||||||
|
|
||||||
def build_binary(self):
|
|
||||||
if Path(f"./dist/OpenCore-Patcher.app").exists():
|
if Path(f"./dist/OpenCore-Patcher.app").exists():
|
||||||
print("- Found OpenCore-Patcher.app, removing...")
|
print("- Found OpenCore-Patcher.app, removing...")
|
||||||
rm_output = subprocess.run(
|
rm_output = subprocess.run(
|
||||||
@@ -105,7 +142,12 @@ class create_binary:
|
|||||||
print(build_result.stderr.decode('utf-8'))
|
print(build_result.stderr.decode('utf-8'))
|
||||||
raise Exception("Build failed")
|
raise Exception("Build failed")
|
||||||
|
|
||||||
def delete_extra_binaries(self):
|
|
||||||
|
def _delete_extra_binaries(self):
|
||||||
|
"""
|
||||||
|
Delete extra binaries from payloads directory
|
||||||
|
"""
|
||||||
|
|
||||||
delete_files = [
|
delete_files = [
|
||||||
"AutoPkg-Assets.pkg",
|
"AutoPkg-Assets.pkg",
|
||||||
"AutoPkg-Assets.pkg.zip",
|
"AutoPkg-Assets.pkg.zip",
|
||||||
@@ -113,6 +155,7 @@ class create_binary:
|
|||||||
"InstallAssistant.pkg.integrityDataV1",
|
"InstallAssistant.pkg.integrityDataV1",
|
||||||
"KDK.dmg",
|
"KDK.dmg",
|
||||||
]
|
]
|
||||||
|
|
||||||
print("- Deleting extra binaries...")
|
print("- Deleting extra binaries...")
|
||||||
for file in Path("payloads").glob(pattern="*"):
|
for file in Path("payloads").glob(pattern="*"):
|
||||||
if file.name in delete_files or file.name.startswith("OpenCore-Legacy-Patcher"):
|
if file.name in delete_files or file.name.startswith("OpenCore-Legacy-Patcher"):
|
||||||
@@ -125,7 +168,12 @@ class create_binary:
|
|||||||
print(f" - Deleting {file}")
|
print(f" - Deleting {file}")
|
||||||
subprocess.run(["rm", "-rf", file])
|
subprocess.run(["rm", "-rf", file])
|
||||||
|
|
||||||
def download_resources(self):
|
|
||||||
|
def _download_resources(self):
|
||||||
|
"""
|
||||||
|
Download required dependencies
|
||||||
|
"""
|
||||||
|
|
||||||
patcher_support_pkg_version = constants.Constants().patcher_support_pkg_version
|
patcher_support_pkg_version = constants.Constants().patcher_support_pkg_version
|
||||||
required_resources = [
|
required_resources = [
|
||||||
"Universal-Binaries.zip"
|
"Universal-Binaries.zip"
|
||||||
@@ -172,21 +220,29 @@ class create_binary:
|
|||||||
print(mv_output.stderr.decode('utf-8'))
|
print(mv_output.stderr.decode('utf-8'))
|
||||||
raise Exception("Move failed")
|
raise Exception("Move failed")
|
||||||
|
|
||||||
def generate_payloads_dmg(self):
|
|
||||||
|
def _generate_payloads_dmg(self):
|
||||||
|
"""
|
||||||
|
Generate disk image containing all payloads
|
||||||
|
Disk image will be password protected due to issues with
|
||||||
|
Apple's notarization system and inclusion of kernel extensions
|
||||||
|
"""
|
||||||
|
|
||||||
if Path("./payloads.dmg").exists():
|
if Path("./payloads.dmg").exists():
|
||||||
if self.args.reset_binaries:
|
if not self.args.reset_binaries:
|
||||||
print(" - Removing old payloads.dmg")
|
|
||||||
rm_output = subprocess.run(
|
|
||||||
["rm", "-rf", "./payloads.dmg"],
|
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
|
||||||
)
|
|
||||||
if rm_output.returncode != 0:
|
|
||||||
print("- Remove failed")
|
|
||||||
print(rm_output.stderr.decode('utf-8'))
|
|
||||||
raise Exception("Remove failed")
|
|
||||||
else:
|
|
||||||
print(" - payloads.dmg already exists, skipping creation")
|
print(" - payloads.dmg already exists, skipping creation")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
print(" - Removing old payloads.dmg")
|
||||||
|
rm_output = subprocess.run(
|
||||||
|
["rm", "-rf", "./payloads.dmg"],
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
|
)
|
||||||
|
if rm_output.returncode != 0:
|
||||||
|
print("- Remove failed")
|
||||||
|
print(rm_output.stderr.decode('utf-8'))
|
||||||
|
raise Exception("Remove failed")
|
||||||
|
|
||||||
print(" - Generating DMG...")
|
print(" - Generating DMG...")
|
||||||
dmg_output = subprocess.run([
|
dmg_output = subprocess.run([
|
||||||
'hdiutil', 'create', './payloads.dmg',
|
'hdiutil', 'create', './payloads.dmg',
|
||||||
@@ -204,7 +260,12 @@ class create_binary:
|
|||||||
|
|
||||||
print(" - DMG generation complete")
|
print(" - DMG generation complete")
|
||||||
|
|
||||||
def add_commit_data(self):
|
|
||||||
|
def _add_commit_data(self):
|
||||||
|
"""
|
||||||
|
Add commit data to Info.plist
|
||||||
|
"""
|
||||||
|
|
||||||
if not self.args.branch and not self.args.commit and not self.args.commit_date:
|
if not self.args.branch and not self.args.commit and not self.args.commit_date:
|
||||||
print(" - No commit data provided, adding source info")
|
print(" - No commit data provided, adding source info")
|
||||||
branch = "Built from source"
|
branch = "Built from source"
|
||||||
@@ -224,20 +285,25 @@ class create_binary:
|
|||||||
}
|
}
|
||||||
plistlib.dump(plist, Path(plist_path).open("wb"), sort_keys=True)
|
plistlib.dump(plist, Path(plist_path).open("wb"), sort_keys=True)
|
||||||
|
|
||||||
def patch_load_command(self):
|
|
||||||
# Patches LC_VERSION_MIN_MACOSX in Load Command to report 10.10
|
def _patch_load_command(self):
|
||||||
#
|
"""
|
||||||
# By default Pyinstaller will create binaries supporting 10.13+
|
Patch LC_VERSION_MIN_MACOSX in Load Command to report 10.10
|
||||||
# However this limitation is entirely arbitrary for our libraries
|
|
||||||
# and instead we're able to support 10.10 without issues.
|
By default Pyinstaller will create binaries supporting 10.13+
|
||||||
#
|
However this limitation is entirely arbitrary for our libraries
|
||||||
# To verify set version:
|
and instead we're able to support 10.10 without issues.
|
||||||
# otool -l ./dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher
|
|
||||||
#
|
To verify set version:
|
||||||
# cmd LC_VERSION_MIN_MACOSX
|
otool -l ./dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher
|
||||||
# cmdsize 16
|
|
||||||
# version 10.13
|
cmd LC_VERSION_MIN_MACOSX
|
||||||
# sdk 10.9
|
cmdsize 16
|
||||||
|
version 10.13
|
||||||
|
sdk 10.9
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
print(" - Patching LC_VERSION_MIN_MACOSX")
|
print(" - Patching LC_VERSION_MIN_MACOSX")
|
||||||
path = './dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher'
|
path = './dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher'
|
||||||
find = b'\x00\x0D\x0A\x00' # 10.13 (0xA0D)
|
find = b'\x00\x0D\x0A\x00' # 10.13 (0xA0D)
|
||||||
@@ -248,19 +314,12 @@ class create_binary:
|
|||||||
with open(path, 'wb') as f:
|
with open(path, 'wb') as f:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
|
|
||||||
def move_launcher(self):
|
|
||||||
print(" - Adding TUI launcher")
|
|
||||||
mv_output = subprocess.run(
|
|
||||||
["cp", "./payloads/launcher.sh", "./dist/OpenCore-Patcher.app/Contents/MacOS/Launcher"],
|
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
|
||||||
)
|
|
||||||
if mv_output.returncode != 0:
|
|
||||||
print(" - Move failed")
|
|
||||||
print(mv_output.stderr.decode('utf-8'))
|
|
||||||
raise Exception("Move failed")
|
|
||||||
|
|
||||||
def post_flight_cleanup(self):
|
def _post_flight_cleanup(self):
|
||||||
# Remove ./dist/OpenCore-Patcher
|
"""
|
||||||
|
Post flight cleanup
|
||||||
|
"""
|
||||||
|
|
||||||
path = "./dist/OpenCore-Patcher"
|
path = "./dist/OpenCore-Patcher"
|
||||||
print(f" - Removing {path}")
|
print(f" - Removing {path}")
|
||||||
rm_output = subprocess.run(
|
rm_output = subprocess.run(
|
||||||
@@ -272,9 +331,12 @@ class create_binary:
|
|||||||
print(rm_output.stderr.decode('utf-8'))
|
print(rm_output.stderr.decode('utf-8'))
|
||||||
raise Exception(f"Remove failed: {path}")
|
raise Exception(f"Remove failed: {path}")
|
||||||
|
|
||||||
def mini_validate(self):
|
|
||||||
# Ensure binary can start
|
def _mini_validate(self):
|
||||||
# Only build a single config, TUI CI will do in-depth validation
|
"""
|
||||||
|
Validate generated binary
|
||||||
|
"""
|
||||||
|
|
||||||
print(" - Validating binary")
|
print(" - Validating binary")
|
||||||
validate_output = subprocess.run(
|
validate_output = subprocess.run(
|
||||||
["./dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher", "--build", "--model", "MacPro3,1"],
|
["./dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher", "--build", "--model", "MacPro3,1"],
|
||||||
@@ -285,5 +347,6 @@ class create_binary:
|
|||||||
print(validate_output.stderr.decode('utf-8'))
|
print(validate_output.stderr.decode('utf-8'))
|
||||||
raise Exception("Validation failed")
|
raise Exception("Validation failed")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
create_binary()
|
create_binary()
|
||||||
Reference in New Issue
Block a user