Просмотр исходного кода

tools: fix progress output in asyncio.run with zero terminal width

Currently the forced progress in RunTool is trying to fit the output
line into a terminal width, but it doesn't take into an account a
situation when the terminal width is reported as zero. This manifests
when running in docker image with redirected output and can be seen
in the github workflow output for esp-idf-ci-action.

docker run --rm -t my_ubuntu_esp python3 -c 'import os,sys; print(os.get_terminal_size(), sys.stdout.isatty())'
os.terminal_size(columns=238, lines=59) True

vs

docker run --rm -t my_ubuntu_esp python3 -c 'import os,sys; print(os.get_terminal_size(), sys.stdout.isatty())' | tee
os.terminal_size(columns=0, lines=0) True

Since the output is reported as tty and the terminal width as 0, the
fit_text_in_terminal() function returns empty string. I also verified this
by running idf.py build inside a testing docker image.

This fix adjusts the fit_text_in_terminal() function to return original
line if the terminal width is zero.

Also simplify the progress print and use same approach as ninja
https://github.com/ninja-build/ninja/blob/master/src/line_printer.cc#L66

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Frantisek Hrbata 2 лет назад
Родитель
Сommit
84deb34035
1 измененных файлов с 4 добавлено и 3 удалено
  1. 4 3
      tools/idf_py_actions/tools.py

+ 4 - 3
tools/idf_py_actions/tools.py

@@ -179,6 +179,8 @@ def fit_text_in_terminal(out: str) -> str:
     """Fit text in terminal, if the string is not fit replace center with `...`"""
     space_for_dots = 3  # Space for "..."
     terminal_width, _ = os.get_terminal_size()
+    if not terminal_width:
+        return out
     if terminal_width <= space_for_dots:
         # if the wide of the terminal is too small just print dots
         return '.' * terminal_width
@@ -273,9 +275,8 @@ class RunTool:
 
         def print_progression(output: str) -> None:
             # Print a new line on top of the previous line
-            sys.stdout.write('\x1b[K')
-            print('\r', end='')
-            print(fit_text_in_terminal(output.strip('\n\r')), end='', file=output_stream)
+            print('\r' + fit_text_in_terminal(output.strip('\n\r')) + '\x1b[K', end='', file=output_stream)
+            output_stream.flush()
 
         async def read_stream() -> Optional[str]:
             try: