В примере ниже продемонстрировано использование субкоманд (или «подкоманд«) с использованием модуля argparse.
К примеру, в предыдущем проекте скрипт управления приложением имел около 20-ти различных опцией (был написан на BASH с использованием getopts()), при том что букв в английском алфавите — 26.
В новом проекте — имеется аналогичный скрипт, но на Python.
Приложение состоит из нескольких частей, и для каждой хочется иметь возможность вызывать опции --deploy или --makeconf.
Реализуется такое с помощью метода add_subparsers:
import argparse
...
def getopts():
"""Create list from called options"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='Application part to act with')
# unity options
# parser.add_argument('-r', '--refresh', nargs='?', const='dev', help=('Refresh modules DLLs and xml files'))
# parser.add_argument('-r', '--refresh', choices=['dev', 'ci'], help=('Refresh modules DLLs and xml files'))
### добавляем новый аргумент `unity`, который будет играть роль "пространства имён" для опций
# таким образом - мы можем использовать например --deploy или -d в разных аргументах
# при этом с помощью set_defaults(func=handler_unity) мы определяем, какая функция будет заниматься
### обработкой аргументов для этого "пространства имён"
parser_unity = subparsers.add_parser('unity', help='Unity application')
parser_unity.set_defaults(func=handler_unity)
parser_unity.add_argument('-r', '--refresh', action='store_true', dest='unity_refresh', help='Copy necessarry DLLs to MainApplication\Assets\PreparedPlugins and NGUIProject\Assets\PreparedPlugins')
parser_unity.add_argument('-t', '--tagcheck', action='store_true', dest='unity_tagcheck', help='Check tags in .csproj files')
parser_unity.add_argument('-b', '--buildtype', nargs='?', choices=['dev', 'ci'], default='dev', dest='unity_buildtype', help='Select unity - for developer or CI server')
parser_unity.add_argument('-c', '--confgen', action='store_true', dest='unity_confgen', help='Generate config.xml and XMLs for each module with TAG = 'CLOUD'')
parser_unity.add_argument('-u', '--uuidgen', action='store', dest='unity_uuidgen', help='Generate UUIDs for each module in Plugins.sln. Must be called with 'config_name' as first argument and optionally - with `-b ci` option')
parser_unity.add_argument('-l', '--configlist', action='store_true', dest='unity_configlist', help='Display configuration names in uuids.ini')
parser_unity.add_argument('-d', '--deploy', action='store_true', dest='unity_deploy', help='Deploy Unity project to appropriate URL')
# Cloudlibrary options
parser_rds = subparsers.add_parser('clc', help='Cloudlibrary options')
parser_rds.set_defaults(func=handler_clc)
parser_rds.add_argument('-d', '--deploy', dest='clc_deploy', action='store_true', help='Update RDSmanager from repository')
# for Clc lib external usage
parser_rds.add_argument('-u', '--user', action='store', dest='clc_user', help='Username for authorization')
parser_rds.add_argument('-x', '--password', action='store', dest='clc_password', help='Password for authorization')
parser_rds.add_argument('-f', '--file', action='store', dest='clc_file', help='Specify local file to save to/upload from')
# Cloudlibrary requests types
parser_rds.add_argument('-g', '--get', action='store', dest='clc_get', help='Request type GET')
parser_rds.add_argument('-p', '--put', action='store', dest='clc_put', help='Request type PUT')
parser_rds.add_argument('--delete', action='store', dest='clc_del', help='Request type DELETE')
# RDSmanager own options
parser_rds = subparsers.add_parser('rds', help='RDSmanager options')
parser_rds.set_defaults(func=handler_rds)
parser_rds.add_argument('-s', '--selfupgrade', dest='rds_selfupgrade', action='store_true', help='Update RDSmanager from repository')
parser_rds.add_argument('-T', '--test', action='store_true', dest='rds_test', help='Temporary test option')
if len(sys.argv) <= 1:
parser.print_help()
sys.exit(1)
else:
res = parser.parse_args()
res.func(res)
def handler_unity(action_list):
"""Check Unity namespace options"""
if action_list.unity_tagcheck:
logger.logger.info('Running tagcheck')
from lib.unity import tag_checker
tag_checker.main(logger)
if action_list.unity_refresh:
logger.logger.info('Running refresh modules')
from lib.unity import refresh
refresh.refresh(logger)
if action_list.unity_confgen:
logger.logger.info('Running confgen')
from lib.unity import confgen
confgen.main(logger, RDS_BASEDIR, action_list.unity_buildtype)
if action_list.unity_uuidgen:
logger.logger.info('Running UUID generator with %s' % action_list.unity_uuidgen)
from lib.unity import uuidgen
uuidgen.uuidgen(logger, RDS_BASEDIR, action_list.unity_uuidgen, action_list.unity_buildtype)
if action_list.unity_configlist:
logger.logger.info('Running configlist')
from lib.unity import confgen
confgen.configlist(logger, RDS_BASEDIR)
if action_list.unity_deploy:
logger.logger.info('Running DEPLOY buildtype = %s' % action_list.unity_buildtype)
from lib.unity import deploy
deploy.main(logger, CLC_USER, CLC_PASSWORD, RDS_BASEDIR, action_list.unity_buildtype)
def handler_clc(action_list):
"""Check Cloudlibrary namespace options"""
if action_list.clc_deploy:
from lib.clc import deploy
deploy.deploy(logger, RDS_BASEDIR)
if action_list.clc_get:
from lib.external.rds_clc import RdsClc
if not action_list.clc_user and not action_list.clc_password:
logger.logger.info('Nether CLC_USER not CLC_PASSWORD found, using default values')
action_list.clc_user = CLC_USER
action_list.clc_password = CLC_PASSWORD
req = RdsClc(action_list.clc_user, action_list.clc_password)
req.cloud_get(action_list.clc_get, action_list.clc_file)
if action_list.clc_put:
from lib.external.rds_clc import RdsClc
if not action_list.clc_user and not action_list.clc_password:
logger.logger.info('Nether CLC_USER not CLC_PASSWORD found, using default values')
action_list.clc_user = CLC_USER
action_list.clc_password = CLC_PASSWORD
req = RdsClc(action_list.clc_user, action_list.clc_password)
req.cloud_put(action_list.clc_put, action_list.clc_file)
if action_list.clc_del:
from lib.external.rds_clc import RdsClc
if not action_list.clc_user and not action_list.clc_password:
logger.logger.info('Nether CLC_USER not CLC_PASSWORD found, using default values')
action_list.clc_user = CLC_USER
action_list.clc_password = CLC_PASSWORD
req = RdsClc(action_list.clc_user, action_list.clc_password)
req.cloud_delete(action_list.clc_del)
def handler_rds(action_list):
"""Check RDS namespace options"""
if action_list.rds_test:
logger.logger.info('Running TEST option')
from lib.external import testing5
testing5.test(logger)
if action_list.rds_selfupgrade:
logger.logger.info('Running self-upgrade')
from lib.service import manager
manager.selfupgrade(logger, RDS_BASEDIR)
if __name__ == '__main__':
logger = Logger(RDS_BASEDIR)
logger.logger('RDSmanager')
logger.logger.info('RDSmanager started at %s' % (time.strftime('%d, %b %Y at %H:%M:%S')))
getopts()
Помощь теперь выглядит так:
d:RDSrdsmanager>RDSmanager.py rds -h RDSmanager started at 25, Jun 2015 at 18:26:46 usage: RDSmanager.py rds [-h] [-s] [-T] optional arguments: -h, --help show this help message and exit -s, --selfupgrade Update RDSmanager from repository -T, --test Temporary test option
d:RDSrdsmanager>RDSmanager.py clc -h
RDSmanager started at 25, Jun 2015 at 18:37:04
usage: RDSmanager.py clc [-h] [-d] [-u CLC_USER] [-x CLC_PASSWORD]
[-f CLC_FILE] [-g CLC_GET] [-p CLC_PUT]
[--delete CLC_DEL]
optional arguments:
-h, --help show this help message and exit
-d, --deploy Update RDSmanager from repository
-u CLC_USER, --user CLC_USER
Username for authorization
-x CLC_PASSWORD, --password CLC_PASSWORD
Password for authorization
-f CLC_FILE, --file CLC_FILE
Specify local file to save to/upload from
-g CLC_GET, --get CLC_GET
Request type GET
-p CLC_PUT, --put CLC_PUT
Request type PUT
--delete CLC_DEL Request type DELETE
И так далее.




