Skip to content

Commit c8dcd4b

Browse files
authored
fix: console output (#8)
1 parent e724658 commit c8dcd4b

File tree

4 files changed

+53
-8
lines changed

4 files changed

+53
-8
lines changed

docs/images/screenshot.png

1.77 KB
Loading

readme.pkg.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Tugboat is a linter to streamline your `Argo Workflows <https://argoproj.github.
1616
| ^^^^^^^
1717
| └ WF001 at .spec.entrypoint in test-
1818
7 | templates:
19+
8 | - name: whalesay
1920
2021
Entrypoint 'ducksay' is not defined in any template.
2122
Defined entrypoints: 'whalesay'.

tests/console/test_output_console.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import pytest
55

6-
from tugboat.console.outputs.console import report
6+
from tugboat.console.outputs.console import _calc_highlight_range, report
77

88

99
class TestReport:
@@ -46,6 +46,7 @@ def test_error(self, monkeypatch: pytest.MonkeyPatch, fixture_dir: Path):
4646
" 1 | apiVersion: argoproj.io/v1alpha1",
4747
" | └ T01 at . in hello-world-",
4848
" 2 | kind: Workflow",
49+
" 3 | metadata:",
4950
"",
5051
" Test error message",
5152
"",
@@ -84,6 +85,7 @@ def test_failure(self, monkeypatch: pytest.MonkeyPatch, fixture_dir: Path):
8485
" | ^^^^^",
8586
" | └ T02 at .spec.entrypoint in hello-",
8687
" 7 | templates:",
88+
" 8 | - name: hello",
8789
"",
8890
" Test failure message",
8991
"",
@@ -121,6 +123,7 @@ def test_skipped(self, monkeypatch: pytest.MonkeyPatch, fixture_dir: Path):
121123
" 2 | kind: Workflow",
122124
" | └ T03 at .kind in hello-world-",
123125
" 3 | metadata:",
126+
" 4 | generateName: hello-world-",
124127
"",
125128
" Test skipped message",
126129
"",
@@ -159,3 +162,21 @@ def test_colored(
159162
output = stream.getvalue()
160163

161164
assert isinstance(output, str)
165+
166+
167+
class TestCalcHighlightRange:
168+
169+
def test_success(self):
170+
start, end = _calc_highlight_range("hello user 1234", 0, 1234)
171+
assert start == 11
172+
assert end == 15
173+
174+
def test_not_found(self):
175+
assert _calc_highlight_range("hello world", 2, "hello") is None
176+
assert _calc_highlight_range("hello world", 0, "not-found") is None
177+
178+
def test_empty(self):
179+
assert _calc_highlight_range("hello world", 0, " ") is None
180+
181+
def test_none(self):
182+
assert _calc_highlight_range("hello world; None", 0, None) is None

tugboat/console/outputs/console.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
if typing.TYPE_CHECKING:
1212
from collections.abc import Callable, Iterator
1313
from pathlib import Path
14-
from typing import IO
14+
from typing import IO, Any
1515

1616
from tugboat.analyze import AugmentedDiagnosis
1717

@@ -73,9 +73,12 @@ def report_diagnosis(echo: Callable, file: Path, diagnosis: AugmentedDiagnosis):
7373
# default to the column number, but if the input is present, use that instead
7474
indent_before_caret = " " * max(diagnosis["column"] - 1, 0)
7575

76-
if diagnosis["input"] is not None and str(diagnosis["input"]) in line:
77-
col_start = line.index(str(diagnosis["input"]))
78-
col_end = col_start + len(str(diagnosis["input"]))
76+
if range_ := _calc_highlight_range(
77+
line=line,
78+
offset=diagnosis["column"] - 1,
79+
input_=diagnosis["input"],
80+
):
81+
col_start, col_end = range_
7982
indent_before_caret = " " * col_start
8083

8184
# print the underline
@@ -116,11 +119,31 @@ def report_diagnosis(echo: Callable, file: Path, diagnosis: AugmentedDiagnosis):
116119
def get_content_near(file: Path, target_line: int) -> Iterator[tuple[int, str]]:
117120
target_line -= 1 # 1-based to 0-based
118121
content = read_file(file).splitlines()
119-
start = max(0, target_line - LINES_BEHIND)
120-
end = min(len(content), target_line + LINES_AHEAD)
121-
yield from enumerate(content[start:end], start + 1)
122+
start = max(0, target_line - LINES_AHEAD)
123+
end = min(len(content), target_line + LINES_BEHIND)
124+
yield from enumerate(content[start : end + 1], start + 1)
122125

123126

124127
@functools.lru_cache(1)
125128
def read_file(path: Path) -> str:
126129
return path.read_text()
130+
131+
132+
def _calc_highlight_range(line: str, offset: int, input_: Any):
133+
"""
134+
Calculate the range to highlight in the line.
135+
"""
136+
if input_ is None:
137+
return # early escape if no value is provided
138+
139+
value = str(input_)
140+
if not value.strip():
141+
return # prevent highlighting empty strings
142+
143+
try:
144+
col_start = line.index(value, offset)
145+
except ValueError:
146+
return
147+
148+
col_end = col_start + len(value)
149+
return col_start, col_end

0 commit comments

Comments
 (0)