def main(args): parser = argparse.ArgumentParser( prog='packer.py', formatter_class=argparse.RawDescriptionHelpFormatter, description='Pack obfuscated scripts', epilog=__doc__, ) add_arguments(parser) packer(parser.parse_args(args))
def main(args): parser = argparse.ArgumentParser( prog='pyarmor', formatter_class=argparse.RawDescriptionHelpFormatter, description=__doc__, epilog='See "pyarmor <command> -h" for more information ' 'on a specific command.\n\nMore usage refer to ' 'https://pyarmor.readthedocs.io' ) parser.add_argument('-v', '--version', action='version', version=_version_info()) parser.add_argument('-q', '--silent', action='store_true', help='Suppress all normal output') subparsers = parser.add_subparsers( title='The most commonly used pyarmor commands are', metavar='' ) # # Command: obfuscate # cparser = subparsers.add_parser( 'obfuscate', aliases=['o'], epilog=_obfuscate.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Obfuscate python scripts') cparser.add_argument('-O', '--output', default='dist', metavar='PATH') cparser.add_argument('-r', '--recursive', action='store_true', help='Search scripts in recursive mode') cparser.add_argument('--exclude', metavar='PATH', action='append', help='Exclude the path in recursive mode. ' 'Multiple paths are allowed, separated by ",". ' 'Or use this option multiple times') cparser.add_argument('--exact', action='store_true', help='Only obfusate list scripts') cparser.add_argument('--no-bootstrap', action='store_true', help='Do not insert bootstrap code to entry script') cparser.add_argument('--no-cross-protection', action='store_true', help='Do not insert cross protection code to entry ' 'script') cparser.add_argument('scripts', metavar='SCRIPT', nargs='*', help='List scripts to obfuscated, the first script ' 'is entry script') cparser.add_argument('-s', '--src', metavar='PATH', help='Base path for searching scripts') cparser.add_argument('-e', '--entry', metavar='SCRIPT', help=argparse.SUPPRESS) cparser.add_argument('--cross-protection', choices=(0, 1), help=argparse.SUPPRESS) cparser.add_argument('--plugin', dest='plugins', action='append', help='Insert extra code to entry script') cparser.add_argument('--restrict', type=int, choices=range(5), default=1, help='Set restrict mode') cparser.add_argument('--capsule', help=argparse.SUPPRESS) cparser.add_argument('--platform', help='Distribute obfuscated scripts ' 'to other platform') cparser.add_argument('--advanced', nargs='?', const=1, type=int, default=0, choices=(0, 1), help='Enable advanced mode') cparser.add_argument('--package-runtime', choices=(0, 1, 2), type=int, default=1, help='Save runtime files as a package or not') cparser.add_argument('-n', '--no-runtime', action='store_true', help='DO NOT generate runtime files') cparser.set_defaults(func=_obfuscate) # # Command: license # cparser = subparsers.add_parser( 'licenses', aliases=['l'], epilog=_licenses.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Generate new licenses for obfuscated scripts' ) cparser.add_argument('codes', nargs='+', metavar='CODE', help='Registration code for this license') group = cparser.add_argument_group('Bind license to hardware') group.add_argument('-e', '--expired', metavar='YYYY-MM-DD', help='Expired date for this license') group.add_argument('-d', '--bind-disk', metavar='SN', help='Bind license to serial number of harddisk') group.add_argument('-4', '--bind-ipv4', metavar='a.b.c.d', help='Bind license to ipv4 addr') # group.add_argument('-6', '--bind-ipv6', metavar='a:b:c:d', # help='Bind license to ipv6 addr') group.add_argument('-m', '--bind-mac', metavar='x:x:x:x', help='Bind license to mac addr') group.add_argument('-x', '--bind-data', metavar='DATA', help='Pass extra ' 'data to license, used to extend license type') group.add_argument('--bind-domain', metavar='DOMAIN', help='Bind license to domain name') group.add_argument('--bind-file', metavar='filename;target_filename', help=argparse.SUPPRESS) cparser.add_argument('-P', '--project', default='', help=argparse.SUPPRESS) cparser.add_argument('-C', '--capsule', help=argparse.SUPPRESS) cparser.add_argument('-O', '--output', help='Output path') cparser.add_argument('--disable-restrict-mode', action='store_true', help='Disable all the restrict modes') cparser.add_argument('--restrict', type=int, choices=(0, 1), default=1, help=argparse.SUPPRESS) cparser.set_defaults(func=_licenses) # # Command: pack # cparser = subparsers.add_parser( 'pack', aliases=['p'], epilog=packer.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Pack obfuscated scripts to one bundle' ) packer.add_arguments(cparser) cparser.set_defaults(func=packer.packer) # # Command: init # cparser = subparsers.add_parser( 'init', aliases=['i'], epilog=_init.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Create a project to manage obfuscated scripts' ) cparser.add_argument('-t', '--type', default='auto', choices=('auto', 'app', 'pkg')) cparser.add_argument('-e', '--entry', help='Entry script of this project') cparser.add_argument('-s', '--src', default='', help='Base path of python scripts') cparser.add_argument('--capsule', help=argparse.SUPPRESS) cparser.add_argument('--child', type=int, help=argparse.SUPPRESS) cparser.add_argument('project', nargs='?', default='', help='Project path') cparser.set_defaults(func=_init) # # Command: config # cparser = subparsers.add_parser( 'config', aliases=['c'], epilog=_config.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Update project settings') cparser.add_argument('project', nargs='?', metavar='PATH', default='', help='Project path') cparser.add_argument('--name') cparser.add_argument('--title') cparser.add_argument('--src') cparser.add_argument('--output') cparser.add_argument('--capsule', help=argparse.SUPPRESS) cparser.add_argument('--platform', help=argparse.SUPPRESS) cparser.add_argument('--manifest', metavar='TEMPLATE', help='Manifest template string') cparser.add_argument('--entry', metavar='SCRIPT', help='Entry script of this project') cparser.add_argument('--is-package', type=int, choices=(0, 1)) cparser.add_argument('--disable-restrict-mode', type=int, choices=(0, 1), help=argparse.SUPPRESS) cparser.add_argument('--restrict-mode', type=int, choices=range(5), help='Set restrict mode') cparser.add_argument('--obf-module-mode', choices=Project.OBF_MODULE_MODE, help='[DEPRECATED] Use --obf-mod instead') cparser.add_argument('--obf-code-mode', choices=Project.OBF_CODE_MODE, help='[DEPRECATED] Use --obf-code and --wrap-mode' ' instead') cparser.add_argument('--obf-mod', type=int, choices=(0, 1)) cparser.add_argument('--obf-code', type=int, choices=(0, 1, 2)) cparser.add_argument('--wrap-mode', type=int, choices=(0, 1)) cparser.add_argument('--cross-protection', type=int, choices=(0, 1)) cparser.add_argument('--runtime-path', metavar="RPATH") cparser.add_argument('--plugin', dest='plugins', action='append', help='Insert extra code to entry script') cparser.add_argument('--advanced-mode', type=int, choices=(0, 1)) cparser.add_argument('--package-runtime', choices=(0, 1, 2), type=int, help='Save runtime files as a package or not') cparser.set_defaults(func=_config) # # Command: build # cparser = subparsers.add_parser( 'build', aliases=['b'], epilog=_build.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Obfuscate all the scripts in the project') cparser.add_argument('project', nargs='?', metavar='PATH', default='', help='Project path') cparser.add_argument('-B', '--force', action='store_true', help='Force to obfuscate all scripts') cparser.add_argument('-r', '--only-runtime', action='store_true', help='Generate extra runtime files only') cparser.add_argument('-n', '--no-runtime', action='store_true', help='DO NOT generate runtime files') cparser.add_argument('-O', '--output', help='Output path, override project configuration') cparser.add_argument('--platform', help='Distribute obfuscated scripts ' 'to other platform') cparser.add_argument('--package-runtime', choices=(0, 1, 2), type=int, help='Save runtime files as a package or not') cparser.set_defaults(func=_build) # # Command: info # cparser = subparsers.add_parser( 'info', epilog=_info.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Show project information' ) cparser.add_argument('project', nargs='?', metavar='PATH', default='', help='Project path') cparser.set_defaults(func=_info) # # Command: check # cparser = subparsers.add_parser( 'check', epilog=_check.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Check consistency of project') cparser.add_argument('project', nargs='?', metavar='PATH', default='', help='Project path') cparser.set_defaults(func=_check) # # Command: hdinfo # cparser = subparsers.add_parser( 'hdinfo', epilog=_hdinfo.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Show hardware information' ) cparser.set_defaults(func=_hdinfo) # # Command: benchmark # cparser = subparsers.add_parser( 'benchmark', epilog=_benchmark.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Run benchmark test in current machine' ) cparser.add_argument('-m', '--obf-mod', choices=(0, 1), default=1, type=int) cparser.add_argument('-c', '--obf-code', choices=(0, 1, 2), default=1, type=int) cparser.add_argument('-w', '--wrap-mode', choices=(0, 1), default=1, type=int) cparser.add_argument('--debug', action='store_true', help='Do not clean the test scripts' 'generated in real time') cparser.set_defaults(func=_benchmark) # # Command: capsule # cparser = subparsers.add_parser( 'capsule', epilog=_capsule.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, add_help=False) cparser.add_argument('-f', '--force', action='store_true', help='Force update public capsule even if it exists') cparser.add_argument('path', nargs='?', default=os.path.expanduser('~'), help='Path to save capsule, default is home path') cparser.set_defaults(func=_capsule) # # Command: register # cparser = subparsers.add_parser( 'register', epilog=_register.__doc__ + purchase_info, formatter_class=argparse.RawDescriptionHelpFormatter, help='Make registration keyfile work') group = cparser.add_mutually_exclusive_group() group.add_argument('filename', nargs='?', metavar='KEYFILE', help='Filename of registration keyfile') cparser.set_defaults(func=_register) # # Command: download # cparser = subparsers.add_parser( 'download', epilog=_download.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Download platform-dependent dynamic libraries') cparser.add_argument('-O', '--output', metavar='NAME', help='Save downloaded file to another path') cparser.add_argument('--url', help='Use this mirror site other than default site') group = cparser.add_mutually_exclusive_group() group.add_argument('--list', nargs='?', const='', dest='pattern', help='List all the available platforms') group.add_argument('platid', nargs='?', help='Download dynamic library by platform id') cparser.set_defaults(func=_download) # # Command: runtime # cparser = subparsers.add_parser( 'runtime', epilog=_runtime.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Generate runtime package separately') cparser.add_argument('-O', '--output', metavar='PATH', default='dist', help='Output path, default is "%(default)s"') cparser.add_argument('-n', '--no-package', action='store_true', help='Generate runtime files without package') cparser.add_argument('-L', '--with-license', metavar='license', help='Replace default license with this file') cparser.add_argument('--platform', help='Generate runtime package ' 'for specified platform') cparser.add_argument('pkgname', nargs='?', default='pytransform', help=argparse.SUPPRESS) cparser.set_defaults(func=_runtime) args = parser.parse_args(args) if args.silent: logging.getLogger().setLevel(100) if not hasattr(args, 'func'): parser.print_help() return logging.info(_version_info(verbose=0)) logging.debug('PyArmor install path: %s', PYARMOR_PATH) args.func(args)
def _parser(): parser = argparse.ArgumentParser( prog='pyarmor', formatter_class=argparse.RawDescriptionHelpFormatter, description=__doc__, epilog='See "pyarmor <command> -h" for more information ' 'on a specific command.\n\nMore usage refer to ' 'https://pyarmor.readthedocs.io' ) parser.add_argument('-v', '--version', action='version', version=_version_action) parser.add_argument('-q', '--silent', action='store_true', help='Suppress all normal output') parser.add_argument('-d', '--debug', action='store_true', help='Print exception traceback and debugging message') subparsers = parser.add_subparsers( title='The most commonly used pyarmor commands are', metavar='' ) # # Command: obfuscate # cparser = subparsers.add_parser( 'obfuscate', aliases=['o'], epilog=_obfuscate.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Obfuscate python scripts') cparser.add_argument('-O', '--output', default='dist', metavar='PATH', help='Output path, default is "%(default)s"') cparser.add_argument('-r', '--recursive', action='store_true', help='Search scripts in recursive mode') cparser.add_argument('--exclude', metavar='PATH', action='append', help='Exclude the path in recursive mode. ' 'Multiple paths are allowed, separated by ",". ' 'Or use this option multiple times') cparser.add_argument('--exact', action='store_true', help='Only obfusate list scripts') cparser.add_argument('--no-bootstrap', action='store_true', help='Do not insert bootstrap code to entry script') cparser.add_argument('--bootstrap', '--bootstrap-code', dest='bootstrap_code', type=int, default=1, choices=(0, 1, 2, 3), help='How to insert bootstrap code to entry script') cparser.add_argument('--no-cross-protection', action='store_true', help='Do not insert cross protection code to entry ' 'script') cparser.add_argument('scripts', metavar='SCRIPT', nargs='+', help='List scripts to obfuscated, the first script ' 'is entry script') cparser.add_argument('-s', '--src', metavar='PATH', help='Specify source path if entry script is not ' 'in the top most path') cparser.add_argument('-e', '--entry', metavar='SCRIPT', help=argparse.SUPPRESS) cparser.add_argument('--cross-protection', choices=(0, 1), help=argparse.SUPPRESS) cparser.add_argument('--plugin', dest='plugins', metavar='NAME', action='append', help='Insert extra code to entry script, ' 'it could be used multiple times') cparser.add_argument('--restrict', type=int, choices=range(5), default=1, help='Set restrict mode') cparser.add_argument('--capsule', help=argparse.SUPPRESS) cparser.add_argument('--platform', dest='platforms', metavar='NAME', action='append', help='Target platform to run obfuscated scripts, ' 'use this option multiple times for more platforms') cparser.add_argument('--advanced', nargs='?', const=1, type=int, default=0, choices=(0, 1), help='Enable advanced mode') cparser.add_argument('--package-runtime', type=int, default=1, choices=(0, 1), help='Package runtime files or not') cparser.add_argument('-n', '--no-runtime', action='store_true', help='DO NOT generate runtime files') cparser.add_argument('--enable-suffix', action='store_true', help='Make unique runtime files and bootstrap code') cparser.set_defaults(func=_obfuscate) # # Command: license # cparser = subparsers.add_parser( 'licenses', aliases=['l'], epilog=_licenses.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Generate new licenses for obfuscated scripts' ) cparser.add_argument('codes', nargs='+', metavar='CODE', help='Registration code for this license') group = cparser.add_argument_group('Bind license to hardware') group.add_argument('-e', '--expired', metavar='YYYY-MM-DD', help='Expired date for this license') group.add_argument('-d', '--bind-disk', metavar='SN', help='Bind license to serial number of harddisk') group.add_argument('-4', '--bind-ipv4', metavar='a.b.c.d', help='Bind license to ipv4 addr') # group.add_argument('-6', '--bind-ipv6', metavar='a:b:c:d', # help='Bind license to ipv6 addr') group.add_argument('-m', '--bind-mac', metavar='x:x:x:x', help='Bind license to mac addr') group.add_argument('-x', '--bind-data', metavar='DATA', help='Pass extra ' 'data to license, used to extend license type') group.add_argument('--bind-domain', metavar='DOMAIN', help='Bind license to domain name') group.add_argument('--bind-file', metavar='filename;target_filename', help=argparse.SUPPRESS) cparser.add_argument('-P', '--project', default='', help=argparse.SUPPRESS) cparser.add_argument('-C', '--capsule', help=argparse.SUPPRESS) cparser.add_argument('-O', '--output', help='Output path, default is ' '`licenses` (`stdout` is also supported)') cparser.add_argument('--disable-restrict-mode', action='store_true', help='Disable all the restrict modes') cparser.add_argument('--enable-period-mode', action='store_true', help='Check license periodly (per hour)') cparser.add_argument('--restrict', type=int, choices=(0, 1), default=1, help=argparse.SUPPRESS) cparser.set_defaults(func=_licenses) # # Command: pack # cparser = subparsers.add_parser( 'pack', aliases=['p'], epilog=packer.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Pack obfuscated scripts to one bundle' ) packer.add_arguments(cparser) cparser.set_defaults(func=packer.packer) # # Command: init # cparser = subparsers.add_parser( 'init', aliases=['i'], epilog=_init.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Create a project to manage obfuscated scripts' ) cparser.add_argument('-t', '--type', default='auto', choices=('auto', 'app', 'pkg')) cparser.add_argument('-e', '--entry', help='Entry script of this project') cparser.add_argument('-s', '--src', default='', help='Project src, base path for matching scripts') cparser.add_argument('--capsule', help=argparse.SUPPRESS) cparser.add_argument('project', nargs='?', default='', help='Project path') cparser.set_defaults(func=_init) # # Command: config # cparser = subparsers.add_parser( 'config', aliases=['c'], epilog=_config.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Update project settings') cparser.add_argument('project', nargs='?', metavar='PATH', default='', help='Project path') cparser.add_argument('--name') cparser.add_argument('--title') cparser.add_argument('--src', help='Project src, base path for matching scripts') cparser.add_argument('--output', help='Output path for obfuscated scripts') cparser.add_argument('--capsule', help=argparse.SUPPRESS) cparser.add_argument('--platform', dest='platforms', metavar='NAME', action='append', help='Target platform to run obfuscated scripts, ' 'use this option multiple times for more platforms') cparser.add_argument('--manifest', metavar='TEMPLATE', help='Filter the project scritps by these manifest ' 'template commands') cparser.add_argument('--entry', metavar='SCRIPT', help='Entry script of this project, sperated by "," ' 'for multiple entry scripts') cparser.add_argument('--is-package', type=int, choices=(0, 1)) cparser.add_argument('--disable-restrict-mode', type=int, choices=(0, 1), help=argparse.SUPPRESS) cparser.add_argument('--restrict', '--restrict-mode', dest='restrict_mode', type=int, choices=range(5), help='Set restrict mode') cparser.add_argument('--obf-module-mode', choices=Project.OBF_MODULE_MODE, help=argparse.SUPPRESS) cparser.add_argument('--obf-code-mode', choices=Project.OBF_CODE_MODE, help=argparse.SUPPRESS) cparser.add_argument('--obf-mod', type=int, choices=(0, 1)) cparser.add_argument('--obf-code', type=int, choices=(0, 1, 2)) cparser.add_argument('--wrap-mode', type=int, choices=(0, 1)) cparser.add_argument('--cross-protection', type=int, choices=(0, 1), help='Insert cross protection code to entry script ' 'or not') cparser.add_argument('--bootstrap', '--bootstrap-code', type=int, dest='bootstrap_code', choices=(0, 1, 2, 3), help='How to insert bootstrap code to entry script') cparser.add_argument('--runtime-path', metavar="RPATH", help='The path to search dynamic library in runtime, ' 'if it is not within the runtime package') cparser.add_argument('--plugin', dest='plugins', metavar='NAME', action='append', help='Insert extra code to entry script, ' 'it could be used multiple times') cparser.add_argument('--advanced', '--advanced-mode', dest='advanced_mode', type=int, choices=(0, 1), help='Enable or disable advanced mode') cparser.add_argument('--package-runtime', choices=(0, 1), type=int, help='Package runtime files or not') cparser.add_argument('--enable-suffix', type=int, choices=(0, 1), help='Make unique runtime files and bootstrap code') cparser.add_argument('--with-license', dest='license_file', help='Use this license file other than default') # cparser.add_argument('--reset', choices=('all', 'glob', 'exact'), # help='Initialize project scripts by different way') # cparser.add_argument('--exclude', dest="exludes", action="append", # help='Exclude the path or script from project. ' # 'This option could be used multiple times') cparser.set_defaults(func=_config) # # Command: build # cparser = subparsers.add_parser( 'build', aliases=['b'], epilog=_build.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Obfuscate all the scripts in the project') cparser.add_argument('project', nargs='?', metavar='PATH', default='', help='Project path, or project configuratioin file') cparser.add_argument('-B', '--force', action='store_true', help='Force to obfuscate all scripts, otherwise ' 'only obfuscate the changed scripts since last build') cparser.add_argument('-r', '--only-runtime', action='store_true', help='Generate runtime files only') cparser.add_argument('-n', '--no-runtime', action='store_true', help='DO NOT generate runtime files') cparser.add_argument('-O', '--output', help='Output path, override project configuration') cparser.add_argument('--platform', dest='platforms', metavar='NAME', action='append', help='Target platform to run obfuscated scripts, ' 'use this option multiple times for more platforms') cparser.add_argument('--package-runtime', choices=(0, 1), type=int, help='Package runtime files or not') cparser.set_defaults(func=_build) # # Command: info # cparser = subparsers.add_parser( 'info', epilog=_info.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Show project information' ) cparser.add_argument('project', nargs='?', metavar='PATH', default='', help='Project path') cparser.set_defaults(func=_info) # # Command: check # cparser = subparsers.add_parser( 'check', epilog=_check.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Check consistency of project') cparser.add_argument('project', nargs='?', metavar='PATH', default='', help='Project path') cparser.set_defaults(func=_check) # # Command: hdinfo # cparser = subparsers.add_parser( 'hdinfo', epilog=_hdinfo.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Show hardware information' ) cparser.set_defaults(func=_hdinfo) # # Command: benchmark # cparser = subparsers.add_parser( 'benchmark', epilog=_benchmark.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Run benchmark test in current machine' ) cparser.add_argument('-m', '--obf-mod', choices=(0, 1), default=1, type=int) cparser.add_argument('-c', '--obf-code', choices=(0, 1, 2), default=1, type=int) cparser.add_argument('-w', '--wrap-mode', choices=(0, 1), default=1, type=int) cparser.add_argument('--debug', action='store_true', help='Do not clean the test scripts' 'generated in real time') cparser.set_defaults(func=_benchmark) # # Command: capsule # cparser = subparsers.add_parser( 'capsule', epilog=_capsule.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, add_help=False) cparser.add_argument('-f', '--force', action='store_true', help='Force update public capsule even if it exists') cparser.add_argument('path', nargs='?', default=os.path.expanduser('~'), help='Path to save capsule, default is home path') cparser.set_defaults(func=_capsule) # # Command: register # cparser = subparsers.add_parser( 'register', epilog=_register.__doc__ + purchase_info, formatter_class=argparse.RawDescriptionHelpFormatter, help='Make registration keyfile work') cparser.add_argument('-n', '--legency', action='store_true', help='Store `license.lic` in the traditional way') cparser.add_argument('filename', nargs='?', metavar='KEYFILE', help='Filename of registration keyfile') cparser.set_defaults(func=_register) # # Command: download # cparser = subparsers.add_parser( 'download', epilog=_download.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Download platform-dependent dynamic libraries') cparser.add_argument('-O', '--output', metavar='PATH', help='Save downloaded library to this path, default ' 'is `~/.pyarmor/platforms`') cparser.add_argument('--url', help=argparse.SUPPRESS) group = cparser.add_mutually_exclusive_group() group.add_argument('--help-platform', nargs='?', const='', metavar='FILTER', help='Display all available platform names') group.add_argument('-L', '--list', nargs='?', const='', dest='pattern', metavar='FILTER', help='List available dynamic libraries in details') group.add_argument('-u', '--update', nargs='?', const='*', metavar='NAME', help='Update all the downloaded dynamic libraries') group.add_argument('platname', nargs='?', metavar='NAME', help='Download dynamic library for this platform') cparser.set_defaults(func=_download) # # Command: runtime # cparser = subparsers.add_parser( 'runtime', epilog=_runtime.__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, help='Generate runtime package separately') cparser.add_argument('-O', '--output', metavar='PATH', default='dist', help='Output path, default is "%(default)s"') cparser.add_argument('-n', '--no-package', action='store_true', help='Generate runtime files without package') cparser.add_argument('-i', '--inside', action='store_true', help='Generate bootstrap script which is used ' 'inside one package') cparser.add_argument('-L', '--with-license', metavar='FILE', help='Replace default license with this file') cparser.add_argument('--platform', dest='platforms', metavar='NAME', action='append', help='Generate runtime package for this platform, ' 'use this option multiple times for more platforms') cparser.add_argument('--enable-suffix', action='store_true', help='Make unique runtime files and bootstrap code') cparser.add_argument('pkgname', nargs='?', default='pytransform', help=argparse.SUPPRESS) cparser.set_defaults(func=_runtime) return parser