We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Deprecated option hints aren't tabbed in `help` goal(s)
**Describe the bug**
Deprecated option hints don't appear to be tabbed

When running `./pants help-advanced`
```
Global deprecated options
-------------------------
 
  --[no-]use-deprecated-python-macros
  PANTS_USE_DEPRECATED_PYTHON_MACROS
  use_deprecated_python_macros
      default: False
      current value: False
      If true, use Pants's deprecated macro system for `python_requirements`, `poetry_requirements`, and `pipenv_requirements` rather than target generation.
      
      The address for macros is different. Rather than `3rdparty/python#Django`, the address will look like `3rdparty/python:Django`. The macro (`python_requirements` et
      al) also was not a proper target, meaning that you could not give it a `name`. In contrast, if the target generator sets its `name`, e.g. to `reqs`, generated
      targets will have an address like `3rdparty/python:reqs#Django`.
      Deprecated, will be removed in version: 2.12.0.dev0.
      In Pants 2.12, the deprecated Python macros like `python_requirements` will be replaced with improved target generators, which are now enabled by default.

If you already migrated by setting `use_deprecated_python_macros = false`, simply delete the option.

Otherwise, when you are ready to upgrade, follow these steps:

  1. Run `./pants update-build-files --fix-python-macros`
  2. Check the logs for an ERROR log to see if you have to manually add `name=` anywhere.
  3. Remove `use_deprecated_python_macros = true` from `[GLOBAL]` in pants.toml.

