Repository: ansible-collections/community.general
Pull request #10087: Feat: Add callback plugin print_task
Author: login: demonpig
Labels: name: feature
description: This issue/PR relates to a feature request
name: callback
description: callback plugin
name: tests
description: tests
name: integration
description: tests/integration
name: new_contributor
description: Help guide this first time contributor
name: plugins
description: plugin (any type)
name: backport-10
description: Automatically create a backport for the stable-10 branch
Created: 2025-05-01T03:19:43Z | Merged: 2025-05-18T20:40:02Z

Prints task snippet to job output.

##### SUMMARY
I figured this might be useful for debugging purposes when executing playbooks. All this callback plugin is doing, is printing out the task snippet as it would show within the playbook. See example below.

Playbook:
```
---

- name: Test
  hosts: all
  gather_facts: false

  tasks:
    - name: TEST | HEllo
      ansible.builtin.shell: echo {{ item }}
      when: false
      async: 10
      poll: 1
      loop:
        - 1
        - 2
        - 3
    # - name: Command 2
      # async: 1
      # ansible.builtin.shell: |
      #   echo hello
      #   exit 1

    - ansible.builtin.shell: echo hello

    - ansible.builtin.ping:
```

Command:
```
ansible-playbook -i inventory playbook.yml -v
```

Output:
```
PLAY [Test] ********************************************************************

TASK [TEST | HEllo] ************************************************************

- name: TEST | HEllo
  ansible.builtin.shell: echo {{ item }}
  when: false
  async: 10
  poll: 1
  loop:
  - 1
  - 2
  - 3

skipping: [localhost] => (item=1)  => {"ansible_loop_var": "item", "changed": false, "false_condition": false, "item": 1, "skip_reason": "Conditional result was False"}
skipping: [localhost] => (item=2)  => {"ansible_loop_var": "item", "changed": false, "false_condition": false, "item": 2, "skip_reason": "Conditional result was False"}
skipping: [localhost] => (item=3)  => {"ansible_loop_var": "item", "changed": false, "false_condition": false, "item": 3, "skip_reason": "Conditional result was False"}
skipping: [localhost] => {"changed": false, "msg": "All items skipped"}

TASK [ansible.builtin.shell] ***************************************************

- ansible.builtin.shell: echo hello

changed: [localhost] => {"changed": true, "cmd": "echo hello", "delta": "0:00:00.005068", "end": "2025-04-30 23:14:05.140808", "msg": "", "rc": 0, "start": "2025-04-30 23:14:05.135740", "stderr": "", "stderr_lines": [], "stdout": "hello", "stdout_lines": ["hello"]}

TASK [ansible.builtin.ping] ****************************************************

- ansible.builtin.ping: None

ok: [localhost] => {"changed": false, "ping": "pong"}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
```

##### ISSUE TYPE
- Feature Pull Request

##### COMPONENT NAME
- `community.general.print_task`

##### ADDITIONAL INFORMATION



Diff:
diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml
index 40959861511..f1a76977765 100644
--- a/.github/BOTMETA.yml
+++ b/.github/BOTMETA.yml
@@ -77,6 +77,8 @@ files:
   $callbacks/opentelemetry.py:
     keywords: opentelemetry observability
     maintainers: v1v
+  $callbacks/print_task.py:
+    maintainers: demonpig
   $callbacks/say.py:
     keywords: brew cask darwin homebrew macosx macports osx
     labels: macos say
