tools/automation/cli_linter/__init__.py (62 lines of code) (raw):

# -------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- import sys import os import yaml from knack.help_files import helps from .linter import LinterManager def define_arguments(parser): parser.add_argument('--ci', action='store_true', help='Run in CI mode') parser.add_argument('--params', dest='rule_types_to_run', action='append_const', const='params', help='Run linter on parameters.') parser.add_argument('--commands', dest='rule_types_to_run', action='append_const', const='commands', help='Run linter on commands.') parser.add_argument('--command-groups', dest='rule_types_to_run', action='append_const', const='command_groups', help='Run linter on command groups.') parser.add_argument('--help-file-entries', dest='rule_types_to_run', action='append_const', const='help_entries', help='Run linter on help-file-entries.') parser.add_argument('--modules', dest='modules', nargs='+', help='The modules on which the linter should run.') parser.add_argument('--extensions', dest='extensions', nargs='+', help='The extensions on which the linter should run.') parser.add_argument('--rules', dest='rules', nargs='+', help='The rules which the linter should run.') def main(args): from azure.cli.core import get_default_cli from azure.cli.core.file_util import get_all_help, create_invoker_and_load_cmds_and_args print('Initializing linter with command table and help files...') # setup CLI to enable command loader az_cli = get_default_cli() # load commands, args, and help create_invoker_and_load_cmds_and_args(az_cli) loaded_help = get_all_help(az_cli) command_loader = az_cli.invocation.commands_loader # format loaded help loaded_help = {data.command: data for data in loaded_help if data.command} # load yaml help help_file_entries = {} for entry_name, help_yaml in helps.items(): help_entry = yaml.safe_load(help_yaml) help_file_entries[entry_name] = help_entry if not args.rule_types_to_run: args.rule_types_to_run = ['params', 'commands', 'command_groups', 'help_entries'] # find rule exclusions and pass to linter manager from ..utilities.path import get_command_modules_paths, get_extensions_paths exclusions = {} command_modules_paths = get_command_modules_paths() extension_paths = get_extensions_paths() for gen in (command_modules_paths, extension_paths): for _, path in gen: exclusion_path = os.path.join(path, 'linter_exclusions.yml') if os.path.isfile(exclusion_path): mod_exclusions = yaml.safe_load(open(exclusion_path)) exclusions.update(mod_exclusions) # only run linter on modules and extensions specified if args.modules or args.extensions: from .util import include_commands command_loader, help_file_entries = include_commands( command_loader, help_file_entries, module_inclusions=args.modules, extensions=args.extensions) # Instantiate and run Linter linter_manager = LinterManager(command_loader=command_loader, help_file_entries=help_file_entries, loaded_help=loaded_help, exclusions=exclusions, rule_inclusions=args.rules) exit_code = linter_manager.run(run_params='params' in args.rule_types_to_run, run_commands='commands' in args.rule_types_to_run, run_command_groups='command_groups' in args.rule_types_to_run, run_help_files_entries='help_entries' in args.rule_types_to_run, ci=args.ci) sys.exit(exit_code) def init_args(root): parser = root.add_parser('cli-lint', help="Verify the contents of the command table and help.") define_arguments(parser) parser.set_defaults(func=main)