Skip to content

Commit

Permalink
Improve terminal logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ofek committed Oct 8, 2023
1 parent 6a1f8dc commit 7fce478
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 28 deletions.
4 changes: 2 additions & 2 deletions src/hatch/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ def hatch(ctx: click.Context, env_name, project, verbose, quiet, color, interact
elif os.environ.get(AppEnvVars.FORCE_COLOR) == '1':
color = True

if interactive is None:
interactive = not running_in_ci()
if interactive is None and running_in_ci():
interactive = False

app = Application(ctx.exit, verbose - quiet, color, interactive)

Expand Down
2 changes: 1 addition & 1 deletion src/hatch/cli/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
class Application(Terminal):
def __init__(self, exit_func, *args, **kwargs):
super().__init__(*args, **kwargs)
self.platform = Platform(self.display_raw)
self.platform = Platform(self.output)
self.__exit_func = exit_func

self.config_file = ConfigFile()
Expand Down
72 changes: 48 additions & 24 deletions src/hatch/cli/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(
self,
console: Console,
*,
tty: bool,
is_interactive: bool,
verbosity: int,
spinner_style: str,
waiting_style: Style,
Expand All @@ -49,7 +49,7 @@ def __init__(
finalizer: Callable,
):
self.__console = console
self.__tty = tty
self.__is_interactive = is_interactive
self.__verbosity = verbosity
self.__spinner_style = spinner_style
self.__waiting_style = waiting_style
Expand Down Expand Up @@ -85,7 +85,7 @@ def __enter__(self) -> BorrowedStatus:
return self

message, _ = self.__messages[-1]
if not self.__tty:
if not self.__is_interactive:
self.__output(message)
return self

Expand All @@ -108,7 +108,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):

self.__output(Text(final_text, style=self.__success_style))

if not self.__tty:
if not self.__is_interactive:
return

self.__status.stop()
Expand All @@ -134,9 +134,9 @@ def __output(self, text):
class Terminal:
def __init__(self, verbosity, enable_color, interactive):
self.verbosity = verbosity
self.interactive = interactive
self.console = Console(
force_terminal=enable_color,
force_interactive=interactive,
no_color=enable_color is False,
markup=False,
emoji=False,
Expand All @@ -157,6 +157,28 @@ def __init__(self, verbosity, enable_color, interactive):
# Chosen as the default since it's compatible everywhere and looks nice
self._style_spinner = 'simpleDotsScrolling'

@cached_property
def kv_separator(self) -> Style:
return self.style_warning('->')

def style_success(self, text: str) -> Text:
return Text(text, style=self._style_level_success)

def style_error(self, text: str) -> Text:
return Text(text, style=self._style_level_error)

def style_warning(self, text: str) -> Text:
return Text(text, style=self._style_level_warning)

def style_waiting(self, text: str) -> Text:
return Text(text, style=self._style_level_waiting)

def style_info(self, text: str) -> Text:
return Text(text, style=self._style_level_info)

def style_debug(self, text: str) -> Text:
return Text(text, style=self._style_level_debug)

def initialize_styles(self, styles: dict): # no cov
# Lazily display errors so that they use the correct style
errors = []
Expand Down Expand Up @@ -194,31 +216,31 @@ def display_error(self, text='', *, stderr=True, indent=None, link=None, **kwarg
if self.verbosity < -2: # noqa: PLR2004
return

self.output(text, self._style_level_error, stderr=stderr, indent=indent, link=link, **kwargs)
self._output(text, self._style_level_error, stderr=stderr, indent=indent, link=link, **kwargs)

def display_warning(self, text='', *, stderr=True, indent=None, link=None, **kwargs):
if self.verbosity < -1:
return

self.output(text, self._style_level_warning, stderr=stderr, indent=indent, link=link, **kwargs)
self._output(text, self._style_level_warning, stderr=stderr, indent=indent, link=link, **kwargs)

def display_info(self, text='', *, stderr=True, indent=None, link=None, **kwargs):
if self.verbosity < 0:
return

self.output(text, self._style_level_info, stderr=stderr, indent=indent, link=link, **kwargs)
self._output(text, self._style_level_info, stderr=stderr, indent=indent, link=link, **kwargs)

def display_success(self, text='', *, stderr=True, indent=None, link=None, **kwargs):
if self.verbosity < 0:
return

self.output(text, self._style_level_success, stderr=stderr, indent=indent, link=link, **kwargs)
self._output(text, self._style_level_success, stderr=stderr, indent=indent, link=link, **kwargs)

def display_waiting(self, text='', *, stderr=True, indent=None, link=None, **kwargs):
if self.verbosity < 0:
return

self.output(text, self._style_level_waiting, stderr=stderr, indent=indent, link=link, **kwargs)
self._output(text, self._style_level_waiting, stderr=stderr, indent=indent, link=link, **kwargs)

def display_debug(self, text='', level=1, *, stderr=True, indent=None, link=None, **kwargs):
if not 1 <= level <= 3: # noqa: PLR2004
Expand All @@ -227,7 +249,7 @@ def display_debug(self, text='', level=1, *, stderr=True, indent=None, link=None
elif self.verbosity < level:
return

self.output(text, self._style_level_debug, stderr=stderr, indent=indent, link=link, **kwargs)
self._output(text, self._style_level_debug, stderr=stderr, indent=indent, link=link, **kwargs)

def display_mini_header(self, text, *, stderr=False, indent=None, link=None):
if self.verbosity < 0:
Expand All @@ -243,7 +265,10 @@ def display_header(self, title='', *, stderr=False):
def display_markdown(self, text, **kwargs): # no cov
from rich.markdown import Markdown

self.display_raw(Markdown(text), **kwargs)
self.output(Markdown(text), **kwargs)

def display_pair(self, key, value):
self.output(self.style_success(key), self.kv_separator, value)

def display_table(self, title, columns, *, show_lines=False, column_options=None, force_ascii=False, num_rows=0):
from rich.table import Table
Expand Down Expand Up @@ -284,7 +309,7 @@ def display_table(self, title, columns, *, show_lines=False, column_options=None
def status(self) -> BorrowedStatus:
return BorrowedStatus(
self.console,
tty=self.interactive and self.console.is_terminal,
is_interactive=self.console.is_interactive,
verbosity=self.verbosity,
spinner_style=self._style_spinner,
waiting_style=self._style_level_waiting,
Expand All @@ -296,30 +321,29 @@ def status(self) -> BorrowedStatus:
def status_if(self, *args, condition: bool, **kwargs) -> TerminalStatus:
return self.status(*args, **kwargs) if condition else NullStatus()

def output(self, text='', style=None, *, stderr=False, indent=None, link=None, **kwargs):
kwargs.setdefault('overflow', 'ignore')
kwargs.setdefault('no_wrap', True)
kwargs.setdefault('crop', False)

def _output(self, text='', style=None, *, stderr=False, indent=None, link=None, **kwargs):
if indent:
text = indent_text(text, indent)

if link:
style = style.update_link(self.platform.format_file_uri(link))

self.output(text, stderr=stderr, style=style, **kwargs)

def output(self, *args, stderr=False, **kwargs):
kwargs.setdefault('overflow', 'ignore')
kwargs.setdefault('no_wrap', True)
kwargs.setdefault('crop', False)

if not stderr:
self.console.print(text, style=style, **kwargs)
self.console.print(*args, **kwargs)
else:
self.console.stderr = True
try:
self.console.print(text, style=style, **kwargs)
self.console.print(*args, **kwargs)
finally:
self.console.stderr = False

def display_raw(self, text, **kwargs):
# No styling
self.console.print(text, overflow='ignore', no_wrap=True, crop=False, **kwargs)

@staticmethod
def prompt(text, **kwargs):
return click.prompt(text, **kwargs)
Expand Down
3 changes: 2 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def isolation() -> Generator[Path, None, None]:

with d.as_cwd(default_env_vars):
os.environ.pop(AppEnvVars.ENV_ACTIVE, None)
os.environ.pop(AppEnvVars.FORCE_COLOR, None)
yield d


Expand Down Expand Up @@ -251,7 +252,7 @@ def devpi(tmp_path_factory, worker_id):
for _ in range(60):
output = subprocess.check_output(['docker', 'logs', 'hatch-devpi']).decode('utf-8')
if f'Serving index {dp.user}/{dp.index}' in output:
time.sleep(2)
time.sleep(5)
break

time.sleep(1)
Expand Down

0 comments on commit 7fce478

Please sign in to comment.