diff --git a/plugins/callback/print_task.py b/plugins/callback/print_task.py
new file mode 100644
index 00000000000..7407b0e8030
--- /dev/null
+++ b/plugins/callback/print_task.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2025, Max Mitschke <maxmitschke@fastmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+name: print_task
+type: aggregate
+short_description: Prints playbook task snippet to job output
+description:
+  - This plugin prints the currently executing playbook task to the job output.
+version_added: 10.7.0
+requirements:
+  - enable in configuration
+'''
+
+EXAMPLES = r'''
+ansible.cfg: >
+    # Enable plugin
+    [defaults]
+    callbacks_enabled=community.general.print_task
+'''
+
+from yaml import load, dump
+
+try:
+    from yaml import CSafeDumper as SafeDumper
+    from yaml import CSafeLoader as SafeLoader
+except ImportError:
+    from yaml import SafeDumper, SafeLoader
+
+from ansible.plugins.callback import CallbackBase
+
+
+class CallbackModule(CallbackBase):
+    """
+    This callback module tells you how long your plays ran for.
+    """
+    CALLBACK_VERSION = 2.0
+    CALLBACK_TYPE = 'aggregate'
+    CALLBACK_NAME = 'community.general.print_task'
+
+    CALLBACK_NEEDS_ENABLED = True
+
+    def __init__(self):
+        super(CallbackModule, self).__init__()
+        self._printed_message = False
+
+    def _print_task(self, task):
+        if hasattr(task, '_ds'):
+            task_snippet = load(str([task._ds.copy()]), Loader=SafeLoader)
+            task_yaml = dump(task_snippet, sort_keys=False, Dumper=SafeDumper)
+            self._display.display(f"\n{task_yaml}\n")
+            self._printed_message = True
+
+    def v2_playbook_on_task_start(self, task, is_conditional):
+        self._printed_message = False
+
+    def v2_runner_on_start(self, host, task):
+        if not self._printed_message:
+            self._print_task(task)
diff --git a/tests/integration/targets/callback_print_task/aliases b/tests/integration/targets/callback_print_task/aliases
new file mode 100644
index 00000000000..3e2dd244c18
--- /dev/null
+++ b/tests/integration/targets/callback_print_task/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+needs/target/callback
diff --git a/tests/integration/targets/callback_print_task/tasks/main.yml b/tests/integration/targets/callback_print_task/tasks/main.yml
new file mode 100644
index 00000000000..718ba607a77
--- /dev/null
+++ b/tests/integration/targets/callback_print_task/tasks/main.yml
@@ -0,0 +1,132 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests       #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Run tests
+  include_role:
+    name: callback
+  vars:
+    tests:
+      - name: community.general.print_task is not enabled
+        environment:
+          ANSIBLE_NOCOLOR: 'true'
+          ANSIBLE_FORCE_COLOR: 'false'
+        playbook: |
+          - hosts: testhost
+            gather_facts: false
+            tasks:
+              - name: Sample task
+                debug:
+                  msg: This is a test
+        expected_output: [
+            "",
+            "PLAY [testhost] ****************************************************************",
+            "",
+            "TASK [Sample task] *************************************************************",
+            "ok: [testhost] => {",
+            "    \"msg\": \"This is a test\"",
+            "}",
+            "",
+            "PLAY RECAP *********************************************************************",
+            "testhost                   : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   "
+        ]
+
+      - name: community.general.print_task is enabled
+        environment:
+          ANSIBLE_NOCOLOR: 'true'
+          ANSIBLE_FORCE_COLOR: 'false'
+          ANSIBLE_CALLBACKS_ENABLED: 'community.general.print_task'
+        playbook: |
+          - hosts: testhost
+            gather_facts: false
+            tasks:
+              - name: Sample task
+                debug:
+                  msg: This is a test
+        expected_output: [
+            "",
+            "PLAY [testhost] ****************************************************************",
+            "",
+            "TASK [Sample task] *************************************************************",
+            "",
+            "- name: Sample task",
+            "  debug:",
+            "    msg: This is a test",
+            "",
+            "ok: [testhost] => {",
+            "    \"msg\": \"This is a test\"",
+            "}",
+            "",
+            "PLAY RECAP *********************************************************************",
+            "testhost                   : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   "
+        ]
+
+      - name: Print with msg parameter on the same line
+        environment:
+          ANSIBLE_NOCOLOR: 'true'
+          ANSIBLE_FORCE_COLOR: 'false'
+          ANSIBLE_CALLBACKS_ENABLED: 'community.general.print_task'
+        playbook: |
+          - hosts: testhost
+            gather_facts: false
+            tasks:
+              - name: Sample task
+                debug: msg="This is a test"
+        expected_output: [
+            "",
+            "PLAY [testhost] ****************************************************************",
+            "",
+            "TASK [Sample task] *************************************************************",
+            "",
+            "- name: Sample task",
+            "  debug: msg=\"This is a test\"",
+            "",
+            "ok: [testhost] => {",
+            "    \"msg\": \"This is a test\"",
+            "}",
+            "",
+            "PLAY RECAP *********************************************************************",
+            "testhost                   : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   "
+        ]
+
+      - name: Task with additional parameters
+        environment:
+          ANSIBLE_NOCOLOR: 'true'
+          ANSIBLE_FORCE_COLOR: 'false'
+          ANSIBLE_CALLBACKS_ENABLED: 'community.general.print_task'
+        playbook: |
+          - hosts: testhost
+            gather_facts: false
+            tasks:
+              - name: Sample task
+                when: True
+                vars:
+                  test_var: "Hello World"
+                debug:
+                  var: test_var
+        expected_output: [
+            "",
+            "PLAY [testhost] ****************************************************************",
+            "",
+            "TASK [Sample task] *************************************************************",
+            "",
+            "- name: Sample task",
+            "  when: true",
+            "  vars:",
+            "    test_var: Hello World",
+            "  debug:",
+            "    var: test_var",
+            "",
+            "ok: [testhost] => {",
+            "    \"test_var\": \"Hello World\"",
+            "}",
+            "",
+            "PLAY RECAP *********************************************************************",
+            "testhost                   : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   "
+        ]
\ No newline at end of file


Reviews:
user: login: Akasurde
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-02T18:16:56Z
user: login: demonpig
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-03T02:59:33Z
user: login: felixfontein
body: Thanks for your contribution! If you haven't done so, please take a look at https://github.com/ansible-collections/community.general/blob/main/CONTRIBUTING.md#creating-new-modules-or-plugins.
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-04T19:47:44Z
user: login: bcoca
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-05T21:33:38Z
user: login: demonpig
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T18:32:31Z
user: login: felixfontein
body: I'd also use the C dumper here if available (and use the safe dumper instead of the default one).

Also, what do you think about @russoz comment?
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-15T05:24:45Z

Review comments:
diff_hunk: @@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2025, Max Mitschke <maxmitschke@fastmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+name: print_task
+type: aggregate
+short_description: Prints playbook task snippet to job output
+description:
+  - This is an Ansible callback plugin that will print the currently executing
+    playbook task to the job output.
+requirements:
path: plugins/callback/print_task.py
user: login: Akasurde
body: ```suggestion
version_added: 10.3.0 
requirements:
```
created_at: 2025-05-02T18:16:56Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2025, Max Mitschke <maxmitschke@fastmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+name: print_task
+type: aggregate
+short_description: Prints playbook task snippet to job output
+description:
+  - This is an Ansible callback plugin that will print the currently executing
+    playbook task to the job output.
+requirements:
path: plugins/callback/print_task.py
user: login: demonpig
body: I didnt realize that I could just click the commit suggestion and added what your suggestion myself.
created_at: 2025-05-03T02:59:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2025, Max Mitschke <maxmitschke@fastmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+name: print_task
+type: aggregate
+short_description: Prints playbook task snippet to job output
+description:
+  - This is an Ansible callback plugin that will print the currently executing
+    playbook task to the job output.
+version_added: 10.3.0
path: plugins/callback/print_task.py
user: login: felixfontein
body: 10.3.0 has been released some months ago. The next feature release will be 10.6.0:
```suggestion
version_added: 10.7.0
```
created_at: 2025-05-04T19:46:22Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2025, Max Mitschke <maxmitschke@fastmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+name: print_task
+type: aggregate
+short_description: Prints playbook task snippet to job output
+description:
+  - This is an Ansible callback plugin that will print the currently executing
+    playbook task to the job output.
path: plugins/callback/print_task.py
user: login: felixfontein
body: It's clear from the documentation that this is an Ansible callback plugin :)
```suggestion
  - This plugin prints the currently executing playbook task to the job output.
```
created_at: 2025-05-04T19:47:09Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2025, Max Mitschke <maxmitschke@fastmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+name: print_task
+type: aggregate
+short_description: Prints playbook task snippet to job output
+description:
+  - This plugin prints the currently executing playbook task to the job output.
+version_added: 10.7.0
+requirements:
+  - enable in configuration
+'''
+
+
+import yaml
path: plugins/callback/print_task.py
user: login: bcoca
body: I would advise against using 'plain' yaml, i would try using the CSafeLoader first (speed of C lib), fallback to SafeLoader (slower python) and avoid other loaders. See core's use of yaml lib when in doubt.
created_at: 2025-05-05T21:33:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2025, Max Mitschke <maxmitschke@fastmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+name: print_task
+type: aggregate
+short_description: Prints playbook task snippet to job output
+description:
+  - This plugin prints the currently executing playbook task to the job output.
+version_added: 10.7.0
+requirements:
+  - enable in configuration
+'''
+
+
+import yaml
path: plugins/callback/print_task.py
user: login: demonpig
body: Just updated the code to do this.
created_at: 2025-05-06T18:32:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2025, Max Mitschke <maxmitschke@fastmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+name: print_task
+type: aggregate
+short_description: Prints playbook task snippet to job output
+description:
+  - This plugin prints the currently executing playbook task to the job output.
+version_added: 10.7.0
+requirements:
+  - enable in configuration
+'''
+
+EXAMPLES = r'''
+ansible.cfg: >
+    # Enable plugin
+    [defaults]
+    callbacks_enabled=community.general.print_task
+'''
+
+from yaml import load, dump
+
+try:
+    from yaml import CSafeLoader as SafeLoader
path: plugins/callback/print_task.py
user: login: felixfontein
body: ```suggestion
    from yaml import CSafeDumper as SafeDumper
    from yaml import CSafeLoader as SafeLoader
```
created_at: 2025-05-15T05:23:38Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2025, Max Mitschke <maxmitschke@fastmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+name: print_task
+type: aggregate
+short_description: Prints playbook task snippet to job output
+description:
+  - This plugin prints the currently executing playbook task to the job output.
+version_added: 10.7.0
+requirements:
+  - enable in configuration
+'''
+
+EXAMPLES = r'''
+ansible.cfg: >
+    # Enable plugin
+    [defaults]
+    callbacks_enabled=community.general.print_task
+'''
+
+from yaml import load, dump
+
+try:
+    from yaml import CSafeLoader as SafeLoader
+except ImportError:
+    from yaml import SafeLoader
path: plugins/callback/print_task.py
user: login: felixfontein
body: ```suggestion
    from yaml import SafeDumper, SafeLoader
```
created_at: 2025-05-15T05:23:44Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2025, Max Mitschke <maxmitschke@fastmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+name: print_task
+type: aggregate
+short_description: Prints playbook task snippet to job output
+description:
+  - This plugin prints the currently executing playbook task to the job output.
+version_added: 10.7.0
+requirements:
+  - enable in configuration
+'''
+
+EXAMPLES = r'''
+ansible.cfg: >
+    # Enable plugin
+    [defaults]
+    callbacks_enabled=community.general.print_task
+'''
+
+from yaml import load, dump
+
+try:
+    from yaml import CSafeLoader as SafeLoader
+except ImportError:
+    from yaml import SafeLoader
+
+from ansible.plugins.callback import CallbackBase
+
+
+class CallbackModule(CallbackBase):
+    """
+    This callback module tells you how long your plays ran for.
+    """
+    CALLBACK_VERSION = 2.0
+    CALLBACK_TYPE = 'aggregate'
+    CALLBACK_NAME = 'community.general.print_task'
+
+    CALLBACK_NEEDS_ENABLED = True
+
+    def __init__(self):
+        super(CallbackModule, self).__init__()
+        self._printed_message = False
+
+    def _print_task(self, task):
+        if hasattr(task, '_ds'):
+            task_snippet = load(str([task._ds.copy()]), Loader=SafeLoader)
+            task_yaml = dump(task_snippet, sort_keys=False)
path: plugins/callback/print_task.py
user: login: felixfontein
body: ```suggestion
            task_yaml = dump(task_snippet, sort_keys=False, Dumper=SafeDumper)
```
created_at: 2025-05-15T05:24:09Z
author_association: COLLABORATOR

