summaryrefslogtreecommitdiff
path: root/lib/ansible/plugins/callback/junit.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ansible/plugins/callback/junit.py')
-rw-r--r--lib/ansible/plugins/callback/junit.py18
1 files changed, 16 insertions, 2 deletions
diff --git a/lib/ansible/plugins/callback/junit.py b/lib/ansible/plugins/callback/junit.py
index 2fe402ea2f..838f491def 100644
--- a/lib/ansible/plugins/callback/junit.py
+++ b/lib/ansible/plugins/callback/junit.py
@@ -40,6 +40,13 @@ DOCUMENTATION = '''
version_added: "2.8"
env:
- name: JUNIT_TASK_RELATIVE_PATH
+ replace_out_of_tree_path:
+ name: Replace out of tree path
+ default: none
+ description: Replace the directory portion of an out-of-tree relative task path with the given placeholder
+ version_added: "2.12.3"
+ env:
+ - name: JUNIT_REPLACE_OUT_OF_TREE_PATH
fail_on_change:
name: JUnit fail on change
default: False
@@ -155,6 +162,7 @@ class CallbackModule(CallbackBase):
self._include_setup_tasks_in_report = os.getenv('JUNIT_INCLUDE_SETUP_TASKS_IN_REPORT', 'True').lower()
self._hide_task_arguments = os.getenv('JUNIT_HIDE_TASK_ARGUMENTS', 'False').lower()
self._test_case_prefix = os.getenv('JUNIT_TEST_CASE_PREFIX', '')
+ self._replace_out_of_tree_path = os.getenv('JUNIT_REPLACE_OUT_OF_TREE_PATH', None)
self._playbook_path = None
self._playbook_name = None
self._play_name = None
@@ -174,6 +182,9 @@ class CallbackModule(CallbackBase):
self._display.warning('The `ordereddict` python module is not installed. '
'Disabling the `junit` callback plugin.')
+ if self._replace_out_of_tree_path is not None:
+ self._replace_out_of_tree_path = to_text(self._replace_out_of_tree_path)
+
if not os.path.exists(self._output_dir):
os.makedirs(self._output_dir)
@@ -232,11 +243,14 @@ class CallbackModule(CallbackBase):
name = '[%s] %s: %s' % (host_data.name, task_data.play, task_data.name)
duration = host_data.finish - task_data.start
- if self._task_relative_path:
- junit_classname = os.path.relpath(task_data.path, self._task_relative_path)
+ if self._task_relative_path and task_data.path:
+ junit_classname = to_text(os.path.relpath(to_bytes(task_data.path), to_bytes(self._task_relative_path)))
else:
junit_classname = task_data.path
+ if self._replace_out_of_tree_path is not None and junit_classname.startswith('../'):
+ junit_classname = self._replace_out_of_tree_path + to_text(os.path.basename(to_bytes(junit_classname)))
+
if self._task_class == 'true':
junit_classname = re.sub(r'\.yml:[0-9]+$', '', junit_classname)