module

Krikri::PluginHelpers::AnsibleSplitlines

AnsibleSplitlines - pure logic matching Ansible's stdout_lines/stderr_lines derivation, which is built from Python's str.splitlines(), not Crystal's plain String#split("\n"). The two differ on the cases that matter for real command output:

  • Boundary set: Python splits on the full str.splitlines() set - "\r\n" as one break, plus single "\n", "\r", "\v" (\x0b), "\f" (\x0c), \x1c, \x1d, \x1e, \x85 (NEL), U+2028 and U+2029 - while split("\n") treats every other boundary as ordinary text. The "\r" case is issue #614: curl's progress meter, written to stderr by a command task's script (install-sdk.sh's curl fetch), is carriage-return separated, so Ansible reports each progress stage as its own *_lines element (with an empty element where a line ends in "\n" immediately before the first "\r"), and a single element containing raw "\r"s is a byte-for-byte divergence.
  • Empty input - Python's splitlines() gives [], Crystal's split gives [""] (one empty element).
  • Any trailing boundary, which split() turns into a spurious final empty element that splitlines() never produces - but a boundary followed by another boundary (or end) still yields its own empty element, e.g. "a\n\r" -> ["a", ""].

Found via konstruktoid-hardening's "Delete unmanaged UFW rules" task: its ufw_not_managed command's grep -v legitimately matches nothing (every rule this role adds is tagged "ansible managed" and filtered out), producing empty stdout; ufw_not_managed.stdout_lines | length > 0 should then gate the whole loop off, but the spurious [""] made it loop once with an empty item, running ufw delete with no rule spec at all - which real ufw rejects with "ERROR: Invalid syntax".

Shared by the plugins that produce stdout/stderr (command, shell - each module that has stdout/stderr sets the *_lines keys itself in Ansible) AND TaskExecutor's register augmentation (which derives them centrally for results that predate a plugin carrying its own).

Class methods

split(text : String) : Array(String)
Source