Sloane Hertel 2 weeks ago committed by GitHub
commit 459e96f52f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,3 @@
minor_changes:
- >-
``ansible-galaxy collection list`` - display the preferred collection when a FQCN is installed to multiple collection paths.

@ -121,16 +121,18 @@ def with_collection_artifacts_manager(wrapped_method):
return method_wrapper
def _display_header(path, h1, h2, w1=10, w2=7):
display.display('\n# {0}\n{1:{cwidth}} {2:{vwidth}}\n{3} {4}\n'.format(
path,
h1,
h2,
'-' * max([len(h1), w1]), # Make sure that the number of dashes is at least the width of the header
'-' * max([len(h2), w2]),
cwidth=w1,
vwidth=w2,
))
def _display_header(path, h1, h2, w1=10, w2=7, h3=''):
optional_column = ' ' if h3 else ''
w3 = len(h3)
# Make sure that the number of dashes is at least the width of the header
h1_sep = '-' * max([len(h1), w1])
h2_sep = '-' * max([len(h2), w2])
h3_sep = '-' * max([len(h3), w3])
display.display(
f"\n# {path}\n{h1:{w1}} {h2:{w2}}{optional_column}{h3}\n{h1_sep} {h2_sep}{optional_column}{h3_sep}\n"
)
def _display_role(gr):
@ -143,12 +145,15 @@ def _display_role(gr):
display.display("- %s, %s" % (gr.name, version))
def _display_collection(collection, cwidth=10, vwidth=7, min_cwidth=10, min_vwidth=7):
display.display('{fqcn:{cwidth}} {version:{vwidth}}'.format(
def _display_collection(collection, cwidth=10, vwidth=7, min_cwidth=10, min_vwidth=7, pwidth=0, preferred=False):
display.display('{fqcn:{cwidth}} {version:{vwidth}}{optional_column}{preference_marker:{pwidth}}'.format(
fqcn=to_text(collection.fqcn),
version=collection.ver,
cwidth=max(cwidth, min_cwidth), # Make sure the width isn't smaller than the header
vwidth=max(vwidth, min_vwidth)
vwidth=max(vwidth, min_vwidth),
pwidth=pwidth,
optional_column=' ' if pwidth != 0 else '',
preference_marker='*' if preferred else ''
))
@ -1673,23 +1678,30 @@ class GalaxyCLI(CLI):
validate_collection_name(collection_name)
namespace_filter, collection_filter = collection_name.split('.')
collections = list(find_existing_collections(
collections = []
fqcn_precedence = {}
for collection in find_existing_collections(
list(collections_search_paths),
artifacts_manager,
namespace_filter=namespace_filter,
collection_filter=collection_filter,
dedupe=False
))
):
collections.append(collection)
fqcn_precedence.setdefault(collection.fqcn, []).append(collection.src)
seen = set()
fqcn_width, version_width = _get_collection_widths(collections)
preferred_header = 'Preferred' if any(len(matches) > 1 for matches in fqcn_precedence.values()) else ''
for collection in sorted(collections, key=lambda c: c.src):
collection_found = True
collection_path = pathlib.Path(to_text(collection.src)).parent.parent.as_posix()
preferred = preferred_header and fqcn_precedence[collection.fqcn].index(collection.src) == 0
if output_format in {'yaml', 'json'}:
collections_in_paths.setdefault(collection_path, {})
collections_in_paths[collection_path][collection.fqcn] = {'version': collection.ver}
collections_in_paths[collection_path][collection.fqcn] = {'version': collection.ver, 'preferred': preferred}
else:
if collection_path not in seen:
_display_header(
@ -1697,10 +1709,11 @@ class GalaxyCLI(CLI):
'Collection',
'Version',
fqcn_width,
version_width
version_width,
h3=preferred_header,
)
seen.add(collection_path)
_display_collection(collection, fqcn_width, version_width)
_display_collection(collection, fqcn_width, version_width, pwidth=len(preferred_header), preferred=preferred)
path_found = False
for path in collections_search_paths:

@ -1443,7 +1443,7 @@ def find_existing_collections(path_filter, artifacts_manager, namespace_filter=N
if collection_filter and not is_sequence(collection_filter):
collection_filter = [collection_filter]
paths = set()
paths = []
for path in files('ansible_collections').glob('*/*/'):
path = _normalize_collection_path(path)
if not path.is_dir():
@ -1457,7 +1457,7 @@ def find_existing_collections(path_filter, artifacts_manager, namespace_filter=N
break
else:
continue
paths.add(path)
paths.append(path)
seen = set()
for path in paths:

@ -180,3 +180,36 @@
that:
- list_result is failed
- "'is expected to have a valid SemVer version value but got None' in list_result.stderr"
- name: Initialize the same FQCN in two collection paths
command: ansible-galaxy collection init {{ item.fqcn }} --init-path "{{ galaxy_dir }}/{{ item.path }}/ansible_collections" {{ galaxy_verbosity }}
loop:
- fqcn: common.collection1
path: dev
- fqcn: common.collection1
path: prod
- name: Update version in one of the paths
lineinfile:
path: "{{ galaxy_dir }}/prod/ansible_collections/common/collection1/galaxy.yml"
line: "version: 2.0.0"
regexp: "version: .*"
- name: Test listing collection in multiple paths
command: ansible-galaxy collection list common.collection1
register: list_common_1
environment:
ANSIBLE_COLLECTIONS_PATH: "{{ galaxy_dir }}/dev:{{ galaxy_dir }}/prod"
- name: Test listing collection in multiple paths with -p
command: ansible-galaxy collection list common.collection1 -p {{ galaxy_dir }}/prod
register: list_common_2
environment:
ANSIBLE_COLLECTIONS_PATH: "{{ galaxy_dir }}/dev"
- assert:
that:
- '"common.collection1 1.0.0 * " in list_common_1.stdout_lines'
- '"common.collection1 2.0.0 " in list_common_1.stdout_lines'
- '"common.collection1 1.0.0 " in list_common_2.stdout_lines'
- '"common.collection1 2.0.0 * " in list_common_2.stdout_lines'

@ -103,16 +103,16 @@ def test_execute_list_collection_all(mocker, capsys, mock_from_path, tmp_path_fa
assert len(out_lines) == 12
assert out_lines[0] == ''
assert out_lines[1] == '# /root/.ansible/collections/ansible_collections'
assert out_lines[2] == 'Collection Version'
assert out_lines[3] == '----------------- -------'
assert out_lines[4] == 'sandwiches.pbj 1.5.0 '
assert out_lines[5] == 'sandwiches.reuben 2.5.0 '
assert out_lines[2] == 'Collection Version Preferred'
assert out_lines[3] == '----------------- ------- ---------'
assert out_lines[4] == 'sandwiches.pbj 1.5.0 '
assert out_lines[5] == 'sandwiches.reuben 2.5.0 * '
assert out_lines[6] == ''
assert out_lines[7] == '# /usr/share/ansible/collections/ansible_collections'
assert out_lines[8] == 'Collection Version'
assert out_lines[9] == '----------------- -------'
assert out_lines[10] == 'sandwiches.ham 1.0.0 '
assert out_lines[11] == 'sandwiches.pbj 1.0.0 '
assert out_lines[8] == 'Collection Version Preferred'
assert out_lines[9] == '----------------- ------- ---------'
assert out_lines[10] == 'sandwiches.ham 1.0.0 * '
assert out_lines[11] == 'sandwiches.pbj 1.0.0 * '
def test_execute_list_collection_specific(mocker, capsys, mock_from_path, tmp_path_factory):
@ -163,14 +163,14 @@ def test_execute_list_collection_specific_duplicate(mocker, capsys, mock_from_pa
assert len(out_lines) == 10
assert out_lines[0] == ''
assert out_lines[1] == '# /root/.ansible/collections/ansible_collections'
assert out_lines[2] == 'Collection Version'
assert out_lines[3] == '-------------- -------'
assert out_lines[4] == 'sandwiches.pbj 1.5.0 '
assert out_lines[2] == 'Collection Version Preferred'
assert out_lines[3] == '-------------- ------- ---------'
assert out_lines[4] == 'sandwiches.pbj 1.5.0 '
assert out_lines[5] == ''
assert out_lines[6] == '# /usr/share/ansible/collections/ansible_collections'
assert out_lines[7] == 'Collection Version'
assert out_lines[8] == '-------------- -------'
assert out_lines[9] == 'sandwiches.pbj 1.0.0 '
assert out_lines[7] == 'Collection Version Preferred'
assert out_lines[8] == '-------------- ------- ---------'
assert out_lines[9] == 'sandwiches.pbj 1.0.0 * '
def test_execute_list_collection_specific_invalid_fqcn(mocker, tmp_path_factory):
@ -235,9 +235,9 @@ def test_execute_list_collection_one_invalid_path(mocker, capsys, mock_from_path
assert out_lines[0] == ''
assert out_lines[1] == '# /root/.ansible/collections/ansible_collections'
assert out_lines[2] == 'Collection Version'
assert out_lines[3] == '----------------- -------'
assert out_lines[4] == 'sandwiches.pbj 1.5.0 '
assert out_lines[2] == 'Collection Version Preferred'
assert out_lines[3] == '----------------- ------- ---------'
assert out_lines[4] == 'sandwiches.pbj 1.5.0 '
# Only a partial test of the output
assert err == '[WARNING]: - the configured path nope, exists, but it is not a directory.\n'

Loading…
Cancel
Save