PR comments:
user: login: ansibullbot
created_at: 2025-05-01T03:50:17Z
body: The test `ansible-test sanity --test validate-modules` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/validate-modules.html)] failed with 4 errors:
```
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.author: Invalid author for dictionary value @ data['author']. Got 'Max Mitschke'
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.callback_type: extra keys not allowed @ data['callback_type']. Got 'aggregate'
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.type: required key not provided @ data['type']. Got None
plugins/callback/print_task.py:0:0: missing-gplv3-license: GPLv3 license header not found in the first 20 lines of the module
```
<!-- job_id: 144619 -->
<!-- job_id: 5173a2236e1b6f6bdb2145f023c1bf96 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pep8` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pep8.html)] failed with 11 errors:
```
plugins/callback/print_task.py:22:1: E302: expected 2 blank lines, found 1
plugins/callback/print_task.py:33:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:35:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:38:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:38:62: W291: trailing whitespace
plugins/callback/print_task.py:39:49: W291: trailing whitespace
plugins/callback/print_task.py:41:1: W293: blank line contains whitespace
plugins/callback/print_task.py:42:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:43:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:46:8: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:50:11: E111: indentation is not a multiple of 4
```
<!-- job_id: 144619 -->
<!-- job_id: 9fa07a0c2a0b05b68b4d2d500bb4b983 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pep8` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pep8.html)] failed with 11 errors:
```
plugins/callback/print_task.py:22:1: E302: expected 2 blank lines, found 1
plugins/callback/print_task.py:33:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:35:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:38:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:38:62: W291: trailing whitespace
plugins/callback/print_task.py:39:49: W291: trailing whitespace
plugins/callback/print_task.py:41:1: W293: blank line contains whitespace
plugins/callback/print_task.py:42:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:43:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:46:8: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:50:11: E111: indentation is not a multiple of 4
```
<!-- job_id: 144619 -->
<!-- job_id: 9fa07a0c2a0b05b68b4d2d500bb4b983 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pep8` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pep8.html)] failed with 11 errors:
```
plugins/callback/print_task.py:22:1: E302: expected 2 blank lines, found 1
plugins/callback/print_task.py:33:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:35:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:38:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:38:62: W291: trailing whitespace
plugins/callback/print_task.py:39:49: W291: trailing whitespace
plugins/callback/print_task.py:41:1: W293: blank line contains whitespace
plugins/callback/print_task.py:42:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:43:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:46:8: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:50:11: E111: indentation is not a multiple of 4
```
<!-- job_id: 144619 -->
<!-- job_id: 9fa07a0c2a0b05b68b4d2d500bb4b983 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pylint` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pylint.html)] failed with 3 errors:
```
plugins/callback/print_task.py:38:61: trailing-whitespace: Trailing whitespace
plugins/callback/print_task.py:39:48: trailing-whitespace: Trailing whitespace
plugins/callback/print_task.py:41:0: trailing-whitespace: Trailing whitespace
```
<!-- job_id: 144619 -->
<!-- job_id: 1caa5d6b7eff6b74daaee5c2592b768e -->
<!-- job_id: None -->
The test `ansible-test sanity --test validate-modules` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/validate-modules.html)] failed with 4 errors:
```
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.author: Invalid author for dictionary value @ data['author']. Got 'Max Mitschke'
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.callback_type: extra keys not allowed @ data['callback_type']. Got 'aggregate'
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.type: required key not provided @ data['type']. Got None
plugins/callback/print_task.py:0:0: missing-gplv3-license: GPLv3 license header not found in the first 20 lines of the module
```
<!-- job_id: 144619 -->
<!-- job_id: 5173a2236e1b6f6bdb2145f023c1bf96 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pylint` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pylint.html)] failed with 3 errors:
```
plugins/callback/print_task.py:38:61: trailing-whitespace: Trailing whitespace
plugins/callback/print_task.py:39:48: trailing-whitespace: Trailing whitespace
plugins/callback/print_task.py:41:0: trailing-whitespace: Trailing whitespace
```
<!-- job_id: 144619 -->
<!-- job_id: 1caa5d6b7eff6b74daaee5c2592b768e -->
<!-- job_id: None -->
The test `ansible-test sanity --test pylint` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pylint.html)] failed with 3 errors:
```
plugins/callback/print_task.py:38:61: trailing-whitespace: Trailing whitespace
plugins/callback/print_task.py:39:48: trailing-whitespace: Trailing whitespace
plugins/callback/print_task.py:41:0: trailing-whitespace: Trailing whitespace
```
<!-- job_id: 144619 -->
<!-- job_id: 1caa5d6b7eff6b74daaee5c2592b768e -->
<!-- job_id: None -->
The test `ansible-test sanity --test validate-modules` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/validate-modules.html)] failed with 4 errors:
```
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.author: Invalid author for dictionary value @ data['author']. Got 'Max Mitschke'
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.callback_type: extra keys not allowed @ data['callback_type']. Got 'aggregate'
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.type: required key not provided @ data['type']. Got None
plugins/callback/print_task.py:0:0: missing-gplv3-license: GPLv3 license header not found in the first 20 lines of the module
```
<!-- job_id: 144619 -->
<!-- job_id: 5173a2236e1b6f6bdb2145f023c1bf96 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pylint` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pylint.html)] failed with 3 errors:
```
plugins/callback/print_task.py:38:61: trailing-whitespace: Trailing whitespace
plugins/callback/print_task.py:39:48: trailing-whitespace: Trailing whitespace
plugins/callback/print_task.py:41:0: trailing-whitespace: Trailing whitespace
```
<!-- job_id: 144619 -->
<!-- job_id: 1caa5d6b7eff6b74daaee5c2592b768e -->
<!-- job_id: None -->
The test `ansible-test sanity --test validate-modules` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/validate-modules.html)] failed with 4 errors:
```
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.author: Invalid author for dictionary value @ data['author']. Got 'Max Mitschke'
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.callback_type: extra keys not allowed @ data['callback_type']. Got 'aggregate'
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.type: required key not provided @ data['type']. Got None
plugins/callback/print_task.py:0:0: missing-gplv3-license: GPLv3 license header not found in the first 20 lines of the module
```
<!-- job_id: 144619 -->
<!-- job_id: 5173a2236e1b6f6bdb2145f023c1bf96 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pep8` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pep8.html)] failed with 11 errors:
```
plugins/callback/print_task.py:22:1: E302: expected 2 blank lines, found 1
plugins/callback/print_task.py:33:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:35:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:38:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:38:62: W291: trailing whitespace
plugins/callback/print_task.py:39:49: W291: trailing whitespace
plugins/callback/print_task.py:41:1: W293: blank line contains whitespace
plugins/callback/print_task.py:42:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:43:7: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:46:8: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:50:11: E111: indentation is not a multiple of 4
```
<!-- job_id: 144619 -->
<!-- job_id: 9fa07a0c2a0b05b68b4d2d500bb4b983 -->
<!-- job_id: None -->

[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: shippable_test_result --->
author_association: COLLABORATOR
user: login: ansibullbot
created_at: 2025-05-02T15:03:09Z
body: The test `ansible-test sanity --test pep8` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pep8.html)] failed with 1 error:
```
plugins/callback/print_task.py:27:1: E302: expected 2 blank lines, found 1
```
<!-- job_id: 144772 -->
<!-- job_id: 564a033b74a986a2865ecf4cda717e13 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pep8` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pep8.html)] failed with 1 error:
```
plugins/callback/print_task.py:27:1: E302: expected 2 blank lines, found 1
```
<!-- job_id: 144772 -->
<!-- job_id: 564a033b74a986a2865ecf4cda717e13 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pep8` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pep8.html)] failed with 1 error:
```
plugins/callback/print_task.py:27:1: E302: expected 2 blank lines, found 1
```
<!-- job_id: 144772 -->
<!-- job_id: 564a033b74a986a2865ecf4cda717e13 -->
<!-- job_id: None -->
The test `ansible-test sanity --test validate-modules` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/validate-modules.html)] failed with 1 error:
```
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.author: Invalid author for dictionary value @ data['author']. Got ['Max Mitschke']
```
<!-- job_id: 144772 -->
<!-- job_id: 5af94bb014a1dd79c7e8d98ff9e4c833 -->
<!-- job_id: None -->
The test `ansible-test sanity --test validate-modules` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/validate-modules.html)] failed with 1 error:
```
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.author: Invalid author for dictionary value @ data['author']. Got ['Max Mitschke']
```
<!-- job_id: 144772 -->
<!-- job_id: 5af94bb014a1dd79c7e8d98ff9e4c833 -->
<!-- job_id: None -->
The test `ansible-test sanity --test validate-modules` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/validate-modules.html)] failed with 1 error:
```
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.author: Invalid author for dictionary value @ data['author']. Got ['Max Mitschke']
```
<!-- job_id: 144772 -->
<!-- job_id: 5af94bb014a1dd79c7e8d98ff9e4c833 -->
<!-- job_id: None -->
The test `ansible-test sanity --test validate-modules` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/validate-modules.html)] failed with 1 error:
```
plugins/callback/print_task.py:0:0: invalid-documentation: DOCUMENTATION.author: Invalid author for dictionary value @ data['author']. Got ['Max Mitschke']
```
<!-- job_id: 144772 -->
<!-- job_id: 5af94bb014a1dd79c7e8d98ff9e4c833 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pep8` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pep8.html)] failed with 1 error:
```
plugins/callback/print_task.py:27:1: E302: expected 2 blank lines, found 1
```
<!-- job_id: 144772 -->
<!-- job_id: 564a033b74a986a2865ecf4cda717e13 -->
<!-- job_id: None -->

