| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- import argparse
- from importlib import import_module
- import os
- __all__ = ['main']
- def exists(path):
- if not os.path.exists(path):
- raise argparse.ArgumentTypeError("could not find: {}".format(path))
- return os.path.abspath(path)
- def main():
- '''Entry point for the CLI
- '''
- # Binary dependencies
- binaries = ('appimagetool', 'patchelf')
- # Parse arguments
- parser = argparse.ArgumentParser(
- prog='python-appimage',
- description='Bundle a Python installation into an AppImage')
- subparsers = parser.add_subparsers(title='command',
- help='Command to execute',
- dest='command')
- parser.add_argument('-a', '--appimagetool-version',
- help='set appimagetool version')
- parser.add_argument('-q', '--quiet', help='disable logging',
- dest='verbosity', action='store_const', const='ERROR')
- parser.add_argument('-v', '--verbose', help='print extra information',
- dest='verbosity', action='store_const', const='DEBUG')
- build_parser = subparsers.add_parser('build',
- description='Build a Python appimage')
- build_subparsers = build_parser.add_subparsers(title='type',
- help='Type of AppImage build', dest='sub_command')
- cache_parser = subparsers.add_parser('cache',
- description='Manage Python appimage cache')
- cache_subparsers = cache_parser.add_subparsers(title='operation',
- help='Type of cache operation', dest='sub_command')
- cache_clean_parser = cache_subparsers.add_parser('clean',
- description='Clean cached image(s)')
- cache_clean_parser.add_argument('tags', nargs='*',
- help='manylinux image tag(s) (e.g. 2014_x86_64)')
- cache_clean_parser.add_argument('-a', '--all', action='store_true',
- help='remove all image(s) data')
- cache_get_parser = cache_subparsers.add_parser('get',
- description='Download image(s) to the cache')
- cache_get_parser.add_argument('tags', nargs='+',
- help='manylinux image tag(s) (e.g. 2014_x86_64)')
- cache_get_parser.add_argument('-e', '--extract', action='store_true',
- help='extract compressed image data')
- cache_list_parser = cache_subparsers.add_parser('list',
- description='List cached image(s)')
- install_parser = subparsers.add_parser('install',
- description='Install binary dependencies')
- install_parser.add_argument('binary', nargs='+',
- choices=binaries, help='one or more binary name')
- build_local_parser = build_subparsers.add_parser('local',
- description='Bundle a local Python installation')
- build_local_parser.add_argument('-d', '--destination',
- help='AppImage destination')
- build_local_parser.add_argument('-p', '--python', help='python executable')
- build_manylinux_parser = build_subparsers.add_parser('manylinux',
- description='Bundle a manylinux Python installation')
- build_manylinux_parser.add_argument('tag',
- help='manylinux image tag (e.g. 2010_x86_64)')
- build_manylinux_parser.add_argument('abi',
- help='python ABI (e.g. cp37-cp37m)')
- build_manylinux_parser.add_argument('-b', '--bare',
- help='produce a bare image without the AppImage layer',
- action='store_true')
- build_manylinux_parser.add_argument('-c', '--clean',
- help='clean the cache after extraction', action='store_true')
- build_manylinux_parser.add_argument('-n', '--no-packaging',
- help='do not package (compress) the image', action='store_true')
- build_app_parser = build_subparsers.add_parser('app',
- description='Build a Python application using a base AppImage')
- build_app_parser.add_argument('appdir',
- help='path to the application metadata')
- build_app_parser.add_argument('-b', '--base-image',
- help='path to a base image on disk')
- build_app_parser.add_argument('-l', '--linux-tag',
- help='linux compatibility tag (e.g. manylinux1_x86_64)')
- build_app_parser.add_argument('-n', '--name',
- help='application name')
- build_app_parser.add_argument('--no-packaging',
- help='do not package the app', action='store_true')
- build_app_parser.add_argument('--python-tag',
- help='python compatibility tag (e.g. cp37-cp37m)')
- build_app_parser.add_argument('-p', '--python-version',
- help='python version (e.g. 3.8)')
- build_app_parser.add_argument('--in-tree-build',
- help='force pip in-tree-build',
- action='store_true',
- default=False)
- build_app_parser.add_argument('-x', '--extra-data', type=exists,
- help='extra application data (bundled under $APPDIR/)', nargs='+')
- list_parser = subparsers.add_parser('list',
- description='List Python versions installed in a manylinux image')
- list_parser.add_argument('tag',
- help='manylinux image tag (e.g. 2010_x86_64)')
- which_parser = subparsers.add_parser('which',
- description='Locate a binary dependency')
- which_parser.add_argument('binary', choices=binaries,
- help='name of the binary to locate')
- args = parser.parse_args()
- # Configure the verbosity
- if args.verbosity:
- from .utils import log
- log.set_level(args.verbosity)
- if args.appimagetool_version:
- from .utils import deps
- deps.APPIMAGETOOL_VERSION = args.appimagetool_version
- # check if no arguments are passed
- if args.command is None:
- parser.print_help()
- return
- # Call the requested command
- module = '.commands.' + args.command
- try:
- module += '.' + args.sub_command
- except AttributeError:
- pass
- command = import_module(module, package=__package__)
- # check if the module has a 'execute' subcommand
- # if not, display the help message
- if not hasattr(command, 'execute'):
- locals().get('{}_parser'.format(args.command)).print_help()
- return
- # execute the command
- command.execute(*command._unpack_args(args))
- if __name__ == '__main__':
- main()
|