Files
sunnypilot/release/pack.py
Cameron Clough 8097a92515 zipapp pack (#35253)
Used to ship python UI in agnos without an openpilot clone

* add a main method to target

* pack script

* validate inputs

* refactors

* copy into temp, dont keep this

* cleanup

* help messages

* rename to pack.py

* pack.py

* updates for device

* moar

* don't use cereal

* just log normally

* use importlib.resources

* revert

* Revert "don't use cereal"

This reverts commit 7208524d422d88a1b07e209359aeb25e8b3bf4e7.

* fix cereal?

* cleanup

* Revert "cleanup"

This reverts commit 921edfe5020f244dbdf4f26767af7c98ca837d1c.

* cython hotfix

* Reapply "cleanup"

This reverts commit 9b54552f784dea1b1eb4ffc03937571e4fc851ba.

* more cleanup

* any script?

* slightly clearer

* rm print

* nothing python should use SVGs

---------

Co-authored-by: Trey Moen <trey@moen.ai>
2025-05-16 22:24:03 +01:00

51 lines
1.6 KiB
Python
Executable File

#!/usr/bin/env python3
import importlib
import shutil
import sys
import tempfile
import zipapp
from argparse import ArgumentParser
from pathlib import Path
from openpilot.common.basedir import BASEDIR
DIRS = ['cereal', 'openpilot']
EXTS = ['.png', '.py', '.ttf', '.capnp']
INTERPRETER = '/usr/bin/env python3'
def copy(src, dest):
if any(src.endswith(ext) for ext in EXTS):
shutil.copy2(src, dest, follow_symlinks=True)
if __name__ == '__main__':
parser = ArgumentParser(prog='pack.py', description="package script into a portable executable", epilog='comma.ai')
parser.add_argument('-e', '--entrypoint', help="function to call in module, default is 'main'", default='main')
parser.add_argument('-o', '--output', help='output file')
parser.add_argument('module', help="the module to target, e.g. 'openpilot.system.ui.spinner'")
args = parser.parse_args()
if not args.output:
args.output = args.module
try:
mod = importlib.import_module(args.module)
except ModuleNotFoundError:
print(f'{args.module} not found, typo?')
sys.exit(1)
if not hasattr(mod, args.entrypoint):
print(f'{args.module} does not have a {args.entrypoint}() function, typo?')
sys.exit(1)
with tempfile.TemporaryDirectory() as tmp:
for directory in DIRS:
shutil.copytree(BASEDIR + '/' + directory, tmp + '/' + directory, symlinks=False, dirs_exist_ok=True, copy_function=copy)
entry = f'{args.module}:{args.entrypoint}'
zipapp.create_archive(tmp, target=args.output, interpreter=INTERPRETER, main=entry)
print(f'created executable {Path(args.output).resolve()}')