From 81d883687e4f03f9b16e549a919dfd51f084d647 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Wed, 29 Oct 2025 19:01:40 +0100 Subject: [PATCH] Make sure ansible-doc doesn't crash when scanning collections whose path contains ansible_collections twice (#85361) (#85930) Ref: https://github.com/ansible/ansible/issues/84909#issuecomment-2767335761 (cherry picked from commit c6d8d206af59a8e7f145017f4aa82e286b81ca24) Co-authored-by: s-hertel <19572925+s-hertel@users.noreply.github.com> Co-authored-by: Brian Coca --- .../fragments/85361-collection-name-from-path-none.yml | 3 +++ lib/ansible/cli/doc.py | 4 +++- lib/ansible/collections/list.py | 6 ++++-- .../ansible_collections/ns/col/plugins/modules/test.py | 0 test/integration/targets/ansible-doc/runme.sh | 7 +++++++ 5 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/85361-collection-name-from-path-none.yml create mode 100644 test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/playbooks/collections/ansible_collections/ns/col/plugins/modules/test.py diff --git a/changelogs/fragments/85361-collection-name-from-path-none.yml b/changelogs/fragments/85361-collection-name-from-path-none.yml new file mode 100644 index 00000000000..4acbbe8af1a --- /dev/null +++ b/changelogs/fragments/85361-collection-name-from-path-none.yml @@ -0,0 +1,3 @@ +bugfixes: + - "ansible-doc - prevent crash when scanning collections in paths that have more than one ``ansible_collections`` in it + (https://github.com/ansible/ansible/issues/84909, https://github.com/ansible/ansible/pull/85361)." diff --git a/lib/ansible/cli/doc.py b/lib/ansible/cli/doc.py index 0319e51d09e..1f33fe17496 100755 --- a/lib/ansible/cli/doc.py +++ b/lib/ansible/cli/doc.py @@ -237,7 +237,9 @@ class RoleMixin(object): b_colldirs = list_collection_dirs(coll_filter=collection_filter) for b_path in b_colldirs: path = to_text(b_path, errors='surrogate_or_strict') - collname = _get_collection_name_from_path(b_path) + if not (collname := _get_collection_name_from_path(b_path)): + display.debug(f'Skipping invalid path {b_path!r}') + continue roles_dir = os.path.join(path, 'roles') if os.path.exists(roles_dir): diff --git a/lib/ansible/collections/list.py b/lib/ansible/collections/list.py index 473c56d0945..1c8fdae9508 100644 --- a/lib/ansible/collections/list.py +++ b/lib/ansible/collections/list.py @@ -17,8 +17,10 @@ def list_collections(coll_filter=None, search_paths=None, dedupe=True, artifacts collections = {} for candidate in list_collection_dirs(search_paths=search_paths, coll_filter=coll_filter, artifacts_manager=artifacts_manager, dedupe=dedupe): - collection = _get_collection_name_from_path(candidate) - collections[collection] = candidate + if collection := _get_collection_name_from_path(candidate): + collections[collection] = candidate + else: + display.debug(f'Skipping invalid collection in path: {candidate!r}') return collections diff --git a/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/playbooks/collections/ansible_collections/ns/col/plugins/modules/test.py b/test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/playbooks/collections/ansible_collections/ns/col/plugins/modules/test.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/integration/targets/ansible-doc/runme.sh b/test/integration/targets/ansible-doc/runme.sh index 504f6afba7b..697f07e5494 100755 --- a/test/integration/targets/ansible-doc/runme.sh +++ b/test/integration/targets/ansible-doc/runme.sh @@ -211,6 +211,13 @@ ANSIBLE_LIBRARY='./nolibrary' ansible-doc --metadata-dump --no-fail-on-errors -- output=$(ANSIBLE_LIBRARY='./nolibrary' ansible-doc --metadata-dump --playbook-dir broken-docs testns.testcol 2>&1 | grep -c 'ERROR' || true) test "${output}" -eq 1 +# ensure --metadata-dump does not crash if the ansible_collections is nested (https://github.com/ansible/ansible/issues/84909) +testdir="$(pwd)" +pbdir="collections/ansible_collections/testns/testcol/playbooks" +cd "$pbdir" +ANSIBLE_COLLECTIONS_PATH="$testdir/$pbdir/collections" ansible-doc -vvv --metadata-dump --no-fail-on-errors +cd "$testdir" + echo "test doc list on broken role metadata" # ensure that role doc does not fail when --no-fail-on-errors is supplied ANSIBLE_LIBRARY='./nolibrary' ansible-doc --no-fail-on-errors --playbook-dir broken-docs testns.testcol.testrole -t role 1>/dev/null 2>&1