forked from dortania/OpenCore-Legacy-Patcher
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
952ac0d
commit e8233c3
Showing
11 changed files
with
664 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#!/usr/bin/env python3 | ||
""" | ||
Build-Suite.command: Generate OpenCore-Patcher.app and OpenCore-Patcher.pkg | ||
""" | ||
|
||
import os | ||
import time | ||
import argparse | ||
|
||
from pathlib import Path | ||
|
||
from ci_tooling.build_module import ( | ||
application, | ||
disk_images, | ||
package, | ||
sign_notarize | ||
) | ||
|
||
|
||
def main() -> None: | ||
""" | ||
Parse Command Line Arguments | ||
""" | ||
|
||
parser = argparse.ArgumentParser(description="Build OpenCore Legacy Patcher Suite") | ||
|
||
# Code Signing Parameters | ||
# - Application Signing Identity | ||
# - Installer Signing Identity | ||
parser.add_argument("--application-signing-identity", type=str, help="Application Signing Identity") | ||
parser.add_argument("--installer-signing-identity", type=str, help="Installer Signing Identity") | ||
|
||
|
||
# Notarization Parameters | ||
# - Notarization Apple ID | ||
# - Notarization Password | ||
# - Notarization Team ID | ||
parser.add_argument("--notarization-apple-id", type=str, help="Notarization Apple ID", default=None) | ||
parser.add_argument("--notarization-password", type=str, help="Notarization Password", default=None) | ||
parser.add_argument("--notarization-team-id", type=str, help="Notarization Team ID", default=None) | ||
|
||
# GitHub Actions CI/CD Parameters | ||
# - Git Branch | ||
# - Git Commit | ||
# - Git Commit Date | ||
parser.add_argument("--git-branch", type=str, help="Git Branch", default=None) | ||
parser.add_argument("--git-commit-url", type=str, help="Git Commit URL", default=None) | ||
parser.add_argument("--git-commit-date", type=str, help="Git Commit Date", default=None) | ||
|
||
# Local Build Parameters | ||
# - Reset payloads.dmg | ||
# - Clean PyInstaller Cache | ||
parser.add_argument("--reset-dmg-cache", action="store_true", help="Redownload PatcherSupportPkg.dmg and regenerate payloads.dmg", default=False) | ||
parser.add_argument("--reset-pyinstaller-cache", action="store_true", help="Clean PyInstaller Cache", default=False) | ||
|
||
# Analytics Parameters | ||
# - Key | ||
# - Site | ||
parser.add_argument("--analytics-key", type=str, help="Analytics Key", default=None) | ||
parser.add_argument("--analytics-endpoint", type=str, help="Analytics Endpoint", default=None) | ||
|
||
# Parse Arguments | ||
args = parser.parse_args() | ||
|
||
# Set 'Current Working Directory' to script directory | ||
os.chdir(Path(__file__).resolve().parent) | ||
|
||
# Prepare workspace | ||
disk_images.GenerateDiskImages(args.reset_dmg_cache).generate() | ||
|
||
# Build OpenCore-Patcher.app | ||
application.GenerateApplication( | ||
reset_pyinstaller_cache=args.reset_pyinstaller_cache, | ||
git_branch=args.git_branch, | ||
git_commit_url=args.git_commit_url, | ||
git_commit_date=args.git_commit_date, | ||
analytics_key=args.analytics_key, | ||
analytics_endpoint=args.analytics_endpoint, | ||
).generate() | ||
|
||
# Sign OpenCore-Patcher.app | ||
sign_notarize.SignAndNotarize( | ||
path=Path("dist/OpenCore-Patcher.app"), | ||
signing_identity=args.application_signing_identity, | ||
notarization_apple_id=args.notarization_apple_id, | ||
notarization_password=args.notarization_password, | ||
notarization_team_id=args.notarization_team_id, | ||
entitlements=Path("./ci_tooling/entitlements/entitlements.plist"), | ||
).sign_and_notarize() | ||
|
||
# Build OpenCore-Patcher.pkg | ||
package.GeneratePackage().generate() | ||
|
||
# Sign OpenCore-Patcher.pkg | ||
sign_notarize.SignAndNotarize( | ||
path=Path("dist/OpenCore-Patcher.pkg"), | ||
signing_identity=args.installer_signing_identity, | ||
notarization_apple_id=args.notarization_apple_id, | ||
notarization_password=args.notarization_password, | ||
notarization_team_id=args.notarization_team_id, | ||
).sign_and_notarize() | ||
|
||
|
||
if __name__ == '__main__': | ||
_start = time.time() | ||
main() | ||
print(f"Build script completed in {str(round(time.time() - _start, 2))} seconds") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
import sys | ||
import time | ||
import plistlib | ||
import subprocess | ||
|
||
from pathlib import Path | ||
|
||
from opencore_legacy_patcher import constants | ||
from opencore_legacy_patcher.support import subprocess_wrapper | ||
|
||
|
||
class GenerateApplication: | ||
""" | ||
Generate OpenCore-Patcher.app | ||
""" | ||
|
||
def __init__(self, reset_pyinstaller_cache: bool = False, git_branch: str = None, git_commit_url: str = None, git_commit_date: str = None, analytics_key: str = None, analytics_endpoint: str = None) -> None: | ||
""" | ||
Initialize | ||
""" | ||
self._pyinstaller = [sys.executable, "-m", "PyInstaller"] | ||
self._application_output = Path("./dist/OpenCore-Patcher.app") | ||
|
||
self._reset_pyinstaller_cache = reset_pyinstaller_cache | ||
|
||
self._git_branch = git_branch | ||
self._git_commit_url = git_commit_url | ||
self._git_commit_date = git_commit_date | ||
|
||
self._analytics_key = analytics_key | ||
self._analytics_endpoint = analytics_endpoint | ||
|
||
|
||
def _generate_application(self) -> None: | ||
""" | ||
Generate PyInstaller Application | ||
""" | ||
if self._application_output.exists(): | ||
subprocess_wrapper.run_and_verify(["/bin/rm", "-rf", self._application_output], stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
|
||
print("Generating OpenCore-Patcher.app") | ||
_args = self._pyinstaller + ["./OpenCore-Patcher-GUI.spec", "--noconfirm"] | ||
if self._reset_pyinstaller_cache: | ||
_args.append("--clean") | ||
|
||
subprocess_wrapper.run_and_verify(_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
|
||
|
||
def _embed_analytics_key(self) -> None: | ||
""" | ||
Embed analytics key | ||
""" | ||
_file = Path("./opencore_legacy_patcher/support/analytics_handler.py") | ||
|
||
if not all([self._analytics_key, self._analytics_endpoint]): | ||
print("Analytics key or endpoint not provided, skipping embedding") | ||
return | ||
|
||
print("Embedding analytics data") | ||
if not Path(_file).exists(): | ||
raise FileNotFoundError("analytics_handler.py not found") | ||
|
||
lines = [] | ||
with open(_file, "r") as f: | ||
lines = f.readlines() | ||
|
||
for i, line in enumerate(lines): | ||
if line.startswith("SITE_KEY: str = "): | ||
lines[i] = f"SITE_KEY: str = \"{self._analytics_key}\"\n" | ||
elif line.startswith("ANALYTICS_SERVER: str = "): | ||
lines[i] = f"ANALYTICS_SERVER: str = \"{self._analytics_endpoint}\"\n" | ||
|
||
with open(_file, "w") as f: | ||
f.writelines(lines) | ||
|
||
|
||
def _remove_analytics_key(self) -> None: | ||
""" | ||
Remove analytics key | ||
""" | ||
_file = Path("./opencore_legacy_patcher/support/analytics_handler.py") | ||
|
||
if not all([self._analytics_key, self._analytics_endpoint]): | ||
return | ||
|
||
print("Removing analytics data") | ||
if not _file.exists(): | ||
raise FileNotFoundError("analytics_handler.py not found") | ||
|
||
lines = [] | ||
with open(_file, "r") as f: | ||
lines = f.readlines() | ||
|
||
for i, line in enumerate(lines): | ||
if line.startswith("SITE_KEY: str = "): | ||
lines[i] = "SITE_KEY: str = \"\"\n" | ||
elif line.startswith("ANALYTICS_SERVER: str = "): | ||
lines[i] = "ANALYTICS_SERVER: str = \"\"\n" | ||
|
||
with open(_file, "w") as f: | ||
f.writelines(lines) | ||
|
||
|
||
def _patch_load_command(self): | ||
""" | ||
Patch LC_VERSION_MIN_MACOSX in Load Command to report 10.10 | ||
By default Pyinstaller will create binaries supporting 10.13+ | ||
However this limitation is entirely arbitrary for our libraries | ||
and instead we're able to support 10.10 without issues. | ||
To verify set version: | ||
otool -l ./dist/OpenCore-Patcher.app/Contents/MacOS/OpenCore-Patcher | ||
cmd LC_VERSION_MIN_MACOSX | ||
cmdsize 16 | ||
version 10.13 | ||
sdk 10.9 | ||
""" | ||
_file = self._application_output / "Contents" / "MacOS" / "OpenCore-Patcher" | ||
|
||
_find = b'\x00\x0D\x0A\x00' # 10.13 (0xA0D) | ||
_replace = b'\x00\x0A\x0A\x00' # 10.10 (0xA0A) | ||
|
||
print("Patching LC_VERSION_MIN_MACOSX") | ||
with open(_file, "rb") as f: | ||
data = f.read() | ||
data = data.replace(_find, _replace, 1) | ||
|
||
with open(_file, "wb") as f: | ||
f.write(data) | ||
|
||
|
||
def _embed_git_data(self) -> None: | ||
""" | ||
Embed git data | ||
""" | ||
_file = self._application_output / "Contents" / "Info.plist" | ||
|
||
_git_branch = self._git_branch or "Built from source" | ||
_git_commit = self._git_commit_url or "" | ||
_git_commit_date = self._git_commit_date or time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) | ||
|
||
print("Embedding git data") | ||
_plist = plistlib.load(_file.open("rb")) | ||
_plist["Github"] = { | ||
"Branch": _git_branch, | ||
"Commit URL": _git_commit, | ||
"Commit Date": _git_commit_date | ||
} | ||
plistlib.dump(_plist, _file.open("wb"), sort_keys=True) | ||
|
||
|
||
def _embed_resources(self) -> None: | ||
""" | ||
Embed resources | ||
""" | ||
print("Embedding resources") | ||
for file in Path("payloads/Icon/AppIcons").glob("*.icns"): | ||
subprocess_wrapper.run_and_verify( | ||
["/bin/cp", str(file), self._application_output / "Contents" / "Resources/"], | ||
stdout=subprocess.PIPE, stderr=subprocess.PIPE | ||
) | ||
|
||
|
||
def generate(self) -> None: | ||
""" | ||
Generate OpenCore-Patcher.app | ||
""" | ||
self._embed_analytics_key() | ||
self._generate_application() | ||
self._remove_analytics_key() | ||
|
||
self._patch_load_command() | ||
self._embed_git_data() | ||
self._embed_resources() |
Oops, something went wrong.