Added custom help formatters for subparsers

Signed-off-by: Maisam Arif <maisarif@amd.com>
Change-Id: Ib7209ad7188733fa2492cde302f5c82c9c9bfa42


[ROCm/amdsmi commit: ddc63db14c]
This commit is contained in:
Maisam Arif
2023-10-13 14:03:24 -05:00
committed by Maisam Arif
parent 12e45f96da
commit 4c90eef8ff
+57 -46
View File
@@ -34,18 +34,28 @@ import amdsmi_cli_exceptions
# Custom Help Formatter for increasing the action max length # Custom Help Formatter for increasing the action max length
class SubparserHelpFormatter(argparse.HelpFormatter): class AMDSMIParserHelpFormatter(argparse.HelpFormatter):
def __init__(self, prog, def __init__(self, prog):
indent_increment=2, super().__init__(prog=prog,
max_help_position=24, indent_increment=2,
width=90): max_help_position=24,
super().__init__(prog, width=90)
indent_increment=indent_increment,
max_help_position=max_help_position,
width=width)
self._action_max_length = 20 self._action_max_length = 20
# Custom Help Formatter for not duplicating the metavar in the subparsers
class AMDSMISubparserHelpFormatter(argparse.RawTextHelpFormatter):
def __init__(self, prog):
super().__init__(prog, max_help_position=80, width=90)
def _format_action_invocation(self, action):
if not action.option_strings or action.nargs == 0:
return super()._format_action_invocation(action)
default = self._get_default_metavar_for_optional(action)
args_string = self._format_args(action, default)
return ', '.join(action.option_strings) + ' ' + args_string
class AMDSMIParser(argparse.ArgumentParser): class AMDSMIParser(argparse.ArgumentParser):
"""Unified Parser for AMDSMI CLI. """Unified Parser for AMDSMI CLI.
This parser doesn't access amdsmi's lib directly,but via AMDSMIHelpers, This parser doesn't access amdsmi's lib directly,but via AMDSMIHelpers,
@@ -69,32 +79,32 @@ class AMDSMIParser(argparse.ArgumentParser):
# Adjust argument parser options # Adjust argument parser options
super().__init__( super().__init__(
formatter_class= lambda prog: SubparserHelpFormatter(prog), formatter_class= lambda prog: AMDSMIParserHelpFormatter(prog),
description=f"AMD System Management Interface | {version_string} | {platform_string}", description=f"AMD System Management Interface | {version_string} | {platform_string}",
add_help=True, add_help=True,
prog=program_name) prog=program_name)
# Setup subparsers # Setup subparsers
subparsers = self.add_subparsers( self.subparsers = self.add_subparsers(
title="AMD-SMI Commands", title="AMD-SMI Commands",
parser_class=argparse.ArgumentParser, parser_class=argparse.ArgumentParser,
help="Descriptions:", help="Descriptions:",
metavar='') metavar='')
# Add all subparsers # Add all subparsers
self._add_version_parser(subparsers, version) self._add_version_parser(self.subparsers, version)
self._add_list_parser(subparsers, list) self._add_list_parser(self.subparsers, list)
self._add_static_parser(subparsers, static) self._add_static_parser(self.subparsers, static)
self._add_firmware_parser(subparsers, firmware) self._add_firmware_parser(self.subparsers, firmware)
self._add_bad_pages_parser(subparsers, bad_pages) self._add_bad_pages_parser(self.subparsers, bad_pages)
self._add_metric_parser(subparsers, metric) self._add_metric_parser(self.subparsers, metric)
self._add_process_parser(subparsers, process) self._add_process_parser(self.subparsers, process)
self._add_profile_parser(subparsers, profile) self._add_profile_parser(self.subparsers, profile)
self._add_event_parser(subparsers, event) self._add_event_parser(self.subparsers, event)
self._add_topology_parser(subparsers, topology) self._add_topology_parser(self.subparsers, topology)
self._add_set_value_parser(subparsers, set_value) self._add_set_value_parser(self.subparsers, set_value)
self._add_reset_parser(subparsers, reset) self._add_reset_parser(self.subparsers, reset)
self._add_rocm_smi_parser(subparsers, rocmsmi) self._add_rocm_smi_parser(self.subparsers, rocmsmi)
def _positive_int(self, int_value): def _positive_int(self, int_value):
@@ -212,7 +222,8 @@ class AMDSMIParser(argparse.ArgumentParser):
json_help = "Displays output in JSON format (human readable by default)." json_help = "Displays output in JSON format (human readable by default)."
csv_help = "Displays output in CSV format (human readable by default)." csv_help = "Displays output in CSV format (human readable by default)."
file_help = "Saves output into a file on the provided path (stdout by default)." file_help = "Saves output into a file on the provided path (stdout by default)."
loglevel_help = "Set the logging level for the parser commands (ERROR by default)." loglevel_choices = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
loglevel_help = f"Set the logging level from the possible choices:\n{loglevel_choices}"
command_modifier_group = subcommand_parser.add_argument_group('Command Modifiers') command_modifier_group = subcommand_parser.add_argument_group('Command Modifiers')
@@ -223,22 +234,22 @@ class AMDSMIParser(argparse.ArgumentParser):
command_modifier_group.add_argument('--file', action=self._check_output_file_path(), type=str, required=False, help=file_help) command_modifier_group.add_argument('--file', action=self._check_output_file_path(), type=str, required=False, help=file_help)
# Placing loglevel outside the subcommands so it can be used with any subcommand # Placing loglevel outside the subcommands so it can be used with any subcommand
command_modifier_group.add_argument('--loglevel', action='store', required=False, help=loglevel_help, default='ERROR', command_modifier_group.add_argument('--loglevel', action='store', required=False, help=loglevel_help, default='ERROR', metavar='LEVEL',
choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]) choices=loglevel_choices)
def _add_watch_arguments(self, subcommand_parser): def _add_watch_arguments(self, subcommand_parser):
# Device arguments help text # Device arguments help text
watch_help = "Reprint the command in a loop of Interval seconds" watch_help = "Reprint the command in a loop of INTERVAL seconds"
watch_time_help = "The total time to watch the given command" watch_time_help = "The total TIME to watch the given command"
iterations_help = "Total number of iterations to loop on the given command" iterations_help = "Total number of ITERATIONS to loop on the given command"
# Mutually Exclusive Args within the subparser # Mutually Exclusive Args within the subparser
subcommand_parser.add_argument('-w', '--watch', action='store', metavar='loop_time', subcommand_parser.add_argument('-w', '--watch', action='store', metavar='INTERVAL',
type=self._positive_int, required=False, help=watch_help) type=self._positive_int, required=False, help=watch_help)
subcommand_parser.add_argument('-W', '--watch_time', action=self._check_watch_selected(), metavar='total_loop_time', subcommand_parser.add_argument('-W', '--watch_time', action=self._check_watch_selected(), metavar='TIME',
type=self._positive_int, required=False, help=watch_time_help) type=self._positive_int, required=False, help=watch_time_help)
subcommand_parser.add_argument('-i', '--iterations', action=self._check_watch_selected(), metavar='number_of_iterations', subcommand_parser.add_argument('-i', '--iterations', action=self._check_watch_selected(), metavar='ITERATIONS',
type=self._positive_int, required=False, help=iterations_help) type=self._positive_int, required=False, help=iterations_help)
@@ -265,7 +276,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create version subparser # Create version subparser
version_parser = subparsers.add_parser('version', help=version_help, description=None) version_parser = subparsers.add_parser('version', help=version_help, description=None)
version_parser._optionals.title = None version_parser._optionals.title = None
version_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) version_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
version_parser.set_defaults(func=func) version_parser.set_defaults(func=func)
self._add_command_modifiers(version_parser) self._add_command_modifiers(version_parser)
@@ -281,7 +292,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create list subparser # Create list subparser
list_parser = subparsers.add_parser('list', help=list_help, description=list_subcommand_help) list_parser = subparsers.add_parser('list', help=list_help, description=list_subcommand_help)
list_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) list_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
list_parser.set_defaults(func=func) list_parser.set_defaults(func=func)
# Add Command Modifiers # Add Command Modifiers
@@ -321,7 +332,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create static subparser # Create static subparser
static_parser = subparsers.add_parser('static', help=static_help, description=static_subcommand_help) static_parser = subparsers.add_parser('static', help=static_help, description=static_subcommand_help)
static_parser._optionals.title = static_optionals_title static_parser._optionals.title = static_optionals_title
static_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) static_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
static_parser.set_defaults(func=func) static_parser.set_defaults(func=func)
self._add_command_modifiers(static_parser) self._add_command_modifiers(static_parser)
@@ -365,7 +376,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create firmware subparser # Create firmware subparser
firmware_parser = subparsers.add_parser('firmware', help=firmware_help, description=firmware_subcommand_help, aliases=['ucode']) firmware_parser = subparsers.add_parser('firmware', help=firmware_help, description=firmware_subcommand_help, aliases=['ucode'])
firmware_parser._optionals.title = firmware_optionals_title firmware_parser._optionals.title = firmware_optionals_title
firmware_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) firmware_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
firmware_parser.set_defaults(func=func) firmware_parser.set_defaults(func=func)
self._add_command_modifiers(firmware_parser) self._add_command_modifiers(firmware_parser)
@@ -398,7 +409,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create bad_pages subparser # Create bad_pages subparser
bad_pages_parser = subparsers.add_parser('bad-pages', help=bad_pages_help, description=bad_pages_subcommand_help) bad_pages_parser = subparsers.add_parser('bad-pages', help=bad_pages_help, description=bad_pages_subcommand_help)
bad_pages_parser._optionals.title = bad_pages_optionals_title bad_pages_parser._optionals.title = bad_pages_optionals_title
bad_pages_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) bad_pages_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
bad_pages_parser.set_defaults(func=func) bad_pages_parser.set_defaults(func=func)
self._add_command_modifiers(bad_pages_parser) self._add_command_modifiers(bad_pages_parser)
@@ -448,7 +459,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create metric subparser # Create metric subparser
metric_parser = subparsers.add_parser('metric', help=metric_help, description=metric_subcommand_help) metric_parser = subparsers.add_parser('metric', help=metric_help, description=metric_subcommand_help)
metric_parser._optionals.title = metric_optionals_title metric_parser._optionals.title = metric_optionals_title
metric_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) metric_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
metric_parser.set_defaults(func=func) metric_parser.set_defaults(func=func)
self._add_command_modifiers(metric_parser) self._add_command_modifiers(metric_parser)
@@ -511,7 +522,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create process subparser # Create process subparser
process_parser = subparsers.add_parser('process', help=process_help, description=process_subcommand_help) process_parser = subparsers.add_parser('process', help=process_help, description=process_subcommand_help)
process_parser._optionals.title = process_optionals_title process_parser._optionals.title = process_optionals_title
process_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) process_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
process_parser.set_defaults(func=func) process_parser.set_defaults(func=func)
self._add_command_modifiers(process_parser) self._add_command_modifiers(process_parser)
@@ -541,7 +552,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create profile subparser # Create profile subparser
profile_parser = subparsers.add_parser('profile', help=profile_help, description=profile_subcommand_help) profile_parser = subparsers.add_parser('profile', help=profile_help, description=profile_subcommand_help)
profile_parser._optionals.title = profile_optionals_title profile_parser._optionals.title = profile_optionals_title
profile_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) profile_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
profile_parser.set_defaults(func=func) profile_parser.set_defaults(func=func)
self._add_command_modifiers(profile_parser) self._add_command_modifiers(profile_parser)
@@ -562,7 +573,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create event subparser # Create event subparser
event_parser = subparsers.add_parser('event', help=event_help, description=event_subcommand_help) event_parser = subparsers.add_parser('event', help=event_help, description=event_subcommand_help)
event_parser._optionals.title = event_optionals_title event_parser._optionals.title = event_optionals_title
event_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) event_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
event_parser.set_defaults(func=func) event_parser.set_defaults(func=func)
self._add_command_modifiers(event_parser) self._add_command_modifiers(event_parser)
@@ -591,7 +602,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create topology subparser # Create topology subparser
topology_parser = subparsers.add_parser('topology', help=topology_help, description=topology_subcommand_help) topology_parser = subparsers.add_parser('topology', help=topology_help, description=topology_subcommand_help)
topology_parser._optionals.title = topology_optionals_title topology_parser._optionals.title = topology_optionals_title
topology_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) topology_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
topology_parser.set_defaults(func=func) topology_parser.set_defaults(func=func)
self._add_command_modifiers(topology_parser) self._add_command_modifiers(topology_parser)
@@ -628,7 +639,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create set_value subparser # Create set_value subparser
set_value_parser = subparsers.add_parser('set', help=set_value_help, description=set_value_subcommand_help) set_value_parser = subparsers.add_parser('set', help=set_value_help, description=set_value_subcommand_help)
set_value_parser._optionals.title = set_value_optionals_title set_value_parser._optionals.title = set_value_optionals_title
set_value_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) set_value_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
set_value_parser.set_defaults(func=func) set_value_parser.set_defaults(func=func)
self._add_command_modifiers(set_value_parser) self._add_command_modifiers(set_value_parser)
@@ -761,7 +772,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create reset subparser # Create reset subparser
reset_parser = subparsers.add_parser('reset', help=reset_help, description=reset_subcommand_help) reset_parser = subparsers.add_parser('reset', help=reset_help, description=reset_subcommand_help)
reset_parser._optionals.title = reset_optionals_title reset_parser._optionals.title = reset_optionals_title
reset_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) reset_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
reset_parser.set_defaults(func=func) reset_parser.set_defaults(func=func)
self._add_command_modifiers(reset_parser) self._add_command_modifiers(reset_parser)
@@ -802,7 +813,7 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create rocm_smi subparser # Create rocm_smi subparser
rocm_smi_parser = subparsers.add_parser('rocm-smi', help=rocm_smi_help, description=rocm_smi_subcommand_help) rocm_smi_parser = subparsers.add_parser('rocm-smi', help=rocm_smi_help, description=rocm_smi_subcommand_help)
rocm_smi_parser._optionals.title = rocm_smi_optionals_title rocm_smi_parser._optionals.title = rocm_smi_optionals_title
rocm_smi_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90) rocm_smi_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
rocm_smi_parser.set_defaults(func=func) rocm_smi_parser.set_defaults(func=func)
self._add_command_modifiers(rocm_smi_parser) self._add_command_modifiers(rocm_smi_parser)