Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add format options for ansible-galaxy collection list #73474

Merged
merged 16 commits into from Feb 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/73474-galaxy-list-format-options.yml
@@ -0,0 +1,2 @@
minor_changes:
- Add ``--format`` CLI option to ``ansible-galaxy collection list`` which allows for ``human`` (default), ``yaml``, or ``json``. (https://github.com/ansible/ansible/pull/73474)
26 changes: 26 additions & 0 deletions lib/ansible/cli/galaxy.py
Expand Up @@ -5,6 +5,7 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

import json
import os.path
import re
import shutil
Expand Down Expand Up @@ -301,6 +302,10 @@ def add_list_options(self, parser, parents=None):

list_parser.add_argument(galaxy_type, help=galaxy_type.capitalize(), nargs='?', metavar=galaxy_type)

if galaxy_type == 'collection':
list_parser.add_argument('--format', dest='output_format', choices=('human', 'yaml', 'json'), default='human',
shanemcd marked this conversation as resolved.
Show resolved Hide resolved
help="Format to display the list of collections in.")

def add_search_options(self, parser, parents=None):
search_parser = parser.add_parser('search', parents=parents,
help='Search the Galaxy database by tags, platforms, author and multiple '
Expand Down Expand Up @@ -1379,9 +1384,11 @@ def execute_list_collection(self, artifacts_manager=None):
:param artifacts_manager: Artifacts manager.
"""

output_format = context.CLIARGS['output_format']
collections_search_paths = set(context.CLIARGS['collections_path'])
collection_name = context.CLIARGS['collection']
default_collections_path = AnsibleCollectionConfig.collection_paths
collections_in_paths = {}

warnings = []
path_found = False
Expand Down Expand Up @@ -1428,6 +1435,13 @@ def execute_list_collection(self, artifacts_manager=None):
except ValueError as val_err:
six.raise_from(AnsibleError(val_err), val_err)

if output_format in {'yaml', 'json'}:
collections_in_paths[collection_path] = {
collection.fqcn: {'version': collection.ver}
}

continue
webknjaz marked this conversation as resolved.
Show resolved Hide resolved

fqcn_width, version_width = _get_collection_widths([collection])

_display_header(collection_path, 'Collection', 'Version', fqcn_width, version_width)
Expand All @@ -1451,6 +1465,13 @@ def execute_list_collection(self, artifacts_manager=None):
display.vvv("No collections found at {0}".format(collection_path))
continue

if output_format in {'yaml', 'json'}:
collections_in_paths[collection_path] = {
collection.fqcn: {'version': collection.ver} for collection in collections
}

continue

# Display header
fqcn_width, version_width = _get_collection_widths(collections)
_display_header(collection_path, 'Collection', 'Version', fqcn_width, version_width)
Expand All @@ -1469,6 +1490,11 @@ def execute_list_collection(self, artifacts_manager=None):
if not path_found:
raise AnsibleOptionsError("- None of the provided paths were usable. Please specify a valid path with --{0}s-path".format(context.CLIARGS['type']))

if output_format == 'json':
display.display(json.dumps(collections_in_paths))
elif output_format == 'yaml':
display.display(yaml.safe_dump(collections_in_paths))

shanemcd marked this conversation as resolved.
Show resolved Hide resolved
return 0

def execute_publish(self):
Expand Down
76 changes: 76 additions & 0 deletions test/integration/targets/ansible-galaxy-collection/tasks/list.yml
Expand Up @@ -31,6 +31,82 @@
- "'dev.collection2 placeholder' in list_result.stdout"
- "'dev.collection3 *' in list_result.stdout"

- name: list collections in human format
command: ansible-galaxy collection list --format human
register: list_result_human
environment:
ANSIBLE_COLLECTIONS_PATH: "{{ galaxy_dir }}/dev:{{ galaxy_dir }}/prod"

- assert:
that:
- "'dev.collection1 *' in list_result_human.stdout"
# Note the version displayed is the 'placeholder' string rather than "*" since it is not falsey
- "'dev.collection2 placeholder' in list_result_human.stdout"
- "'dev.collection3 *' in list_result_human.stdout"

- name: list collections in yaml format
command: ansible-galaxy collection list --format yaml
register: list_result_yaml
environment:
ANSIBLE_COLLECTIONS_PATH: "{{ galaxy_dir }}/dev:{{ galaxy_dir }}/prod"

- assert:
that:
- "item.value | length == 3"
- "item.value['dev.collection1'].version == '*'"
- "item.value['dev.collection2'].version == 'placeholder'"
- "item.value['dev.collection3'].version == '*'"
with_dict: "{{ list_result_yaml.stdout | from_yaml }}"

- name: list collections in json format
command: ansible-galaxy collection list --format json
register: list_result_json
environment:
ANSIBLE_COLLECTIONS_PATH: "{{ galaxy_dir }}/dev:{{ galaxy_dir }}/prod"

- assert:
that:
- "item.value | length == 3"
- "item.value['dev.collection1'].version == '*'"
- "item.value['dev.collection2'].version == 'placeholder'"
- "item.value['dev.collection3'].version == '*'"
with_dict: "{{ list_result_json.stdout | from_json }}"

- name: list single collection in json format
command: "ansible-galaxy collection list {{ item.key }} --format json"
register: list_single_result_json
environment:
ANSIBLE_COLLECTIONS_PATH: "{{ galaxy_dir }}/dev:{{ galaxy_dir }}/prod"
with_dict: "{{ { 'dev.collection1': '*', 'dev.collection2': 'placeholder', 'dev.collection3': '*' } }}"

- assert:
that:
- "(item.stdout | from_json)[galaxy_dir + '/dev/ansible_collections'][item.item.key].version == item.item.value"
with_items: "{{ list_single_result_json.results }}"

- name: list single collection in yaml format
command: "ansible-galaxy collection list {{ item.key }} --format yaml"
register: list_single_result_yaml
environment:
ANSIBLE_COLLECTIONS_PATH: "{{ galaxy_dir }}/dev:{{ galaxy_dir }}/prod"
with_dict: "{{ { 'dev.collection1': '*', 'dev.collection2': 'placeholder', 'dev.collection3': '*' } }}"

- assert:
that:
- "(item.stdout | from_yaml)[galaxy_dir + '/dev/ansible_collections'][item.item.key].version == item.item.value"
with_items: "{{ list_single_result_json.results }}"

- name: test that no json is emitted when no collection paths are usable
command: "ansible-galaxy collection list --format json"
register: list_result_error
ignore_errors: True
environment:
ANSIBLE_COLLECTIONS_PATH: ""

- assert:
that:
- "'{}' not in list_result_error.stdout"

- name: install an artifact to the second collections path
command: ansible-galaxy collection install namespace1.name1 -s galaxy_ng {{ galaxy_verbosity }} -p "{{ galaxy_dir }}/prod"
environment:
Expand Down
1 change: 1 addition & 0 deletions test/units/cli/galaxy/test_execute_list_collection.py
Expand Up @@ -41,6 +41,7 @@ def cliargs(collections_paths=None, collection_name=None):
'collections_path': collections_paths,
'collection': collection_name,
'type': 'collection',
'output_format': 'human'
}


Expand Down