def _register_subcommands(self, command_classes, parent_run_cmd, app_context: ApplicationContext): for command_class in command_classes: def wrapper(): c = command_class @click.pass_context def r(ctx: click.Context, *_, **kwargs): app_context.add_cmd_args(ctx.info_name, ctx.params) app_context.command_names.current = get_invoked_subommand( ctx.parent) app_context.command_names.invoked_subcommand = get_invoked_subommand( ctx) app_context.command_names.invoked_subcommand_primary_name = ctx.invoked_subcommand app_context.current_args = Node.create_from(ctx.params) for k, v in kwargs.items(): ctx.obj.add_arg(k, v) log_debug('Starting command', name=c.name) res = c().run(ctx.obj) if ctx.invoked_subcommand is None or res: ctx.exit(res) r.command_class = c return r try: cmd_opt_ctx = OptionContext() cmd_opt_ctx.register_args(command_class.register_arguments) cls = AliasedGroup if command_class.subcommand_classes else click.core.Command cmd_run = parent_run_cmd.command( name=command_class.name, help=command_class.description, cls=cls, context_settings=CONTEXT_SETTINGS)( cmd_opt_ctx.add_args_to_func(wrapper())) self._register_subcommands(command_class.subcommand_classes, cmd_run, app_context) except Exception as e: print( f'Error occurred while registering args for command `{command_class.name}`: {e}' ) raise
def run(self, args: typing.Optional[typing.List[str]] = None): single_command_mode = bool(self._command_class and len(self._command_classes) == 1) app_context = ApplicationContext() app_context.single_command_mode = single_command_mode app_context.config_directories = list( self._config_dir_registry.config_directories) app_context.environment = self._env_config.current_env @click.pass_context def app_run(ctx: click.Context, *args, **kwargs): app_context.add_cmd_args( '__main__', ctx.params, self._command_class.name if single_command_mode else '') app_context.command_names.invoked_subcommand = get_invoked_subommand( ctx) app_context.command_names.invoked_subcommand_primary_name = ctx.invoked_subcommand app_context.current_args = Node.create_from(ctx.params) ctx.obj = app_context ctx.obj.command_registry = self._command_registry ctx.obj.program_name = self._program_name for k, v in kwargs.items(): ctx.obj.add_arg(k, v) self._process_debug_opts(ctx.obj.args) if self._process_logging_options(ctx.obj.args): sys.exit(1) if self._enable_env_options and ctx.obj.args.environment: self._env_config.set_current_env(ctx.obj.args.environment) self._load_env() if single_command_mode: app_context.command_names.current = self._command_class.name res = self._command_class().run(app_context) if ctx.invoked_subcommand is None or res: ctx.exit(res) app_run.app_context = app_context app_opt_ctx = OptionContext() app_opt_ctx.register_args(self._register_app_args) if single_command_mode: app_opt_ctx.register_args(self._command_class.register_arguments) try: app_run = app_opt_ctx.add_args_to_func(app_run) except Exception as e: if single_command_mode: suffix = f'for command `{self._command_class.name}`' else: suffix = 'for the application' print(f'Error occurred while registering args {suffix}: {e}') raise if single_command_mode: has_classes = len(self._command_class.subcommand_classes) > 0 app_run = (click.group if has_classes else click.command)( self._program_name, help=self._description or self._command_class.description, context_settings=CONTEXT_SETTINGS, cls=(AppGroup if has_classes else AppCommand))(app_run) self._register_subcommands(self._command_class.subcommand_classes, app_run, app_context) else: self._command_registry.register_class(_ListAllCommand) self._command_registry.register_class(_ListCommand) app_run = click.group( self._program_name, cls=AppGroup, help=self._description, context_settings=CONTEXT_SETTINGS, )(app_run) self._register_subcommands(self._command_registry._command_classes, app_run, app_context) return app_run(args, self._program_name)