From 804438f04506a1ed8cfec99d25a7ea261fa9e631 Mon Sep 17 00:00:00 2001 From: magical Date: Wed, 10 Aug 2022 03:45:03 +0000 Subject: [PATCH] add bundle.py to create single-file bbj client python is able to import modules from a zip file. if the zip file contains __main__.py it will even run it as a script! this lets us bundle bbj's frontend together with its sole external dependency (urwid) to create a single executable file that'll run anywhere with python installed, no virtualenv needed. the only downside is that python can't import shared objects (.so) from a zip file, so urwid can't use its C-accelerated str_util module and has to fall back to the python version. which is slower, probably. --- bundle.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 bundle.py diff --git a/bundle.py b/bundle.py new file mode 100644 index 0000000..4557036 --- /dev/null +++ b/bundle.py @@ -0,0 +1,32 @@ +import zipfile +import glob +import os + + +# TODO: should we include .pyc files? +# TODO: add urwid source into the repo somewhere + +files = { + '__main__.py': 'clients/urwid/main.py', + 'network.py': 'clients/network_client.py', + 'urwid': 'env/lib/python3.8/site-packages/urwid/*.py', +} + +with open('bbj_demo', 'wb') as f: + f.write(b"#!/usr/bin/env python3\n") + with zipfile.ZipFile(f, 'w', compression=zipfile.ZIP_DEFLATED) as z: + z.comment = b'BBJ' + for name, source in files.items(): + if '*' in source: + dirname = name + for path in sorted(glob.glob(source)): + name = dirname + '/' + os.path.basename(path) + z.write(path, name) + else: + z.write(source, name) +try: + mask = os.umask(0) + os.umask(mask) +except OSError: + mask = 0 +os.chmod(z.filename, 0o777&~mask)