Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions app/atomic_svc.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,12 @@ def _handle_multiline_commands(cmd, executor):
@staticmethod
def _concatenate_shell_commands(command_lines):
"""Concatenate multiple shell command lines. The ; character won't be added at the end of each command if the
command line ends in "then" or "do" or already ends with a ; character."""
command line ends in "then" or "do" or already ends with a ; character.
Whitespace-only lines are skipped to avoid producing stray ';' separators."""
to_concat = []
num_lines = len(command_lines)
for index, cmd in enumerate(command_lines):
non_empty_lines = [cmd for cmd in command_lines if cmd.strip()]
num_lines = len(non_empty_lines)
for index, cmd in enumerate(non_empty_lines):
to_concat.append(cmd)
if re.search(r'do\s*$', cmd) or re.search(r'then\s*$', cmd) or re.search(r';\s*$', cmd):
if not re.search(r'\s+$', cmd):
Expand Down
14 changes: 14 additions & 0 deletions tests/test_atomic_svc.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import hashlib
import os
import re
import pytest

from plugins.atomic.app.atomic_svc import AtomicService
Expand Down Expand Up @@ -178,6 +179,19 @@ def test_handle_multiline_command_shell_ifthen(self):
want = 'if condition; then innercommand; innercommand2; fi'
assert AtomicService._handle_multiline_commands(commands, 'sh') == want

def test_handle_multiline_command_no_extra_semicolon_after_fi(self):
"""Regression test for issue #3097: whitespace-only lines between prereq block
(ending with 'fi;') and the ability command must not produce a stray '; ' separator,
which resulted in commands like 'fi; ; ip neighbour show'."""
# Simulate the precmd built by _prepare_executor:
# dep_construct ends with 'fi;', then ' \n ' (two spaces) separates it from the
# ability command — matching the double-space pattern of the actual bug report.
commands = 'if [ -x "$(command -v ip)" ]; then : ; else apt-get install iproute2 -y; fi;\n \n ip neighbour show'
result = AtomicService._handle_multiline_commands(commands, 'sh')
assert not re.search(r';\s+;', result), \
f"Unexpected consecutive semicolons with only whitespace between them in: {result!r}"
assert 'ip neighbour show' in result
Comment on lines +182 to +193
Comment on lines +189 to +193

def test_use_default_inputs(self, atomic_svc, atomic_test):
platform = 'windows'
string_to_analyze = '#{recon_commands} -a'
Expand Down
Loading