dangerzone/install/macos/build-app.py
deeplow 3f23010394
Redo macOS build-app.py and add --codesign-only opt
Redoes the build-app.py script to add an option to sign only an already-
produced app bundle.
2023-04-10 10:40:01 +01:00

163 lines
4.3 KiB
Python
Executable file

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import glob
import inspect
import itertools
import os
import shutil
import subprocess
root = os.path.dirname(
os.path.dirname(
os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
)
)
def run(cmd):
subprocess.run(cmd, cwd=root, check=True)
def build_app_bundle():
"""
Builds the Dangerzone.app bundle and saves it in dist/Dangerzone.app
"""
print("○ Deleting old build and dist")
if os.path.exists(build_path):
shutil.rmtree(build_path)
if os.path.exists(dist_path):
shutil.rmtree(dist_path)
print("○ Building app bundle")
run(["pyinstaller", "install/pyinstaller/pyinstaller.spec", "--clean"])
shutil.rmtree(os.path.join(dist_path, "dangerzone"))
os.symlink(
"dangerzone",
os.path.join(app_path, "Contents/MacOS/dangerzone-cli"),
)
print(f"○ Finished build app: {app_path}")
def codesign(path, entitlements, identity):
run(
[
"codesign",
"--sign",
identity,
"--entitlements",
str(entitlements),
"--timestamp",
"--deep",
str(path),
"--force",
"--options",
"runtime",
]
)
def sign_app_bundle(build_path, dist_path, app_path):
"""
Signs the app bundle stored in dist/Dangerzone.app,
producing a Dangerzone.dmg file
"""
print(f"○ Signing app bundle in {app_path}")
# Detect if create-dmg is installed
if not os.path.exists(app_path):
print(f"ERROR: Dangerzone.app not found in {app_path}.")
exit(1)
dmg_path = os.path.join(dist_path, "Dangerzone.dmg")
icon_path = os.path.join(root, "install", "macos", "dangerzone.icns")
print("○ Code signing app bundle")
identity_name_application = (
# FIXME: Update this line with the proper developer ID, once we know what
# that is.
"Developer ID Application: FREEDOM OF THE PRESS FOUNDATION, 501(c)(3)"
)
entitlements_plist_path = os.path.join(root, "install/macos/entitlements.plist")
for path in itertools.chain(
glob.glob(f"{app_path}/**/*.so", recursive=True),
glob.glob(f"{app_path}/**/*.dylib", recursive=True),
glob.glob(f"{app_path}/**/Python3", recursive=True),
[app_path],
):
codesign(path, entitlements_plist_path, identity_name_application)
print(f"○ Signed app bundle: {app_path}")
# Detect if create-dmg is installed
if not os.path.exists("/usr/local/bin/create-dmg"):
print("create-dmg is not installed, skipping creating a DMG")
return
print("○ Creating DMG")
run(
[
"create-dmg",
"--volname",
"Dangerzone",
"--volicon",
icon_path,
"--window-size",
"400",
"200",
"--icon-size",
"100",
"--icon",
"Dangerzone.app",
"100",
"70",
"--hide-extension",
"Dangerzone.app",
"--app-drop-link",
"300",
"70",
dmg_path,
app_path,
"--identity",
identity_name_application,
]
)
print(f"○ Finished building DMG: {dmg_path}")
def main():
# Parse arguments
parser = argparse.ArgumentParser()
codesign_opts = parser.add_mutually_exclusive_group()
codesign_opts.add_argument(
"--with-codesign",
action="store_true",
dest="with_codesign",
help="Codesign the app bundle",
)
codesign_opts.add_argument(
"--only-codesign",
action="store_true",
dest="only_codesign",
help="Exclusively codesign the app bundle in dist/Dangerzone.app",
)
args = parser.parse_args()
build_path = os.path.join(root, "build")
dist_path = os.path.join(root, "dist")
app_path = os.path.join(dist_path, "Dangerzone.app")
if args.only_codesign:
sign_app_bundle(build_path, dist_path, app_path)
else:
build_app_bundle(build_path, dist_path, app_path)
if args.with_codesign:
sign_app_bundle(build_path, dist_path, app_path)
else:
print("○ Skipping code signing")
if __name__ == "__main__":
main()