Skip to content

Commit

Permalink
oelint.vars.multilineident: rework fix
Browse files Browse the repository at this point in the history
and handle the last line of the input in a better way

Closes #662

Signed-off-by: Konrad Weihmann <[email protected]>
  • Loading branch information
priv-kweihmann committed Nov 26, 2024
1 parent 299683f commit 74c3518
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 7 deletions.
35 changes: 28 additions & 7 deletions oelint_adv/rule_base/rule_var_multilineindent.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ def __init__(self) -> None:
severity='info',
message='On a multiline assignment, line indent is desirable. {a} set, {b} desirable')

def __line_stats(self, i: Variable) -> List[Tuple[int, str]]:
def __line_stats(self, i: Variable) -> Tuple[int, int, List[Tuple[int, int, str]]]:
_map = []

_lines = i.VarValueStripped.replace('\x1b"', '"').split('\x1b')
non_empty_line_indent = 4
first_line_has_content = False
last_line_indent = 0
if _lines[0].strip():
first_line_has_content = True
non_empty_line_indent = i.Raw.index(_lines[0])
last_line_indent = non_empty_line_indent

for index, value in enumerate(_lines):
if value.strip(' \x1b'):
Expand All @@ -32,15 +34,15 @@ def __line_stats(self, i: Variable) -> List[Tuple[int, str]]:
else:
_map.append((0, 0, value.lstrip()))

return _map
return (last_line_indent, non_empty_line_indent, _map)

def check(self, _file: str, stash: Stash) -> List[Tuple[str, int, str]]:
res = []
items: List[Variable] = stash.GetItemsFor(filename=_file, classifier=Variable.CLASSIFIER)
for i in items:
if not i.IsMultiLine():
continue
_indent_map = self.__line_stats(i)
_, _, _indent_map = self.__line_stats(i)
for index, _line in enumerate(_indent_map):
expected, actual, _ = _line
if expected != actual:
Expand All @@ -55,21 +57,40 @@ def fix(self, _file: str, stash: Stash) -> List[str]:
if not i.IsMultiLine():
continue
_lines = i.VarValueStripped.split('\x1b')
_indent_map = self.__line_stats(i)
_last_line_indent, _standard_indent, _indent_map = self.__line_stats(i)

def _rreplace(in_: str, needle: str, repl: str) -> str:
return in_[::-1].replace(needle[::-1], repl[::-1], 1)[::-1]

fix_applied = False
for index, value in enumerate(_lines):
if value != _indent_map[index][2]:
if not value.strip():
continue
replacement = _indent_map[index][2]
fix_applied = True
# Note: we need to start replacing from the back of the string
# as otherwise a last line containing only whitespace
# will affect prior lines
i.VarValue = _rreplace(i.VarValue, value, _indent_map[index][2])
i.Raw = _rreplace(i.Raw, value, _indent_map[index][2])
i.RealRaw = _rreplace(i.RealRaw, value, _indent_map[index][2])
i.VarValue = _rreplace(i.VarValue, value, replacement)
i.Raw = _rreplace(i.Raw, value, replacement)
i.RealRaw = _rreplace(i.RealRaw, value, replacement)

_last_line = i.VarValue.split('\x1b')[-1]
_last_line_stripped = _last_line.strip()
if len(_last_line_stripped) > 1:
_last_line_expected = f'{" " * _standard_indent + _last_line_stripped}'
else:
_last_line_expected = f'{" " * _last_line_indent + _last_line_stripped}'

if _last_line != _last_line_expected:
if _last_line.strip('"\''):
i.VarValue = _rreplace(i.VarValue, _last_line, _last_line_expected)
i.Raw = _rreplace(i.Raw, _last_line, _last_line_expected)
i.RealRaw = _rreplace(i.RealRaw, _last_line, _last_line_expected)
fix_applied = True

if fix_applied:
res.append(_file)

return res
71 changes: 71 additions & 0 deletions tests/test_class_oelint_vars_multilineident.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,41 @@ def test_bad(self, input_, id_, occurrence):
"
''',
},
{
'oelint_adv_test.bb':
'''
A:append = " \\
b \\
c \\
"
''',
},
{
'oelint_adv_test.bb':
'''
A:append = " \\
b \\
c \\
"
''',
},
{
'oelint_adv_test.bb':
'''
A = "d \\
b \\
c \\
"
''',
},
{
'oelint_adv_test.bb':
'''
A = "d \\
b \\
c"
''',
},
],
)
def test_fix(self, input_, id_):
Expand Down Expand Up @@ -218,6 +253,42 @@ def test_bad_two(self, input_, id_, occurrence):
"
''',
},
{
'oelint_adv_test.bb':
'''
A = "a \\
some \\"quoted\\" value \\
"
''',
},
{
'oelint_adv_test.bb':
'''
A = "a \\
b"
''',
},
{
'oelint_adv_test.bb':
'''
A = "a \\
b"
B = "a \\
b"
''',
},
{
'oelint_adv_test.bb':
'''
A = "
a \\
b
"
B = "
a \\
b"
''',
},
],
)
def test_good(self, input_, id_, occurrence):
Expand Down

0 comments on commit 74c3518

Please sign in to comment.