[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: shippable_test_result --->
author_association: COLLABORATOR
user: login: demonpig
created_at: 2025-05-02T17:26:11Z
body: I'm not entirely sure how to work around the three tests that are failing. When I checked the outputs, they test playbooks are failing with the following. This is something that this callback plugin uses. 

```
07:15 [ERROR]: Task failed: Module failed: Cannot detect the required Python library cryptography (>= 3.4)
07:15 Origin: /root/ansible_collections/community/general/tests/output/.tmp/integration/java_cert-di_su1xq-ÅÑŚÌβŁÈ/tests/integration/targets/java_cert/tasks/state_change.yml:10:3
07:15 
07:15  8 #
07:15  9
07:15 10 - name: Create private keys
07:15      ^ column 3
07:15 
07:15 failed: [testhost] (item=/tmp/ansible.b0rnqgr_.test/key.pem) => {
07:15     "ansible_loop_var": "item",
07:15     "changed": false,
07:15     "invocation": {
07:15         "module_args": {
07:15             "attributes": null,
07:15             "backup": false,
07:15             "cipher": "auto",
07:15             "curve": null,
07:15             "force": false,
07:15             "format": "auto_ignore",
07:15             "format_mismatch": "regenerate",
07:15             "group": null,
07:15             "mode": "u=rw,go=",
07:15             "owner": null,
07:15             "passphrase": null,
07:15     },
07:15     "item": "/tmp/ansible.b0rnqgr_.test/key.pem",
07:15     "msg": "Cannot detect the required Python library cryptography (>= 3.4)"
07:15 }
```
author_association: CONTRIBUTOR
user: login: felixfontein
created_at: 2025-05-02T17:30:55Z
body: The Debian Bullseye tests failures are unrelated to this PR, please simply ignore them for now.
author_association: COLLABORATOR
user: login: ansibullbot
created_at: 2025-05-03T03:24:22Z
body: The test `ansible-test sanity --test pep8` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pep8.html)] failed with 4 errors:
```
plugins/callback/print_task.py:43:11: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:44:11: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:45:11: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:46:11: E111: indentation is not a multiple of 4
```
<!-- job_id: 144806 -->
<!-- job_id: f844195bd58c82415395b3fa59d749a7 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pep8` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pep8.html)] failed with 4 errors:
```
plugins/callback/print_task.py:43:11: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:44:11: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:45:11: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:46:11: E111: indentation is not a multiple of 4
```
<!-- job_id: 144806 -->
<!-- job_id: f844195bd58c82415395b3fa59d749a7 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pep8` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pep8.html)] failed with 4 errors:
```
plugins/callback/print_task.py:43:11: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:44:11: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:45:11: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:46:11: E111: indentation is not a multiple of 4
```
<!-- job_id: 144806 -->
<!-- job_id: f844195bd58c82415395b3fa59d749a7 -->
<!-- job_id: None -->
The test `ansible-test sanity --test pep8` [[explain](https://docs.ansible.com/ansible-core/devel/dev_guide/testing/sanity/pep8.html)] failed with 4 errors:
```
plugins/callback/print_task.py:43:11: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:44:11: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:45:11: E111: indentation is not a multiple of 4
plugins/callback/print_task.py:46:11: E111: indentation is not a multiple of 4
```
<!-- job_id: 144806 -->
<!-- job_id: f844195bd58c82415395b3fa59d749a7 -->
<!-- job_id: None -->

[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: shippable_test_result --->
author_association: COLLABORATOR
user: login: demonpig
created_at: 2025-05-05T19:45:29Z
body: I'll work on some tests later tonight.
author_association: CONTRIBUTOR
user: login: russoz
created_at: 2025-05-10T10:32:11Z
body: Hi @demonpig pardon me for being a bit of a contrarian here, but how is this better than `ansible-playbook -vvv`? Or `-vvvv`? It already shows the module arguments. Personally, in my plabooks, I would not want to be changing the callback configs for a debug, just increasing the verbosity would do the trick for me. YMMV
author_association: COLLABORATOR
user: login: felixfontein
created_at: 2025-05-15T05:25:52Z
body: > Hi @demonpig pardon me for being a bit of a contrarian here, but how is this better than `ansible-playbook -vvv`? Or `-vvvv`?

It shows the arguments after being passed through the module, but you don't really see the raw task information (which also happens to be untemplated).
author_association: COLLABORATOR
user: login: demonpig
created_at: 2025-05-16T13:28:38Z
body: @russoz I understand your points. I view this as an addition to `-vvvv` where you can get a print out of the task and the arguments passed to it. Part of the reason behind this was a need to debug playbooks within AWX / Ansible Automation Platform without having to look at the source code.
author_association: CONTRIBUTOR
user: login: felixfontein
created_at: 2025-05-17T06:01:14Z
body: If nobody objects, I'll merge this for 10.7.0.
author_association: COLLABORATOR
user: login: patchback[bot]
created_at: 2025-05-18T20:40:05Z
body: 
### Backport to stable-10: 💚 backport PR created

✅ Backport PR branch: `patchback/backports/stable-10/b861850e1a9495a1227a15b894b531409b4384e5/pr-10087`

Backported as https://github.com/ansible-collections/community.general/pull/10159



<sub><sup>
--
🤖 @patchback
I'm built with [octomachinery](https://octomachinery.dev) and
my source is open — https://github.com/sanitizers/patchback-github-app.
</sup></sub>


author_association: NONE
user: login: felixfontein
created_at: 2025-05-18T20:41:15Z
body: @demonpig thanks for your contribution!
@Akasurde @bcoca @russoz thanks for reviewing and commenting!
author_association: COLLABORATOR