(Why upgrade from the old macro mechanism to target generation? Among other benefits, it makes sure that the Pants daemon is properly invalidated when you change `requirements.txt` and `pyproject.toml`.)
```

**Pants version**
`main`

**OS**
Linux

**Additional info**
N/A


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/python/pants/help/help_formatter.py`
Content:
```
1 # Copyright 2015 Pants project contributors (see CONTRIBUTORS.md).
2 # Licensed under the Apache License, Version 2.0 (see LICENSE).
3 
4 import json
5 import textwrap
6 from enum import Enum
7 from typing import List, Optional
8 
9 from pants.help.help_info_extracter import OptionHelpInfo, OptionScopeHelpInfo, to_help_str
10 from pants.help.maybe_color import MaybeColor
11 from pants.option.ranked_value import Rank, RankedValue
12 from pants.util.docutil import bin_name, terminal_width
13 from pants.util.strutil import hard_wrap
14 
15 
16 class HelpFormatter(MaybeColor):
17     def __init__(self, *, show_advanced: bool, show_deprecated: bool, color: bool) -> None:
18         super().__init__(color=color)
19         self._show_advanced = show_advanced
20         self._show_deprecated = show_deprecated
21         self._width = terminal_width()
22 
23     def format_options(self, oshi: OptionScopeHelpInfo):
24         """Return a help message for the specified options."""
25         lines = []
26 
27         def add_option(ohis, *, category=None):
28             lines.append("")
29             goal_or_subsystem = "goal" if oshi.is_goal else "subsystem"
30             display_scope = f"`{oshi.scope}` {goal_or_subsystem}" if oshi.scope else "Global"
31             if category:
32                 title = f"{display_scope} {category} options"
33                 lines.append(self.maybe_green(f"{title}\n{'-' * len(title)}"))
34             else:
35                 # The basic options section gets the description and options scope info.
36                 # No need to repeat those in the advanced section.
37                 title = f"{display_scope} options"
38                 lines.append(self.maybe_green(f"{title}\n{'-' * len(title)}\n"))
39                 lines.extend(hard_wrap(oshi.description, width=self._width))
40                 lines.append(" ")
41                 lines.append(f"Activated by {self.maybe_magenta(oshi.provider)}")
42                 config_section = f"[{oshi.scope or 'GLOBAL'}]"
43                 lines.append(f"Config section: {self.maybe_magenta(config_section)}")
44             lines.append(" ")
45             if not ohis:
46                 lines.append("None available.")
47                 return
48             for ohi in ohis:
49                 lines.extend([*self.format_option(ohi), ""])
50 
51         add_option(oshi.basic)
52         if self._show_advanced:
53             add_option(oshi.advanced, category="advanced")
54         if self._show_deprecated:
55             add_option(oshi.deprecated, category="deprecated")
56         if oshi.advanced and not self._show_advanced:
57             lines.append(
58                 self.maybe_green(
59                     f"Advanced options available. You can list them by running "
60                     f"{bin_name()} help-advanced {oshi.scope}."
61                 )
62             )
63         return [*lines, ""]
64 
65     def format_option(self, ohi: OptionHelpInfo) -> List[str]:
66         """Format the help output for a single option.
67 
68         :param ohi: Extracted information for option to print
69         :return: Formatted help text for this option
70         """
71 
72         def maybe_parens(s: Optional[str]) -> str:
73             return f" ({s})" if s else ""
74 
75         def format_value(ranked_val: RankedValue, prefix: str, left_padding: str) -> List[str]:
76             if isinstance(ranked_val.value, (list, dict)):
77                 is_enum_list = (
78                     isinstance(ranked_val.value, list)
79                     and len(ranked_val.value) > 0
80                     and isinstance(ranked_val.value[0], Enum)
81                 )
82                 normalized_val = (
83                     [enum_elmt.value for enum_elmt in ranked_val.value]
84                     if is_enum_list
85                     else ranked_val.value
86                 )
87                 val_lines = json.dumps(normalized_val, sort_keys=True, indent=4).split("\n")
88             else:
89                 val_lines = [to_help_str(ranked_val.value)]
90             val_lines[0] = f"{prefix}{val_lines[0]}"
91             val_lines[-1] = f"{val_lines[-1]}{maybe_parens(ranked_val.details)}"
92             val_lines = [self.maybe_cyan(f"{left_padding}{line}") for line in val_lines]
93             return val_lines
94 
95         indent = "      "
96         arg_lines = [f"  {self.maybe_magenta(args)}" for args in ohi.display_args]
97         arg_lines.append(self.maybe_magenta(f"  {ohi.env_var}"))
98         arg_lines.append(self.maybe_magenta(f"  {ohi.config_key}"))
99         choices = "" if ohi.choices is None else f"one of: [{', '.join(ohi.choices)}]"
100         choices_lines = [
101             f"{indent}{'  ' if i != 0 else ''}{self.maybe_cyan(s)}"
102             for i, s in enumerate(textwrap.wrap(f"{choices}", self._width))
103         ]
104         default_lines = format_value(RankedValue(Rank.HARDCODED, ohi.default), "default: ", indent)
105         if not ohi.value_history:
106             # Should never happen, but this keeps mypy happy.
107             raise ValueError("No value history - options not parsed.")
108         final_val = ohi.value_history.final_value
109         curr_value_lines = format_value(final_val, "current value: ", indent)
110 
111         interesting_ranked_values = [
112             rv
113             for rv in reversed(ohi.value_history.ranked_values)
114             if rv.rank not in (Rank.NONE, Rank.HARDCODED, final_val.rank)
115         ]
116         value_derivation_lines = [
117             line
118             for rv in interesting_ranked_values
119             for line in format_value(rv, "overrode: ", f"{indent}    ")
120         ]
121         description_lines = hard_wrap(ohi.help, indent=len(indent), width=self._width)
122         lines = [
123             *arg_lines,
124             *choices_lines,
125             *default_lines,
126             *curr_value_lines,
127             *value_derivation_lines,
128             *description_lines,
129         ]
130         if ohi.deprecated_message:
131             maybe_colorize = self.maybe_red if ohi.deprecation_active else self.maybe_yellow
132             lines.append(maybe_colorize(f"{indent}{ohi.deprecated_message}"))
133             if ohi.removal_hint:
134                 lines.append(maybe_colorize(f"{indent}{ohi.removal_hint}"))
135         return lines
136
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/python/pants/help/help_formatter.py b/src/python/pants/help/help_formatter.py
--- a/src/python/pants/help/help_formatter.py
+++ b/src/python/pants/help/help_formatter.py
@@ -92,19 +92,33 @@
             val_lines = [self.maybe_cyan(f"{left_padding}{line}") for line in val_lines]
             return val_lines
 
+        def wrap(s: str) -> List[str]:
+            return hard_wrap(s, indent=len(indent), width=self._width)
+
         indent = "      "
+
         arg_lines = [f"  {self.maybe_magenta(args)}" for args in ohi.display_args]
         arg_lines.append(self.maybe_magenta(f"  {ohi.env_var}"))
         arg_lines.append(self.maybe_magenta(f"  {ohi.config_key}"))
+
         choices = "" if ohi.choices is None else f"one of: [{', '.join(ohi.choices)}]"
         choices_lines = [
             f"{indent}{'  ' if i != 0 else ''}{self.maybe_cyan(s)}"
             for i, s in enumerate(textwrap.wrap(f"{choices}", self._width))
         ]
+
+        deprecated_lines = []
+        if ohi.deprecated_message:
+            maybe_colorize = self.maybe_red if ohi.deprecation_active else self.maybe_yellow
+            deprecated_lines.extend(wrap(maybe_colorize(ohi.deprecated_message)))
+            if ohi.removal_hint:
+                deprecated_lines.extend(wrap(maybe_colorize(ohi.removal_hint)))
+
         default_lines = format_value(RankedValue(Rank.HARDCODED, ohi.default), "default: ", indent)
         if not ohi.value_history:
             # Should never happen, but this keeps mypy happy.
             raise ValueError("No value history - options not parsed.")
+
         final_val = ohi.value_history.final_value
         curr_value_lines = format_value(final_val, "current value: ", indent)
 
@@ -118,18 +132,14 @@
             for rv in interesting_ranked_values
             for line in format_value(rv, "overrode: ", f"{indent}    ")
         ]
-        description_lines = hard_wrap(ohi.help, indent=len(indent), width=self._width)
+        description_lines = wrap(ohi.help)
         lines = [
             *arg_lines,
             *choices_lines,
             *default_lines,
             *curr_value_lines,
             *value_derivation_lines,
+            *deprecated_lines,
             *description_lines,
         ]
-        if ohi.deprecated_message:
-            maybe_colorize = self.maybe_red if ohi.deprecation_active else self.maybe_yellow
-            lines.append(maybe_colorize(f"{indent}{ohi.deprecated_message}"))
-            if ohi.removal_hint:
-                lines.append(maybe_colorize(f"{indent}{ohi.removal_hint}"))
         return lines

{"golden_diff": "diff --git a/src/python/pants/help/help_formatter.py b/src/python/pants/help/help_formatter.py\n--- a/src/python/pants/help/help_formatter.py\n+++ b/src/python/pants/help/help_formatter.py\n@@ -92,19 +92,33 @@\n             val_lines = [self.maybe_cyan(f\"{left_padding}{line}\") for line in val_lines]\n             return val_lines\n \n+        def wrap(s: str) -> List[str]:\n+            return hard_wrap(s, indent=len(indent), width=self._width)\n+\n         indent = \"      \"\n+\n         arg_lines = [f\"  {self.maybe_magenta(args)}\" for args in ohi.display_args]\n         arg_lines.append(self.maybe_magenta(f\"  {ohi.env_var}\"))\n         arg_lines.append(self.maybe_magenta(f\"  {ohi.config_key}\"))\n+\n         choices = \"\" if ohi.choices is None else f\"one of: [{', '.join(ohi.choices)}]\"\n         choices_lines = [\n             f\"{indent}{'  ' if i != 0 else ''}{self.maybe_cyan(s)}\"\n             for i, s in enumerate(textwrap.wrap(f\"{choices}\", self._width))\n         ]\n+\n+        deprecated_lines = []\n+        if ohi.deprecated_message:\n+            maybe_colorize = self.maybe_red if ohi.deprecation_active else self.maybe_yellow\n+            deprecated_lines.extend(wrap(maybe_colorize(ohi.deprecated_message)))\n+            if ohi.removal_hint:\n+                deprecated_lines.extend(wrap(maybe_colorize(ohi.removal_hint)))\n+\n         default_lines = format_value(RankedValue(Rank.HARDCODED, ohi.default), \"default: \", indent)\n         if not ohi.value_history:\n             # Should never happen, but this keeps mypy happy.\n             raise ValueError(\"No value history - options not parsed.\")\n+\n         final_val = ohi.value_history.final_value\n         curr_value_lines = format_value(final_val, \"current value: \", indent)\n \n@@ -118,18 +132,14 @@\n             for rv in interesting_ranked_values\n             for line in format_value(rv, \"overrode: \", f\"{indent}    \")\n         ]\n-        description_lines = hard_wrap(ohi.help, indent=len(indent), width=self._width)\n+        description_lines = wrap(ohi.help)\n         lines = [\n             *arg_lines,\n             *choices_lines,\n             *default_lines,\n             *curr_value_lines,\n             *value_derivation_lines,\n+            *deprecated_lines,\n             *description_lines,\n         ]\n-        if ohi.deprecated_message:\n-            maybe_colorize = self.maybe_red if ohi.deprecation_active else self.maybe_yellow\n-            lines.append(maybe_colorize(f\"{indent}{ohi.deprecated_message}\"))\n-            if ohi.removal_hint:\n-                lines.append(maybe_colorize(f\"{indent}{ohi.removal_hint}\"))\n         return lines\n", "issue": "Deprecated option hints aren't tabbed in `help` goal(s)\n**Describe the bug**\r\nDeprecated option hints don't appear to be tabbed\r\n\r\nWhen running `./pants help-advanced`\r\n```\r\nGlobal deprecated options\r\n-------------------------\r\n \r\n  --[no-]use-deprecated-python-macros\r\n  PANTS_USE_DEPRECATED_PYTHON_MACROS\r\n  use_deprecated_python_macros\r\n      default: False\r\n      current value: False\r\n      If true, use Pants's deprecated macro system for `python_requirements`, `poetry_requirements`, and `pipenv_requirements` rather than target generation.\r\n      \r\n      The address for macros is different. Rather than `3rdparty/python#Django`, the address will look like `3rdparty/python:Django`. The macro (`python_requirements` et\r\n      al) also was not a proper target, meaning that you could not give it a `name`. In contrast, if the target generator sets its `name`, e.g. to `reqs`, generated\r\n      targets will have an address like `3rdparty/python:reqs#Django`.\r\n      Deprecated, will be removed in version: 2.12.0.dev0.\r\n      In Pants 2.12, the deprecated Python macros like `python_requirements` will be replaced with improved target generators, which are now enabled by default.\r\n\r\nIf you already migrated by setting `use_deprecated_python_macros = false`, simply delete the option.\r\n\r\nOtherwise, when you are ready to upgrade, follow these steps:\r\n\r\n  1. Run `./pants update-build-files --fix-python-macros`\r\n  2. Check the logs for an ERROR log to see if you have to manually add `name=` anywhere.\r\n  3. Remove `use_deprecated_python_macros = true` from `[GLOBAL]` in pants.toml.\r\n\r\n(Why upgrade from the old macro mechanism to target generation? Among other benefits, it makes sure that the Pants daemon is properly invalidated when you change `requirements.txt` and `pyproject.toml`.)\r\n```\r\n\r\n**Pants version**\r\n`main`\r\n\r\n**OS**\r\nLinux\r\n\r\n**Additional info**\r\nN/A\r\n\n", "before_files": [{"content": "# Copyright 2015 Pants project contributors (see CONTRIBUTORS.md).\n# Licensed under the Apache License, Version 2.0 (see LICENSE).\n\nimport json\nimport textwrap\nfrom enum import Enum\nfrom typing import List, Optional\n\nfrom pants.help.help_info_extracter import OptionHelpInfo, OptionScopeHelpInfo, to_help_str\nfrom pants.help.maybe_color import MaybeColor\nfrom pants.option.ranked_value import Rank, RankedValue\nfrom pants.util.docutil import bin_name, terminal_width\nfrom pants.util.strutil import hard_wrap\n\n\nclass HelpFormatter(MaybeColor):\n    def __init__(self, *, show_advanced: bool, show_deprecated: bool, color: bool) -> None:\n        super().__init__(color=color)\n        self._show_advanced = show_advanced\n        self._show_deprecated = show_deprecated\n        self._width = terminal_width()\n\n    def format_options(self, oshi: OptionScopeHelpInfo):\n        \"\"\"Return a help message for the specified options.\"\"\"\n        lines = []\n\n        def add_option(ohis, *, category=None):\n            lines.append(\"\")\n            goal_or_subsystem = \"goal\" if oshi.is_goal else \"subsystem\"\n            display_scope = f\"`{oshi.scope}` {goal_or_subsystem}\" if oshi.scope else \"Global\"\n            if category:\n                title = f\"{display_scope} {category} options\"\n                lines.append(self.maybe_green(f\"{title}\\n{'-' * len(title)}\"))\n            else:\n                # The basic options section gets the description and options scope info.\n                # No need to repeat those in the advanced section.\n                title = f\"{display_scope} options\"\n                lines.append(self.maybe_green(f\"{title}\\n{'-' * len(title)}\\n\"))\n                lines.extend(hard_wrap(oshi.description, width=self._width))\n                lines.append(\" \")\n                lines.append(f\"Activated by {self.maybe_magenta(oshi.provider)}\")\n                config_section = f\"[{oshi.scope or 'GLOBAL'}]\"\n                lines.append(f\"Config section: {self.maybe_magenta(config_section)}\")\n            lines.append(\" \")\n            if not ohis:\n                lines.append(\"None available.\")\n                return\n            for ohi in ohis:\n                lines.extend([*self.format_option(ohi), \"\"])\n\n        add_option(oshi.basic)\n        if self._show_advanced:\n            add_option(oshi.advanced, category=\"advanced\")\n        if self._show_deprecated:\n            add_option(oshi.deprecated, category=\"deprecated\")\n        if oshi.advanced and not self._show_advanced:\n            lines.append(\n                self.maybe_green(\n                    f\"Advanced options available. You can list them by running \"\n                    f\"{bin_name()} help-advanced {oshi.scope}.\"\n                )\n            )\n        return [*lines, \"\"]\n\n    def format_option(self, ohi: OptionHelpInfo) -> List[str]:\n        \"\"\"Format the help output for a single option.\n\n        :param ohi: Extracted information for option to print\n        :return: Formatted help text for this option\n        \"\"\"\n\n        def maybe_parens(s: Optional[str]) -> str:\n            return f\" ({s})\" if s else \"\"\n\n        def format_value(ranked_val: RankedValue, prefix: str, left_padding: str) -> List[str]:\n            if isinstance(ranked_val.value, (list, dict)):\n                is_enum_list = (\n                    isinstance(ranked_val.value, list)\n                    and len(ranked_val.value) > 0\n                    and isinstance(ranked_val.value[0], Enum)\n                )\n                normalized_val = (\n                    [enum_elmt.value for enum_elmt in ranked_val.value]\n                    if is_enum_list\n                    else ranked_val.value\n                )\n                val_lines = json.dumps(normalized_val, sort_keys=True, indent=4).split(\"\\n\")\n            else:\n                val_lines = [to_help_str(ranked_val.value)]\n            val_lines[0] = f\"{prefix}{val_lines[0]}\"\n            val_lines[-1] = f\"{val_lines[-1]}{maybe_parens(ranked_val.details)}\"\n            val_lines = [self.maybe_cyan(f\"{left_padding}{line}\") for line in val_lines]\n            return val_lines\n\n        indent = \"      \"\n        arg_lines = [f\"  {self.maybe_magenta(args)}\" for args in ohi.display_args]\n        arg_lines.append(self.maybe_magenta(f\"  {ohi.env_var}\"))\n        arg_lines.append(self.maybe_magenta(f\"  {ohi.config_key}\"))\n        choices = \"\" if ohi.choices is None else f\"one of: [{', '.join(ohi.choices)}]\"\n        choices_lines = [\n            f\"{indent}{'  ' if i != 0 else ''}{self.maybe_cyan(s)}\"\n            for i, s in enumerate(textwrap.wrap(f\"{choices}\", self._width))\n        ]\n        default_lines = format_value(RankedValue(Rank.HARDCODED, ohi.default), \"default: \", indent)\n        if not ohi.value_history:\n            # Should never happen, but this keeps mypy happy.\n            raise ValueError(\"No value history - options not parsed.\")\n        final_val = ohi.value_history.final_value\n        curr_value_lines = format_value(final_val, \"current value: \", indent)\n\n        interesting_ranked_values = [\n            rv\n            for rv in reversed(ohi.value_history.ranked_values)\n            if rv.rank not in (Rank.NONE, Rank.HARDCODED, final_val.rank)\n        ]\n        value_derivation_lines = [\n            line\n            for rv in interesting_ranked_values\n            for line in format_value(rv, \"overrode: \", f\"{indent}    \")\n        ]\n        description_lines = hard_wrap(ohi.help, indent=len(indent), width=self._width)\n        lines = [\n            *arg_lines,\n            *choices_lines,\n            *default_lines,\n            *curr_value_lines,\n            *value_derivation_lines,\n            *description_lines,\n        ]\n        if ohi.deprecated_message:\n            maybe_colorize = self.maybe_red if ohi.deprecation_active else self.maybe_yellow\n            lines.append(maybe_colorize(f\"{indent}{ohi.deprecated_message}\"))\n            if ohi.removal_hint:\n                lines.append(maybe_colorize(f\"{indent}{ohi.removal_hint}\"))\n        return lines\n", "path": "src/python/pants/help/help_formatter.py"}], "after_files": [{"content": "# Copyright 2015 Pants project contributors (see CONTRIBUTORS.md).\n# Licensed under the Apache License, Version 2.0 (see LICENSE).\n\nimport json\nimport textwrap\nfrom enum import Enum\nfrom typing import List, Optional\n\nfrom pants.help.help_info_extracter import OptionHelpInfo, OptionScopeHelpInfo, to_help_str\nfrom pants.help.maybe_color import MaybeColor\nfrom pants.option.ranked_value import Rank, RankedValue\nfrom pants.util.docutil import bin_name, terminal_width\nfrom pants.util.strutil import hard_wrap\n\n\nclass HelpFormatter(MaybeColor):\n    def __init__(self, *, show_advanced: bool, show_deprecated: bool, color: bool) -> None:\n        super().__init__(color=color)\n        self._show_advanced = show_advanced\n        self._show_deprecated = show_deprecated\n        self._width = terminal_width()\n\n    def format_options(self, oshi: OptionScopeHelpInfo):\n        \"\"\"Return a help message for the specified options.\"\"\"\n        lines = []\n\n        def add_option(ohis, *, category=None):\n            lines.append(\"\")\n            goal_or_subsystem = \"goal\" if oshi.is_goal else \"subsystem\"\n            display_scope = f\"`{oshi.scope}` {goal_or_subsystem}\" if oshi.scope else \"Global\"\n            if category:\n                title = f\"{display_scope} {category} options\"\n                lines.append(self.maybe_green(f\"{title}\\n{'-' * len(title)}\"))\n            else:\n                # The basic options section gets the description and options scope info.\n                # No need to repeat those in the advanced section.\n                title = f\"{display_scope} options\"\n                lines.append(self.maybe_green(f\"{title}\\n{'-' * len(title)}\\n\"))\n                lines.extend(hard_wrap(oshi.description, width=self._width))\n                lines.append(\" \")\n                lines.append(f\"Activated by {self.maybe_magenta(oshi.provider)}\")\n                config_section = f\"[{oshi.scope or 'GLOBAL'}]\"\n                lines.append(f\"Config section: {self.maybe_magenta(config_section)}\")\n            lines.append(\" \")\n            if not ohis:\n                lines.append(\"None available.\")\n                return\n            for ohi in ohis:\n                lines.extend([*self.format_option(ohi), \"\"])\n\n        add_option(oshi.basic)\n        if self._show_advanced:\n            add_option(oshi.advanced, category=\"advanced\")\n        if self._show_deprecated:\n            add_option(oshi.deprecated, category=\"deprecated\")\n        if oshi.advanced and not self._show_advanced:\n            lines.append(\n                self.maybe_green(\n                    f\"Advanced options available. You can list them by running \"\n                    f\"{bin_name()} help-advanced {oshi.scope}.\"\n                )\n            )\n        return [*lines, \"\"]\n\n    def format_option(self, ohi: OptionHelpInfo) -> List[str]:\n        \"\"\"Format the help output for a single option.\n\n        :param ohi: Extracted information for option to print\n        :return: Formatted help text for this option\n        \"\"\"\n\n        def maybe_parens(s: Optional[str]) -> str:\n            return f\" ({s})\" if s else \"\"\n\n        def format_value(ranked_val: RankedValue, prefix: str, left_padding: str) -> List[str]:\n            if isinstance(ranked_val.value, (list, dict)):\n                is_enum_list = (\n                    isinstance(ranked_val.value, list)\n                    and len(ranked_val.value) > 0\n                    and isinstance(ranked_val.value[0], Enum)\n                )\n                normalized_val = (\n                    [enum_elmt.value for enum_elmt in ranked_val.value]\n                    if is_enum_list\n                    else ranked_val.value\n                )\n                val_lines = json.dumps(normalized_val, sort_keys=True, indent=4).split(\"\\n\")\n            else:\n                val_lines = [to_help_str(ranked_val.value)]\n            val_lines[0] = f\"{prefix}{val_lines[0]}\"\n            val_lines[-1] = f\"{val_lines[-1]}{maybe_parens(ranked_val.details)}\"\n            val_lines = [self.maybe_cyan(f\"{left_padding}{line}\") for line in val_lines]\n            return val_lines\n\n        def wrap(s: str) -> List[str]:\n            return hard_wrap(s, indent=len(indent), width=self._width)\n\n        indent = \"      \"\n\n        arg_lines = [f\"  {self.maybe_magenta(args)}\" for args in ohi.display_args]\n        arg_lines.append(self.maybe_magenta(f\"  {ohi.env_var}\"))\n        arg_lines.append(self.maybe_magenta(f\"  {ohi.config_key}\"))\n\n        choices = \"\" if ohi.choices is None else f\"one of: [{', '.join(ohi.choices)}]\"\n        choices_lines = [\n            f\"{indent}{'  ' if i != 0 else ''}{self.maybe_cyan(s)}\"\n            for i, s in enumerate(textwrap.wrap(f\"{choices}\", self._width))\n        ]\n\n        deprecated_lines = []\n        if ohi.deprecated_message:\n            maybe_colorize = self.maybe_red if ohi.deprecation_active else self.maybe_yellow\n            deprecated_lines.extend(wrap(maybe_colorize(ohi.deprecated_message)))\n            if ohi.removal_hint:\n                deprecated_lines.extend(wrap(maybe_colorize(ohi.removal_hint)))\n\n        default_lines = format_value(RankedValue(Rank.HARDCODED, ohi.default), \"default: \", indent)\n        if not ohi.value_history:\n            # Should never happen, but this keeps mypy happy.\n            raise ValueError(\"No value history - options not parsed.\")\n\n        final_val = ohi.value_history.final_value\n        curr_value_lines = format_value(final_val, \"current value: \", indent)\n\n        interesting_ranked_values = [\n            rv\n            for rv in reversed(ohi.value_history.ranked_values)\n            if rv.rank not in (Rank.NONE, Rank.HARDCODED, final_val.rank)\n        ]\n        value_derivation_lines = [\n            line\n            for rv in interesting_ranked_values\n            for line in format_value(rv, \"overrode: \", f\"{indent}    \")\n        ]\n        description_lines = wrap(ohi.help)\n        lines = [\n            *arg_lines,\n            *choices_lines,\n            *default_lines,\n            *curr_value_lines,\n            *value_derivation_lines,\n            *deprecated_lines,\n            *description_lines,\n        ]\n        return lines\n", "path": "src/python/pants/help/help_formatter.py"}]}