Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrap ./pants help based on actual terminal width #11378

Merged
merged 4 commits into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/python/pants/help/help_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
# Licensed under the Apache License, Version 2.0 (see LICENSE).

import json
import textwrap
from enum import Enum
from textwrap import wrap
from typing import List, Optional

from pants.help.help_info_extracter import OptionHelpInfo, OptionScopeHelpInfo, to_help_str
from pants.help.maybe_color import MaybeColor
from pants.option.ranked_value import Rank, RankedValue
from pants.util.docutil import terminal_width
from pants.util.strutil import hard_wrap


Expand All @@ -34,7 +35,7 @@ def add_option(ohis, *, category=None):
# No need to repeat those in the advanced section.
title = f"{display_scope} options"
lines.append(self.maybe_green(f"{title}\n{'-' * len(title)}\n"))
lines.extend(hard_wrap(oshi.description))
lines.extend(hard_wrap(oshi.description, width=terminal_width()))
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each call to terminal_width is a syscall, so it might be good to just call it once at the top.

lines.append(" ")
config_section = f"[{oshi.scope or 'GLOBAL'}]"
lines.append(f"Config section: {self.maybe_magenta(config_section)}")
Expand Down Expand Up @@ -89,7 +90,7 @@ def format_value(ranked_val: RankedValue, prefix: str, left_padding: str) -> Lis
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(wrap(f"{choices}", 96))
for i, s in enumerate(textwrap.wrap(f"{choices}", terminal_width()))
]
default_lines = format_value(RankedValue(Rank.HARDCODED, ohi.default), "default: ", indent)
if not ohi.value_history:
Expand All @@ -108,7 +109,7 @@ def format_value(ranked_val: RankedValue, prefix: str, left_padding: str) -> Lis
for rv in interesting_ranked_values
for line in format_value(rv, "overrode: ", f"{indent} ")
]
description_lines = hard_wrap(ohi.help, indent=len(indent))
description_lines = hard_wrap(ohi.help, indent=len(indent), width=terminal_width())
lines = [
*arg_lines,
*choices_lines,
Expand Down
9 changes: 6 additions & 3 deletions src/python/pants/help/help_printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
VersionHelp,
)
from pants.option.scope import GLOBAL_SCOPE
from pants.util.docutil import terminal_width
from pants.util.strutil import first_paragraph, hard_wrap


Expand Down Expand Up @@ -112,7 +113,7 @@ def _print_thing_help(self) -> None:

@staticmethod
def _format_summary_description(descr: str, chars_before_description: int) -> str:
lines = textwrap.wrap(descr, 96 - chars_before_description)
lines = textwrap.wrap(descr, terminal_width() - chars_before_description)
if len(lines) > 1:
lines = [
lines[0],
Expand Down Expand Up @@ -257,7 +258,7 @@ def _print_target_help(self, target_alias: str) -> None:
self._print_title(target_alias)
tinfo = self._all_help_info.name_to_target_type_info[target_alias]
if tinfo.description:
formatted_desc = "\n".join(hard_wrap(tinfo.description))
formatted_desc = "\n".join(hard_wrap(tinfo.description, width=terminal_width()))
print(formatted_desc)
print("\n\nValid fields:")
for field in sorted(tinfo.fields, key=lambda x: x.alias):
Expand All @@ -268,7 +269,9 @@ def _print_target_help(self, target_alias: str) -> None:
print(self.maybe_cyan(f"{indent}type: {field.type_hint}"))
print(self.maybe_cyan(f"{indent}{required_or_default}"))
if field.description:
formatted_desc = "\n".join(hard_wrap(field.description, indent=len(indent)))
formatted_desc = "\n".join(
hard_wrap(field.description, indent=len(indent), width=terminal_width())
)
print(formatted_desc)
print()

Expand Down
6 changes: 6 additions & 0 deletions src/python/pants/init/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,16 @@ def initialize_stdio(global_bootstrap_options: OptionValueContainer) -> Iterator
tuple(message_regex_filters),
log_path,
)
sys.__stdin__, sys.__stdout__, sys.__stderr__ = sys.stdin, sys.stdout, sys.stderr
# Install a Python logger that will route through the Rust logger.
with _python_logging_setup(global_level, print_stacktrace):
yield
finally:
sys.__stdin__, sys.__stdout__, sys.__stderr__ = (
original_stdin,
original_stdout,
original_stderr,
)
sys.stdin, sys.stdout, sys.stderr = original_stdin, original_stdout, original_stderr
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: A bit nicer symmetry with the above maybe:

Suggested change
sys.__stdin__, sys.__stdout__, sys.__stderr__ = (
original_stdin,
original_stdout,
original_stderr,
)
sys.stdin, sys.stdout, sys.stderr = original_stdin, original_stdout, original_stderr
sys.stdin, sys.stdout, sys.stderr = original_stdin, original_stdout, original_stderr
sys.__stdin__, sys.__stdout__, sys.__stderr__ = sys.stdin, sys.stdout, sys.stderr



Expand Down
8 changes: 8 additions & 0 deletions src/python/pants/util/docutil.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

import shutil

from pants.version import MAJOR_MINOR


# NB: This is not memoized because that would cause Pants to not pick up terminal resizing when
# using pantsd.
def terminal_width(*, fallback: int = 96, padding: int = 2) -> int:
return shutil.get_terminal_size(fallback=(fallback, 24)).columns - padding


def docs_url(slug: str) -> str:
"""Link to the Pants docs using the current version of Pants."""
return f"https://www.pantsbuild.org/v{MAJOR_MINOR}/docs/{slug}"