diff options
author | Rob Austein <sra@hactrn.net> | 2019-03-10 13:46:08 -0400 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2019-03-10 13:46:08 -0400 |
commit | fa9a04b06a7c6f62979c506b9999abf6b2eb8208 (patch) | |
tree | 887062e0d0c0ff844eb5fd05d603aad897c77d7e /pyzipper |
First public version.
Diffstat (limited to 'pyzipper')
-rwxr-xr-x | pyzipper | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/pyzipper b/pyzipper new file mode 100755 index 0000000..9e50835 --- /dev/null +++ b/pyzipper @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +""" +Generate an executable Python zip package. +""" + +import os, zipfile, argparse + +ap = argparse.ArgumentParser(description = __doc__, + formatter_class = argparse.ArgumentDefaultsHelpFormatter) +ap.add_argument("-o", "--output", required = True, type = argparse.FileType("wb+")) +ap.add_argument("-m", "--module", default = "main", help = "module within package to run") +ap.add_argument("-e", "--executable", default = "python", help = "python executable to run") +ap.add_argument("source") +args = ap.parse_args() + +# PyZipFile.writepy()'s behavior changes when it sees __init__.py +if os.path.exists(os.path.join(args.source, "__init__.py")): + module = "{0.source}.{0.module}".format(args) +else: + module = args.module + +# Write executable shim +args.output.write('''\ +#/bin/sh - +PYTHONPATH="$0"${{PYTHONPATH+":$PYTHONPATH"}} exec {e} -m {m} ${{1+"$@"}} +'''.format(m = module, e = args.executable).encode("ascii")) + +# Make output executable +os.fchmod(args.output.fileno(), 0o755) + +# Create the zip file and populate it with the code +z = zipfile.PyZipFile(args.output, "a", zipfile.ZIP_DEFLATED) +z.writepy(args.source) + +# Add data files, if any +if os.path.isdir(args.source): + for root, dirs, files in os.walk(args.source): + for fn in files: + if not any(fn.endswith(fn2) for fn2 in (".py", ".pyc", ".pyo")): + z.write(os.path.join(root, fn)) + +# Test the zip file we just generated out of paranoia +z.testzip() |