summaryrefslogtreecommitdiff
path: root/venv/lib/python3.11/site-packages/rich_click/rich_click.py
diff options
context:
space:
mode:
Diffstat (limited to 'venv/lib/python3.11/site-packages/rich_click/rich_click.py')
-rw-r--r--venv/lib/python3.11/site-packages/rich_click/rich_click.py893
1 files changed, 0 insertions, 893 deletions
diff --git a/venv/lib/python3.11/site-packages/rich_click/rich_click.py b/venv/lib/python3.11/site-packages/rich_click/rich_click.py
deleted file mode 100644
index 215c170..0000000
--- a/venv/lib/python3.11/site-packages/rich_click/rich_click.py
+++ /dev/null
@@ -1,893 +0,0 @@
-import inspect
-import re
-from typing import Dict, Iterable, List, Optional, Tuple, TYPE_CHECKING, Union
-
-import click
-import rich.columns
-import rich.markdown
-import rich.text
-
-# Due to how rich_click.cli.patch() works, it is safer to import Command types directly
-# rather than use the click module e.g. click.Command
-from click import Command, Group
-from rich import box
-from rich.align import Align
-from rich.columns import Columns
-from rich.emoji import Emoji
-from rich.highlighter import RegexHighlighter
-from rich.markdown import Markdown
-from rich.padding import Padding
-from rich.panel import Panel
-from rich.style import StyleType
-from rich.table import Table
-from rich.text import Text
-from typing_extensions import Literal
-
-from rich_click._compat_click import CLICK_IS_BEFORE_VERSION_8X, CLICK_IS_BEFORE_VERSION_9X, CLICK_IS_VERSION_80
-from rich_click.rich_help_configuration import (
- force_terminal_default,
- OptionHighlighter,
- RichHelpConfiguration,
- terminal_width_default,
-)
-from rich_click.rich_help_formatter import RichHelpFormatter
-
-# Support rich <= 10.6.0
-try:
- from rich.console import group
-except ImportError:
- from rich.console import render_group as group # type: ignore[attr-defined,no-redef]
-
-
-if CLICK_IS_BEFORE_VERSION_9X:
- from click import MultiCommand
-else:
- MultiCommand = Group # type: ignore[misc,assignment]
-
-
-# Default styles
-STYLE_OPTION: rich.style.StyleType = "bold cyan"
-STYLE_ARGUMENT: rich.style.StyleType = "bold cyan"
-STYLE_COMMAND: rich.style.StyleType = "bold cyan"
-STYLE_SWITCH: rich.style.StyleType = "bold green"
-STYLE_METAVAR: rich.style.StyleType = "bold yellow"
-STYLE_METAVAR_APPEND: rich.style.StyleType = "dim yellow"
-STYLE_METAVAR_SEPARATOR: rich.style.StyleType = "dim"
-STYLE_HEADER_TEXT: rich.style.StyleType = ""
-STYLE_EPILOG_TEXT: rich.style.StyleType = ""
-STYLE_FOOTER_TEXT: rich.style.StyleType = ""
-STYLE_USAGE: rich.style.StyleType = "yellow"
-STYLE_USAGE_COMMAND: rich.style.StyleType = "bold"
-STYLE_DEPRECATED: rich.style.StyleType = "red"
-STYLE_HELPTEXT_FIRST_LINE: rich.style.StyleType = ""
-STYLE_HELPTEXT: rich.style.StyleType = "dim"
-STYLE_OPTION_HELP: rich.style.StyleType = ""
-STYLE_OPTION_DEFAULT: rich.style.StyleType = "dim"
-STYLE_OPTION_ENVVAR: rich.style.StyleType = "dim yellow"
-STYLE_REQUIRED_SHORT: rich.style.StyleType = "red"
-STYLE_REQUIRED_LONG: rich.style.StyleType = "dim red"
-STYLE_OPTIONS_PANEL_BORDER: rich.style.StyleType = "dim"
-ALIGN_OPTIONS_PANEL: rich.align.AlignMethod = "left"
-STYLE_OPTIONS_TABLE_SHOW_LINES: bool = False
-STYLE_OPTIONS_TABLE_LEADING: int = 0
-STYLE_OPTIONS_TABLE_PAD_EDGE: bool = False
-STYLE_OPTIONS_TABLE_PADDING: rich.padding.PaddingDimensions = (0, 1)
-STYLE_OPTIONS_TABLE_BOX: rich.style.StyleType = ""
-STYLE_OPTIONS_TABLE_ROW_STYLES: Optional[List[rich.style.StyleType]] = None
-STYLE_OPTIONS_TABLE_BORDER_STYLE: Optional[rich.style.StyleType] = None
-STYLE_COMMANDS_PANEL_BORDER: rich.style.StyleType = "dim"
-ALIGN_COMMANDS_PANEL: rich.align.AlignMethod = "left"
-STYLE_COMMANDS_TABLE_SHOW_LINES: bool = False
-STYLE_COMMANDS_TABLE_LEADING: int = 0
-STYLE_COMMANDS_TABLE_PAD_EDGE: bool = False
-STYLE_COMMANDS_TABLE_PADDING: rich.padding.PaddingDimensions = (0, 1)
-STYLE_COMMANDS_TABLE_BOX: rich.style.StyleType = ""
-STYLE_COMMANDS_TABLE_ROW_STYLES: Optional[List[rich.style.StyleType]] = None
-STYLE_COMMANDS_TABLE_BORDER_STYLE: Optional[rich.style.StyleType] = None
-STYLE_COMMANDS_TABLE_COLUMN_WIDTH_RATIO: Optional[Union[Tuple[None, None], Tuple[int, int]]] = (None, None)
-STYLE_ERRORS_PANEL_BORDER: rich.style.StyleType = "red"
-ALIGN_ERRORS_PANEL: rich.align.AlignMethod = "left"
-STYLE_ERRORS_SUGGESTION: rich.style.StyleType = "dim"
-STYLE_ERRORS_SUGGESTION_COMMAND: rich.style.StyleType = "blue"
-STYLE_ABORTED: rich.style.StyleType = "red"
-WIDTH: Optional[int] = terminal_width_default()
-MAX_WIDTH: Optional[int] = terminal_width_default()
-COLOR_SYSTEM: Optional[
- Literal["auto", "standard", "256", "truecolor", "windows"]
-] = "auto" # Set to None to disable colors
-FORCE_TERMINAL: Optional[bool] = force_terminal_default()
-
-# Fixed strings
-HEADER_TEXT: Optional[str] = None
-FOOTER_TEXT: Optional[str] = None
-DEPRECATED_STRING: str = "(Deprecated) "
-DEFAULT_STRING: str = "[default: {}]"
-ENVVAR_STRING: str = "[env var: {}]"
-REQUIRED_SHORT_STRING: str = "*"
-REQUIRED_LONG_STRING: str = "[required]"
-RANGE_STRING: str = " [{}]"
-APPEND_METAVARS_HELP_STRING: str = "({})"
-ARGUMENTS_PANEL_TITLE: str = "Arguments"
-OPTIONS_PANEL_TITLE: str = "Options"
-COMMANDS_PANEL_TITLE: str = "Commands"
-ERRORS_PANEL_TITLE: str = "Error"
-ERRORS_SUGGESTION: Optional[str] = None # Default: Try 'cmd -h' for help. Set to False to disable.
-ERRORS_EPILOGUE: Optional[str] = None
-ABORTED_TEXT: str = "Aborted."
-
-# Behaviours
-SHOW_ARGUMENTS: bool = False # Show positional arguments
-SHOW_METAVARS_COLUMN: bool = True # Show a column with the option metavar (eg. INTEGER)
-APPEND_METAVARS_HELP: bool = False # Append metavar (eg. [TEXT]) after the help text
-GROUP_ARGUMENTS_OPTIONS: bool = False # Show arguments with options instead of in own panel
-OPTION_ENVVAR_FIRST: bool = False # Show env vars before option help text instead of avert
-USE_MARKDOWN: bool = False # Parse help strings as markdown
-USE_MARKDOWN_EMOJI: bool = True # Parse emoji codes in markdown :smile:
-USE_RICH_MARKUP: bool = False # Parse help strings for rich markup (eg. [red]my text[/])
-# Define sorted groups of panels to display subcommands
-COMMAND_GROUPS: Dict[str, List[Dict[str, Union[str, List[str]]]]] = {}
-# Define sorted groups of panels to display options and arguments
-OPTION_GROUPS: Dict[str, List[Dict[str, Union[str, List[str], Dict[str, List[str]]]]]] = {}
-USE_CLICK_SHORT_HELP: bool = False # Use click's default function to truncate help text
-
-highlighter: rich.highlighter.Highlighter = OptionHighlighter()
-_formatter: Optional[RichHelpFormatter] = None
-
-
-def _get_rich_formatter(formatter: Optional[click.HelpFormatter] = None) -> RichHelpFormatter:
- """Get Rich Help Formatter.
-
- Resolves the rich help formatter from the following:
- - formatter, if exists and is a `RichHelpFormatter` object
- - cached, module-level formatter
- - active click Context, that is cached as module-level attr
- - module-level settings (default)
-
- Args:
- formatter: A possible Rich help formatter
- """
- if formatter and isinstance(formatter, RichHelpFormatter):
- return formatter
-
- global _formatter
- if _formatter:
- return _formatter
- ctx = click.get_current_context(True)
- if ctx:
- formatter = ctx.make_formatter()
- if isinstance(formatter, RichHelpFormatter):
- _formatter = formatter
- return _formatter
-
- _formatter = RichHelpFormatter(config=get_module_help_configuration())
- return _formatter
-
-
-def _make_rich_rext(
- text: str, style: StyleType = "", formatter: Optional[RichHelpFormatter] = None
-) -> Union[rich.markdown.Markdown, Text]:
- """Take a string, remove indentations, and return styled text.
-
- By default, return the text as a Rich Text with the request style.
- If config.use_rich_markup is True, also parse the text for Rich markup strings.
- If config.use_markdown is True, parse as Markdown.
-
- Only one of config.use_markdown or config.use_rich_markup can be True.
- If both are True, config.use_markdown takes precedence.
-
- Args:
- text (str): Text to style
- style (str): Rich style to apply
-
- Returns:
- MarkdownElement or Text: Styled text object
- """
- formatter = _get_rich_formatter(formatter)
- config = formatter.config
- # Remove indentations from input text
- text = inspect.cleandoc(text)
- if config.use_markdown:
- if config.use_markdown_emoji:
- text = Emoji.replace(text)
- return Markdown(text, style=style)
- if config.use_rich_markup:
- return config.highlighter(Text.from_markup(text, style=style))
- else:
- return config.highlighter(Text(text, style=style))
-
-
-@group()
-def _get_help_text(
- obj: Union[Command, Group], formatter: Optional[RichHelpFormatter] = None
-) -> Iterable[Union[rich.markdown.Markdown, rich.text.Text]]:
- """Build primary help text for a click command or group.
-
- Returns the prose help text for a command or group, rendered either as a
- Rich Text object or as Markdown.
- If the command is marked as depreciated, the depreciated string will be prepended.
-
- Args:
- obj (click.Command or click.Group): Command or group to build help text for
-
- Yields:
- Text or Markdown: Multiple styled objects (depreciated, usage)
- """
- if TYPE_CHECKING:
- assert isinstance(obj.help, str)
- formatter = _get_rich_formatter(formatter)
- config = formatter.config
- # Prepend deprecated status
- if obj.deprecated:
- yield Text(config.deprecated_string, style=config.style_deprecated)
-
- # Fetch and dedent the help text
- help_text = inspect.cleandoc(obj.help)
-
- # Trim off anything that comes after \f on its own line
- help_text = help_text.partition("\f")[0]
-
- # Get the first paragraph
- first_line = help_text.split("\n\n")[0]
- # Remove single linebreaks
- if not config.use_markdown and not first_line.startswith("\b"):
- first_line = first_line.replace("\n", " ")
- yield _make_rich_rext(first_line.strip(), config.style_helptext_first_line, formatter)
-
- # Get remaining lines, remove single line breaks and format as dim
- remaining_paragraphs = help_text.split("\n\n")[1:]
- if len(remaining_paragraphs) > 0:
- if not config.use_markdown:
- # Remove single linebreaks
- remaining_paragraphs = [
- x.replace("\n", " ").strip() if not x.startswith("\b") else "{}\n".format(x.strip("\b\n"))
- for x in remaining_paragraphs
- ]
- # Join back together
- remaining_lines = "\n".join(remaining_paragraphs)
- else:
- # Join with double linebreaks if markdown
- remaining_lines = "\n\n".join(remaining_paragraphs)
-
- yield _make_rich_rext(remaining_lines, config.style_helptext, formatter)
-
-
-def _get_option_help(
- param: Union[click.Argument, click.Option], ctx: click.Context, formatter: Optional[RichHelpFormatter] = None
-) -> rich.columns.Columns:
- """Build primary help text for a click option or argument.
-
- Returns the prose help text for an option or argument, rendered either
- as a Rich Text object or as Markdown.
- Additional elements are appended to show the default and required status if applicable.
-
- Args:
- param (click.Argument or click.Option): Parameter to build help text for
- ctx (click.Context): Click Context object
-
- Returns:
- Columns: A columns element with multiple styled objects (help, default, required)
- """
- formatter = _get_rich_formatter(formatter)
- config = formatter.config
- items: List[rich.console.RenderableType] = []
-
- if TYPE_CHECKING:
- assert isinstance(param.name, str)
-
- # Get the environment variable first
- envvar = getattr(param, "envvar", None)
- # https://github.com/pallets/click/blob/0aec1168ac591e159baf6f61026d6ae322c53aaf/src/click/core.py#L2720-L2726
- if envvar is None:
- if (
- getattr(param, "allow_from_autoenv", None)
- and getattr(ctx, "auto_envvar_prefix", None) is not None
- and param.name is not None
- ):
- envvar = f"{ctx.auto_envvar_prefix}_{param.name.upper()}"
- if envvar is not None:
- envvar = ", ".join(envvar) if type(envvar) is list else envvar
-
- # Environment variable config.before help text
- if getattr(param, "show_envvar", None) and config.option_envvar_first and envvar is not None:
- items.append(Text(config.envvar_string.format(envvar), style=config.style_option_envvar))
-
- # Main help text
- if getattr(param, "help", None):
- if TYPE_CHECKING:
- assert isinstance(param, click.Option)
- assert hasattr(param, "help")
- assert isinstance(param.help, str)
- paragraphs = param.help.split("\n\n")
- # Remove single linebreaks
- if not config.use_markdown:
- paragraphs = [
- x.replace("\n", " ").strip() if not x.startswith("\b") else "{}\n".format(x.strip("\b\n"))
- for x in paragraphs
- ]
- items.append(_make_rich_rext("\n".join(paragraphs).strip(), config.style_option_help, formatter))
-
- # Append metavar if requested
- if config.append_metavars_help:
- metavar_str = param.make_metavar()
- # Do it ourselves if this is a positional argument
- if isinstance(param, click.core.Argument) and re.match(rf"\[?{param.name.upper()}]?", metavar_str):
- metavar_str = param.type.name.upper()
- # Attach metavar if param is a positional argument, or if it is a non boolean and non flag option
- if isinstance(param, click.core.Argument) or (metavar_str != "BOOLEAN" and not param.is_flag):
- metavar_str = metavar_str.replace("[", "").replace("]", "")
- items.append(
- Text(
- config.append_metavars_help_string.format(metavar_str),
- style=config.style_metavar_append,
- overflow="fold",
- )
- )
-
- # Environment variable config.after help text
- if getattr(param, "show_envvar", None) and not config.option_envvar_first and envvar is not None:
- items.append(Text(config.envvar_string.format(envvar), style=config.style_option_envvar))
-
- # Default value
- # Click 7.x, 8.0, and 8.1 all behave slightly differently when handling the default value help text.
- if not hasattr(param, "show_default"):
- parse_default = False
- elif CLICK_IS_BEFORE_VERSION_8X:
- parse_default = bool(param.default is not None and (param.show_default or getattr(ctx, "show_default", None)))
- elif CLICK_IS_VERSION_80:
- show_default_is_str = isinstance(param.show_default, str)
- parse_default = bool(
- show_default_is_str or (param.default is not None and (param.show_default or ctx.show_default))
- )
- else:
- show_default_is_str = False
- if param.show_default is not None:
- if isinstance(param.show_default, str):
- show_default_is_str = show_default = True
- else:
- show_default = bool(param.show_default)
- else:
- show_default = bool(getattr(ctx, "show_default", False))
- parse_default = bool(show_default_is_str or (show_default and (param.default is not None)))
-
- if parse_default:
- help_record = param.get_help_record(ctx)
- if TYPE_CHECKING:
- assert isinstance(help_record, tuple)
- default_str_match = re.search(r"\[(?:.+; )?default: (.*)\]", help_record[-1])
- if default_str_match:
- # Don't show the required string, as we show that afterwards anyway
- default_str = default_str_match.group(1).replace("; required", "")
- items.append(
- Text(
- config.default_string.format(default_str),
- style=config.style_option_default,
- )
- )
-
- # Required?
- if param.required:
- items.append(Text(config.required_long_string, style=config.style_required_long))
-
- # Use Columns - this allows us to group different renderable types
- # (Text, Markdown) onto a single line.
- return Columns(items)
-
-
-def _make_command_help(
- help_text: str, formatter: Optional[RichHelpFormatter] = None
-) -> Union[rich.text.Text, rich.markdown.Markdown]:
- """Build cli help text for a click group command.
-
- That is, when calling help on groups with multiple subcommands
- (not the main help text when calling the subcommand help).
-
- Returns the first paragraph of help text for a command, rendered either as a
- Rich Text object or as Markdown.
- Ignores single newlines as paragraph markers, looks for double only.
-
- Args:
- help_text (str): Help text
-
- Returns:
- Text or Markdown: Styled object
- """
- formatter = _get_rich_formatter(formatter)
- config = formatter.config
- paragraphs = inspect.cleandoc(help_text).split("\n\n")
- # Remove single linebreaks
- if not config.use_markdown and not paragraphs[0].startswith("\b"):
- paragraphs[0] = paragraphs[0].replace("\n", " ")
- elif paragraphs[0].startswith("\b"):
- paragraphs[0] = paragraphs[0].replace("\b\n", "")
-
- return _make_rich_rext(paragraphs[0].strip(), config.style_option_help, formatter)
-
-
-def get_rich_usage(
- obj: Union[Command, Group],
- ctx: click.Context,
- formatter: click.HelpFormatter,
-) -> None:
- """Get usage text for a command."""
- formatter = _get_rich_formatter(formatter)
- config = formatter.config
- console = formatter.console
-
- # Highlighter for options and arguments
- class UsageHighlighter(RegexHighlighter):
- highlights = [
- r"(?P<argument>\w+)",
- ]
-
- usage_highlighter = UsageHighlighter()
-
- # Print usage
- console.print(
- Padding(
- Columns(
- (
- Text("Usage:", style=config.style_usage),
- Text(ctx.command_path, style=config.style_usage_command),
- usage_highlighter(" ".join(obj.collect_usage_pieces(ctx))),
- )
- ),
- 1,
- ),
- )
-
-
-def rich_format_help(
- obj: Command,
- ctx: click.Context,
- formatter: click.HelpFormatter,
-) -> None:
- """Print nicely formatted help text using rich.
-
- Based on original code from rich-cli, by @willmcgugan.
- https://github.com/Textualize/rich-cli/blob/8a2767c7a340715fc6fbf4930ace717b9b2fc5e5/src/rich_cli/__main__.py#L162-L236
-
- Replacement for the click function format_help().
- Takes a command or group and builds the help text output.
-
- Args:
- obj (click.Command or click.Group): Command or group to build help text for
- ctx (click.Context): Click Context object
- formatter (click.HelpFormatter): Click HelpFormatter object
- """
- formatter = _get_rich_formatter(formatter)
- config = formatter.config
- console = formatter.console
- highlighter = formatter.config.highlighter
-
- # Header text if we have it
- if config.header_text:
- console.print(
- Padding(
- _make_rich_rext(config.header_text, config.style_header_text, formatter),
- (1, 1, 0, 1),
- ),
- )
-
- # Print usage
- get_rich_usage(obj, ctx, formatter)
-
- # Print command / group help if we have some
- if obj.help:
- # Print with some padding
- console.print(
- Padding(
- Align(_get_help_text(obj, formatter), pad=False),
- (0, 1, 1, 1),
- )
- )
-
- # Look through config.option_groups for this command
- # stick anything unmatched into a default group at the end
- option_groups = config.option_groups.get(ctx.command_path, []).copy()
- option_groups.append({"options": []})
- argument_group_options = []
-
- for param in obj.get_params(ctx):
- # Skip positional arguments - they don't have opts or helptext and are covered in usage
- # See https://click.palletsprojects.com/en/8.0.x/documentation/#documenting-arguments
- if isinstance(param, click.core.Argument) and not config.show_arguments:
- continue
-
- # Skip if option is hidden
- if getattr(param, "hidden", False):
- continue
-
- # Already mentioned in a config option group
- for option_group in option_groups:
- if any([opt in option_group.get("options", []) for opt in param.opts]):
- break
-
- # No break, no mention - add to the default group
- else:
- if isinstance(param, click.core.Argument) and not config.group_arguments_options:
- argument_group_options.append(param.opts[0])
- else:
- list_of_option_groups: List[str] = option_groups[-1]["options"] # type: ignore[assignment]
- list_of_option_groups.append(param.opts[0])
-
- # If we're not grouping arguments and we got some, prepend before default options
- if len(argument_group_options) > 0:
- extra_option_group = {"name": config.arguments_panel_title, "options": argument_group_options}
- option_groups.insert(len(option_groups) - 1, extra_option_group)
-
- # print("!", option_groups)
-
- # Print each option group panel
- for option_group in option_groups:
- options_rows = []
- for opt in option_group.get("options", []):
- # Get the param
- for param in obj.get_params(ctx):
- if any([opt in param.opts]):
- break
- # Skip if option is not listed in this group
- else:
- continue
-
- # Short and long form
- opt_long_strs = []
- opt_short_strs = []
- for idx, opt in enumerate(param.opts):
- opt_str = opt
- try:
- opt_str += "/" + param.secondary_opts[idx]
- except IndexError:
- pass
-
- if isinstance(param, click.core.Argument):
- opt_long_strs.append(opt_str.upper())
- elif "--" in opt:
- opt_long_strs.append(opt_str)
- else:
- opt_short_strs.append(opt_str)
-
- # Column for a metavar, if we have one
- metavar = Text(style=config.style_metavar, overflow="fold")
- metavar_str = param.make_metavar()
-
- if TYPE_CHECKING:
- assert isinstance(param.name, str)
- assert isinstance(param, click.Option)
-
- # Do it ourselves if this is a positional argument
- if isinstance(param, click.core.Argument) and re.match(rf"\[?{param.name.upper()}]?", metavar_str):
- metavar_str = param.type.name.upper()
-
- # Attach metavar if param is a positional argument, or if it is a non boolean and non flag option
- if isinstance(param, click.core.Argument) or (
- metavar_str != "BOOLEAN" and not getattr(param, "is_flag", None)
- ):
- metavar.append(metavar_str)
-
- # Range - from
- # https://github.com/pallets/click/blob/c63c70dabd3f86ca68678b4f00951f78f52d0270/src/click/core.py#L2698-L2706 # noqa: E501
- try:
- # skip count with default range type
- if isinstance(param.type, click.types._NumberRangeBase) and not (
- param.count and param.type.min == 0 and param.type.max is None
- ):
- range_str = param.type._describe_range()
- if range_str:
- metavar.append(config.range_string.format(range_str))
- except AttributeError:
- # click.types._NumberRangeBase is only in Click 8x onwards
- pass
-
- # Required asterisk
- required: Union[Text, str] = ""
- if param.required:
- required = Text(config.required_short_string, style=config.style_required_short)
-
- # Highlighter to make [ | ] and <> dim
- class MetavarHighlighter(RegexHighlighter):
- highlights = [
- r"^(?P<metavar_sep>(\[|<))",
- r"(?P<metavar_sep>\|)",
- r"(?P<metavar_sep>(\]|>)$)",
- ]
-
- metavar_highlighter = MetavarHighlighter()
-
- rows = [
- required,
- highlighter(highlighter(",".join(opt_long_strs))),
- highlighter(highlighter(",".join(opt_short_strs))),
- metavar_highlighter(metavar),
- _get_option_help(param, ctx, formatter),
- ]
-
- # Remove metavar if specified in config
- if not config.show_metavars_column:
- rows.pop(3)
-
- options_rows.append(rows)
-
- if len(options_rows) > 0:
- t_styles = {
- "show_lines": config.style_options_table_show_lines,
- "leading": config.style_options_table_leading,
- "box": config.style_options_table_box,
- "border_style": config.style_options_table_border_style,
- "row_styles": config.style_options_table_row_styles,
- "pad_edge": config.style_options_table_pad_edge,
- "padding": config.style_options_table_padding,
- }
- t_styles.update(option_group.get("table_styles", {})) # type: ignore[arg-type]
- box_style = getattr(box, t_styles.pop("box"), None) # type: ignore[arg-type]
-
- options_table = Table(
- highlight=True,
- show_header=False,
- expand=True,
- box=box_style,
- **t_styles, # type: ignore[arg-type]
- )
- # Strip the required column if none are required
- if all([x[0] == "" for x in options_rows]):
- options_rows = [x[1:] for x in options_rows]
- for row in options_rows:
- options_table.add_row(*row)
- console.print(
- Panel(
- options_table,
- border_style=config.style_options_panel_border,
- title=option_group.get("name", config.options_panel_title),
- title_align=config.align_options_panel,
- )
- )
-
- #
- # Groups only:
- # List click command groups
- #
-
- if isinstance(obj, MultiCommand):
- # Look through COMMAND_GROUPS for this command
- # stick anything unmatched into a default group at the end
- cmd_groups = config.command_groups.get(ctx.command_path, []).copy()
- cmd_groups.append({"commands": []})
- for command in obj.list_commands(ctx):
- for cmd_group in cmd_groups:
- if command in cmd_group.get("commands", []):
- break
- else:
- commands: List[str] = cmd_groups[-1]["commands"] # type: ignore[assignment]
- commands.append(command)
-
- # Print each command group panel
- for cmd_group in cmd_groups:
- t_styles = {
- "show_lines": config.style_commands_table_show_lines,
- "leading": config.style_commands_table_leading,
- "box": config.style_commands_table_box,
- "border_style": config.style_commands_table_border_style,
- "row_styles": config.style_commands_table_row_styles,
- "pad_edge": config.style_commands_table_pad_edge,
- "padding": config.style_commands_table_padding,
- }
- t_styles.update(cmd_group.get("table_styles", {})) # type: ignore[arg-type]
- box_style = getattr(box, t_styles.pop("box"), None) # type: ignore[arg-type]
-
- commands_table = Table(
- highlight=False,
- show_header=False,
- expand=True,
- box=box_style,
- **t_styles, # type: ignore[arg-type]
- )
- # Define formatting in first column, as commands don't match highlighter regex
- # and set column ratio for first and second column, if a ratio has been set
- if config.style_commands_table_column_width_ratio is None:
- table_column_width_ratio: Union[Tuple[None, None], Tuple[int, int]] = (None, None)
- else:
- table_column_width_ratio = config.style_commands_table_column_width_ratio
-
- commands_table.add_column(style=config.style_command, no_wrap=True, ratio=table_column_width_ratio[0])
- commands_table.add_column(
- no_wrap=False,
- ratio=table_column_width_ratio[1],
- )
- for command in cmd_group.get("commands", []):
- # Skip if command does not exist
- if command not in obj.list_commands(ctx):
- continue
- cmd = obj.get_command(ctx, command)
- if TYPE_CHECKING:
- assert cmd is not None
- if cmd.hidden:
- continue
- # Use the truncated short text as with vanilla text if requested
- if config.use_click_short_help:
- helptext = cmd.get_short_help_str()
- else:
- # Use short_help function argument if used, or the full help
- helptext = cmd.short_help or cmd.help or ""
- commands_table.add_row(command, _make_command_help(helptext, formatter))
- if commands_table.row_count > 0:
- console.print(
- Panel(
- commands_table,
- border_style=config.style_commands_panel_border,
- title=cmd_group.get("name", config.commands_panel_title),
- title_align=config.align_commands_panel,
- )
- )
-
- # Epilogue if we have it
- if isinstance(obj, Command) and obj.epilog:
- # Remove single linebreaks, replace double with single
- lines = obj.epilog.split("\n\n")
- epilogue = "\n".join([x.replace("\n", " ").strip() for x in lines])
- console.print(Padding(Align(_make_rich_rext(epilogue, config.style_epilog_text, formatter), pad=False), 1))
-
- # Footer text if we have it
- if config.footer_text:
- console.print(Padding(_make_rich_rext(config.footer_text, config.style_footer_text, formatter), (1, 1, 0, 1)))
-
-
-def rich_format_error(self: click.ClickException, formatter: Optional[RichHelpFormatter] = None) -> None:
- """Print richly formatted click errors.
-
- Called by custom exception handler to print richly formatted click errors.
- Mimics original click.ClickException.echo() function but with rich formatting.
-
- Args:
- click.ClickException: Click exception to format.
- """
- formatter = _get_rich_formatter(formatter)
- console = formatter.console
- config = formatter.config
- highlighter = formatter.config.highlighter
- # Print usage
- if getattr(self, "ctx", None) is not None:
- if TYPE_CHECKING:
- assert hasattr(self, "ctx")
- get_rich_usage(self.ctx.command, self.ctx, formatter)
- if config.errors_suggestion:
- console.print(
- Padding(
- config.errors_suggestion,
- (0, 1, 0, 1),
- ),
- style=config.style_errors_suggestion,
- )
- elif (
- config.errors_suggestion is None
- and getattr(self, "ctx", None) is not None
- and self.ctx.command.get_help_option(self.ctx) is not None # type: ignore[attr-defined]
- ):
- cmd_path = self.ctx.command_path # type: ignore[attr-defined]
- help_option = self.ctx.help_option_names[0] # type: ignore[attr-defined]
- console.print(
- Padding(
- Columns(
- (
- Text("Try"),
- Text(f"'{cmd_path} {help_option}'", style=config.style_errors_suggestion_command),
- Text("for help"),
- )
- ),
- (0, 1, 0, 1),
- ),
- style=config.style_errors_suggestion,
- )
-
- # A major Python library using click (dbt-core) has its own exception
- # logic that subclasses ClickException, but does not use the message
- # attribute. Checking for the 'message' attribute works to make the
- # rich-click CLI compatible.
- if hasattr(self, "message"):
- console.print(
- Padding(
- Panel(
- highlighter(self.format_message()),
- border_style=config.style_errors_panel_border,
- title=config.errors_panel_title,
- title_align=config.align_errors_panel,
- ),
- (0, 0, 1, 0),
- )
- )
- if config.errors_epilogue:
- console.print(Padding(config.errors_epilogue, (0, 1, 1, 1)))
-
-
-def rich_abort_error(formatter: Optional[RichHelpFormatter] = None) -> None:
- """Print richly formatted abort error."""
- formatter = _get_rich_formatter(formatter)
- config = formatter.config
- formatter.console.print(config.aborted_text, style=config.style_aborted)
-
-
-module_config: Optional[RichHelpConfiguration] = None
-
-
-def get_module_help_configuration() -> RichHelpConfiguration:
- """Get Module-level help configuration resolved into a `RichHelpConfiguration` instance."""
- global module_config
- if module_config:
- return module_config
- module_config = RichHelpConfiguration(
- STYLE_OPTION,
- STYLE_ARGUMENT,
- STYLE_COMMAND,
- STYLE_SWITCH,
- STYLE_METAVAR,
- STYLE_METAVAR_APPEND,
- STYLE_METAVAR_SEPARATOR,
- STYLE_HEADER_TEXT,
- STYLE_EPILOG_TEXT,
- STYLE_FOOTER_TEXT,
- STYLE_USAGE,
- STYLE_USAGE_COMMAND,
- STYLE_DEPRECATED,
- STYLE_HELPTEXT_FIRST_LINE,
- STYLE_HELPTEXT,
- STYLE_OPTION_HELP,
- STYLE_OPTION_DEFAULT,
- STYLE_OPTION_ENVVAR,
- STYLE_REQUIRED_SHORT,
- STYLE_REQUIRED_LONG,
- STYLE_OPTIONS_PANEL_BORDER,
- ALIGN_OPTIONS_PANEL,
- STYLE_OPTIONS_TABLE_SHOW_LINES,
- STYLE_OPTIONS_TABLE_LEADING,
- STYLE_OPTIONS_TABLE_PAD_EDGE,
- STYLE_OPTIONS_TABLE_PADDING,
- STYLE_OPTIONS_TABLE_BOX,
- STYLE_OPTIONS_TABLE_ROW_STYLES,
- STYLE_OPTIONS_TABLE_BORDER_STYLE,
- STYLE_COMMANDS_PANEL_BORDER,
- ALIGN_COMMANDS_PANEL,
- STYLE_COMMANDS_TABLE_SHOW_LINES,
- STYLE_COMMANDS_TABLE_LEADING,
- STYLE_COMMANDS_TABLE_PAD_EDGE,
- STYLE_COMMANDS_TABLE_PADDING,
- STYLE_COMMANDS_TABLE_BOX,
- STYLE_COMMANDS_TABLE_ROW_STYLES,
- STYLE_COMMANDS_TABLE_BORDER_STYLE,
- STYLE_COMMANDS_TABLE_COLUMN_WIDTH_RATIO,
- STYLE_ERRORS_PANEL_BORDER,
- ALIGN_ERRORS_PANEL,
- STYLE_ERRORS_SUGGESTION,
- STYLE_ERRORS_SUGGESTION_COMMAND,
- STYLE_ABORTED,
- WIDTH,
- MAX_WIDTH,
- COLOR_SYSTEM,
- FORCE_TERMINAL,
- HEADER_TEXT,
- FOOTER_TEXT,
- DEPRECATED_STRING,
- DEFAULT_STRING,
- ENVVAR_STRING,
- REQUIRED_SHORT_STRING,
- REQUIRED_LONG_STRING,
- RANGE_STRING,
- APPEND_METAVARS_HELP_STRING,
- ARGUMENTS_PANEL_TITLE,
- OPTIONS_PANEL_TITLE,
- COMMANDS_PANEL_TITLE,
- ERRORS_PANEL_TITLE,
- ERRORS_SUGGESTION,
- ERRORS_EPILOGUE,
- ABORTED_TEXT,
- SHOW_ARGUMENTS,
- SHOW_METAVARS_COLUMN,
- APPEND_METAVARS_HELP,
- GROUP_ARGUMENTS_OPTIONS,
- OPTION_ENVVAR_FIRST,
- USE_MARKDOWN,
- USE_MARKDOWN_EMOJI,
- USE_RICH_MARKUP,
- COMMAND_GROUPS,
- OPTION_GROUPS,
- USE_CLICK_SHORT_HELP,
- highlighter,
- )
- return module_config