diff --git a/oelint_adv/rule_base/rule_var_multilineindent.py b/oelint_adv/rule_base/rule_var_multilineindent.py index 3359175..c5c2c81 100644 --- a/oelint_adv/rule_base/rule_var_multilineindent.py +++ b/oelint_adv/rule_base/rule_var_multilineindent.py @@ -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'): @@ -32,7 +34,7 @@ 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 = [] @@ -40,7 +42,7 @@ def check(self, _file: str, stash: Stash) -> List[Tuple[str, int, str]]: 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: @@ -55,7 +57,7 @@ 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] @@ -63,13 +65,32 @@ def _rreplace(in_: str, needle: str, repl: str) -> str: 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 diff --git a/tests/test_class_oelint_vars_multilineident.py b/tests/test_class_oelint_vars_multilineident.py index 4de42dd..c747734 100644 --- a/tests/test_class_oelint_vars_multilineident.py +++ b/tests/test_class_oelint_vars_multilineident.py @@ -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_): @@ -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):