This commit is contained in:
Sloane Hertel 2026-05-27 22:08:40 -05:00 committed by GitHub
commit 4f08e9378e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 80 additions and 6 deletions

View file

@ -0,0 +1,3 @@
minor_changes:
- >-
``ansible-galaxy collection list`` - add ``--deduplicate`` toggle to see only the first of each FQCN using the configured path order.

View file

@ -388,6 +388,8 @@ class GalaxyCLI(CLI):
if galaxy_type == 'collection':
list_parser.add_argument('--format', dest='output_format', choices=('human', 'yaml', 'json'), default='human',
help="Format to display the list of collections in.")
list_parser.add_argument('--deduplicate', dest='deduplicate', action='store_true',
help='List only the first of each FQCN using the configured path order.')
def add_search_options(self, parser, parents=None):
search_parser = parser.add_parser('search', parents=parents,
@ -1640,11 +1642,14 @@ class GalaxyCLI(CLI):
artifacts_manager.require_build_metadata = False
output_format = context.CLIARGS['output_format']
deduplicate_fqcn = context.CLIARGS['deduplicate']
collection_name = context.CLIARGS['collection']
default_collections_path = set(C.COLLECTIONS_PATHS)
collections_search_paths = (
set(context.CLIARGS['collections_path'] or []) | default_collections_path | set(self.collection_paths)
ordered_search_paths = (
list(context.CLIARGS['collections_path'] or [])
+ C.COLLECTIONS_PATHS
+ self.collection_paths
)
collections_search_paths = set(ordered_search_paths)
collections_in_paths = {}
warnings = []
@ -1667,9 +1672,22 @@ class GalaxyCLI(CLI):
dedupe=False
))
def configuration_order(collection):
src = pathlib.Path(to_text(collection.src))
for path in ordered_search_paths:
if src.is_relative_to(path):
return (ordered_search_paths.index(path), collection.src)
return (float("inf"), collection.src)
seen = set()
seen_fqcn = set()
fqcn_width, version_width = _get_collection_widths(collections)
for collection in sorted(collections, key=lambda c: c.src):
for collection in sorted(collections, key=configuration_order):
if deduplicate_fqcn:
if collection.fqcn in seen_fqcn:
continue
seen_fqcn.add(collection.fqcn)
collection_found = True
collection_path = pathlib.Path(to_text(collection.src)).parent.parent.as_posix()
@ -1691,7 +1709,7 @@ class GalaxyCLI(CLI):
path_found = False
for path in collections_search_paths:
if not os.path.exists(path):
if path in default_collections_path:
if path in C.COLLECTIONS_PATHS:
# don't warn for missing default paths
continue
warnings.append("- the configured path {0} does not exist.".format(path))

View file

@ -241,3 +241,55 @@
that:
- list_result is failed
- "'is expected to have a valid SemVer version value but got None' in list_result.stderr"
- name: Test showing the first FQCN in the configured paths
vars:
dev: "{{ galaxy_dir }}/dev/ansible_collections"
prod: "{{ galaxy_dir }}/prod/ansible_collections"
test_paths:
- "{{ dev }}"
- "{{ prod }}"
block:
- name: Remove collection paths
file:
path: "{{ item }}"
state: absent
loop: "{{ test_paths }}"
- name: Initialize collection paths
file:
path: "{{ item }}"
state: directory
loop: "{{ test_paths }}"
- name: Initialize a collection in two paths
command: ansible-galaxy collection init common.collection --init-path {{ item }}
loop: "{{ test_paths }}"
- name: List deduplicated collection by name
command: ansible-galaxy collection list common.collection --deduplicate --format yaml
register: first_by_name
environment:
ANSIBLE_COLLECTIONS_PATH: "{{ test_paths | join(':') }}"
- name: Reverse the search order and list all deduplicated collections
command: ansible-galaxy collection list --deduplicate --format yaml
register: first_all
environment:
ANSIBLE_COLLECTIONS_PATH: "{{ test_paths | reverse | join(':') }}"
- name: List deduplicated collections with -p
command: ansible-galaxy collection list -p {{ test_paths | first }} --deduplicate --format yaml
register: first_override
environment:
ANSIBLE_COLLECTIONS_PATH: "{{ test_paths | last }}"
- assert:
that:
- 'first_by_name.stdout | from_yaml == {dev: found}'
- 'first_all.stdout | from_yaml == {prod: found}'
- 'first_override.stdout | from_yaml == {dev: found}'
vars:
found:
common.collection:
version: 1.0.0

View file

@ -33,7 +33,8 @@ def cliargs(collections_paths=None, collection_name=None):
'collections_path': collections_paths,
'collection': collection_name,
'type': 'collection',
'output_format': 'human'
'output_format': 'human',
'deduplicate': False,
}