diff --git a/changelogs/fragments/tty_nowrap.yml b/changelogs/fragments/tty_nowrap.yml new file mode 100644 index 00000000000..083639ca48e --- /dev/null +++ b/changelogs/fragments/tty_nowrap.yml @@ -0,0 +1,2 @@ +bugfixes: + - Avoid wrapping output when no tty is present. diff --git a/lib/ansible/config/base.yml b/lib/ansible/config/base.yml index 5c64ea67107..e3a7dcaf14e 100644 --- a/lib/ansible/config/base.yml +++ b/lib/ansible/config/base.yml @@ -1783,6 +1783,16 @@ NETWORK_GROUP_MODULES: - {key: network_group_modules, section: defaults} type: list yaml: {key: defaults.network_group_modules} +NOTTY_WRAP: + name: no tty wrap + description: Toggle wrapping text in the abcense of a TTY + default: True + type: bool + version_added: '2.13' + env: + - name: ANSIBLE_NOTTY_WRAP + ini: + - {key: notty_wrap, section: defaults} INJECT_FACTS_AS_VARS: default: True description: diff --git a/lib/ansible/utils/display.py b/lib/ansible/utils/display.py index 85affd75a31..3dff0f549d0 100644 --- a/lib/ansible/utils/display.py +++ b/lib/ansible/utils/display.py @@ -428,6 +428,7 @@ class Display(metaclass=Singleton): log_only: bool = False, newline: bool = True, caplevel: int | None = None, + nowrap: bool = False, ) -> None: """ Display a message to the user @@ -445,12 +446,18 @@ class Display(metaclass=Singleton): if not log_only: - has_newline = msg.endswith(u'\n') - if has_newline: - msg2 = msg[:-1] + istty = stderr and sys.__stderr__.isatty() or not stderr and sys.__stdout__.isatty() + + if istty and not nowrap: + wrapped = textwrap.wrap(msg, self.columns, drop_whitespace=False) + msg2 = "\n".join(wrapped) + "\n" else: msg2 = msg + has_newline = msg.endswith(u'\n') + if has_newline: + msg2 = msg2[:-1] + if color: msg2 = stringc(msg2, color) @@ -677,6 +684,7 @@ class Display(metaclass=Singleton): deprecator: _messages.PluginInfo | None = None, help_text: str | None = None, obj: t.Any = None, + wrap_text: bool = C.NOTTY_WRAP, ) -> None: """ Display a deprecation warning message, if enabled. @@ -855,7 +863,7 @@ class Display(metaclass=Singleton): if star_len <= 3: star_len = 3 stars = u"*" * star_len - self.display(u"\n%s %s" % (msg, stars), color=color) + self.display(u"\n%s %s" % (msg, stars), color=color, nowrap=True) @_proxy def banner_cowsay(self, msg: str, color: str | None = None) -> None: @@ -873,8 +881,9 @@ class Display(metaclass=Singleton): runcmd.append(to_bytes(msg)) cmd = subprocess.Popen(runcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (out, err) = cmd.communicate() - self.display(u"%s\n" % to_text(out), color=color) + self.display(u"%s\n" % to_text(out), color=color, nowrap=True) +<<<<<<< HEAD def error_as_warning( self, msg: str | None, @@ -927,6 +936,14 @@ class Display(metaclass=Singleton): event = _error_factory.ControllerEventFactory.from_exception(msg, _traceback.is_traceback_enabled(_traceback.TracebackEvent.ERROR)) wrap_text = False +======= + @_proxy + def error(self, msg: str, wrap_text: bool = C.NOTTY_WRAP) -> None: + if wrap_text: + new_msg = u"\n[ERROR]: %s" % msg + wrapped = textwrap.wrap(new_msg, self.columns) + new_msg = u"\n".join(wrapped) + u"\n" +>>>>>>> 175789f85e7 (no tty, no wrap) else: event = _messages.Event( msg=msg,