I haven't used argparse in 10 years, but I understand it and what I have below does work as I want it to work... but this is going to get a lot more complicated as I continue adding commands, parsers and subparsers. I'm wondering what the best way is to organize this? In my mind I should be able to see the command sequence in the text nearly as clearly as I see it in my diagram... but everytime I look at it, after being away for a while, my brain swims as I try to follow it. There has to be a better way to organize this right?
import argparse
from modules import cli_tools
#LVL 1: create the top-level parser for the "sacs" command.
sacs_parser = argparse.ArgumentParser(prog = 'sacs', description = 'Master Command For Controlling SACS.')
sacs_subparsers = sacs_parser.add_subparsers(help='Management Module Selector.')
#LVL 2: create the second-level parsers for the "sacs [module]" commands.
csv_parser = sacs_subparsers.add_parser('csv', help='Generic CSV Management Module.')
am_parser = sacs_subparsers.add_parser('am', help='SACS Asset Management Module.')
mm_parser = sacs_subparsers.add_parser('mm', help='SACS Metric Management Module.')
#LVL 3: create the third-level subparser for the "sacs [module] [action]" commands.
csv_action_subparser = csv_parser.add_subparsers(help='The action to perform.')
mm_action_subparser = mm_parser.add_subparsers(help='The action to perform.')
#LVL 4: create the fourth-level subparser for the "sacs [module] [action] [type]" commands.
mm_create_parser = mm_action_subparser.add_parser('create', help='Used to Create a new event/asset input file.')
mm_create_type_parser = mm_create_parser.add_subparsers(help='The type of file to create.')
#LVL 5: create the fifth-level parser for the "sacs [module] [action] [type]" commands.
csv_reconcile_parser = csv_action_subparser.add_parser('reconcile', help='reconcile two csvs.')
mm_create_asset_parser = mm_create_type_parser.add_parser('assets', help='Create an Asset File.')
mm_create_asset_subtype_parser = mm_create_asset_parser.add_subparsers(help='The type of file to create.')
mm_create_event_parser = mm_create_type_parser.add_parser('events', help='Create an Event File.')
#LVL 6: create the sixth-level parser for the "sacs [module] [action] [type] [subtype]" commands.
mm_create_asset_uaid_parser = mm_create_asset_subtype_parser.add_parser('uaid', help='Create an Asset File with UAID as the primary key.')
mm_create_asset_vid_parser = mm_create_asset_subtype_parser.add_parser('vid', help='Create an Asset File with Vulnerability ID as the primary key.')
#COMMAND ARGS: Add Arguments to the final command "sacs csv reconcile [args]"
csv_reconcile_parser.add_argument('key', help='The name of the field that holds the unique ID to compare against.')
csv_reconcile_parser.add_argument('inputfile1', help='The master file (used when same record exists in both files).')
csv_reconcile_parser.add_argument('inputfile2', help='The secondary file, which is trumped by the master file.')
csv_reconcile_parser.add_argument('outputfile', help='The output file; note it will be overwritten if it exists.')
csv_reconcile_parser.set_defaults(func=cli_tools.csv_reconcile)
#COMMAND ARGS: Add Arguments to the final command "sacs mm create assets uaid [args]"
mm_create_asset_uaid_parser.add_argument('appmapp_file', help='The input file.')
mm_create_asset_uaid_parser.add_argument('output_file', help='The output file.')
mm_create_asset_uaid_parser.set_defaults(func=cli_tools.asset_create_uaid)
#COMMAND ARGS: Add Arguments to the final command "sacs mm create assets vid [args]"
mm_create_asset_vid_parser.add_argument('vulnerability_file', help='The input file.')
mm_create_asset_vid_parser.add_argument('appmapp_file', help='The output file.')
mm_create_asset_vid_parser.add_argument('output_file', help='The output file.')
mm_create_asset_vid_parser.set_defaults(func=cli_tools.asset_create_vid)
args = sacs_parser.parse_args()
args.func(args)
Potential avenues to better way:
- parser/subparser renaming.
- change the ordering of the statements.
- some way to indent without messing with python.
All ideas are on the table, I want to see how others deal with this while designing complex commands.