galaxy - add format options for collection list (#73474)
* Include all collections in single json object / yaml document * Add tests * For galaxy list yaml/json output, use dictionary of dictionaries instead of list * Add tests for listing single collection in yaml / output format * --output -> --format * Add explicit test for listing collection in human format * Fix bug where empty json object was emitted + add test
This commit is contained in:
parent
d3f3784b86
commit
67f5bb39c7
4 changed files with 105 additions and 0 deletions
|
@ -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)
|
|
@ -5,6 +5,7 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import json
|
||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
|
@ -301,6 +302,10 @@ class GalaxyCLI(CLI):
|
||||||
|
|
||||||
list_parser.add_argument(galaxy_type, help=galaxy_type.capitalize(), nargs='?', metavar=galaxy_type)
|
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',
|
||||||
|
help="Format to display the list of collections in.")
|
||||||
|
|
||||||
def add_search_options(self, parser, parents=None):
|
def add_search_options(self, parser, parents=None):
|
||||||
search_parser = parser.add_parser('search', parents=parents,
|
search_parser = parser.add_parser('search', parents=parents,
|
||||||
help='Search the Galaxy database by tags, platforms, author and multiple '
|
help='Search the Galaxy database by tags, platforms, author and multiple '
|
||||||
|
@ -1379,9 +1384,11 @@ class GalaxyCLI(CLI):
|
||||||
:param artifacts_manager: Artifacts manager.
|
:param artifacts_manager: Artifacts manager.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
output_format = context.CLIARGS['output_format']
|
||||||
collections_search_paths = set(context.CLIARGS['collections_path'])
|
collections_search_paths = set(context.CLIARGS['collections_path'])
|
||||||
collection_name = context.CLIARGS['collection']
|
collection_name = context.CLIARGS['collection']
|
||||||
default_collections_path = AnsibleCollectionConfig.collection_paths
|
default_collections_path = AnsibleCollectionConfig.collection_paths
|
||||||
|
collections_in_paths = {}
|
||||||
|
|
||||||
warnings = []
|
warnings = []
|
||||||
path_found = False
|
path_found = False
|
||||||
|
@ -1428,6 +1435,13 @@ class GalaxyCLI(CLI):
|
||||||
except ValueError as val_err:
|
except ValueError as val_err:
|
||||||
six.raise_from(AnsibleError(val_err), 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
|
||||||
|
|
||||||
fqcn_width, version_width = _get_collection_widths([collection])
|
fqcn_width, version_width = _get_collection_widths([collection])
|
||||||
|
|
||||||
_display_header(collection_path, 'Collection', 'Version', fqcn_width, version_width)
|
_display_header(collection_path, 'Collection', 'Version', fqcn_width, version_width)
|
||||||
|
@ -1451,6 +1465,13 @@ class GalaxyCLI(CLI):
|
||||||
display.vvv("No collections found at {0}".format(collection_path))
|
display.vvv("No collections found at {0}".format(collection_path))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if output_format in {'yaml', 'json'}:
|
||||||
|
collections_in_paths[collection_path] = {
|
||||||
|
collection.fqcn: {'version': collection.ver} for collection in collections
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
# Display header
|
# Display header
|
||||||
fqcn_width, version_width = _get_collection_widths(collections)
|
fqcn_width, version_width = _get_collection_widths(collections)
|
||||||
_display_header(collection_path, 'Collection', 'Version', fqcn_width, version_width)
|
_display_header(collection_path, 'Collection', 'Version', fqcn_width, version_width)
|
||||||
|
@ -1469,6 +1490,11 @@ class GalaxyCLI(CLI):
|
||||||
if not path_found:
|
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']))
|
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))
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def execute_publish(self):
|
def execute_publish(self):
|
||||||
|
|
|
@ -31,6 +31,82 @@
|
||||||
- "'dev.collection2 placeholder' in list_result.stdout"
|
- "'dev.collection2 placeholder' in list_result.stdout"
|
||||||
- "'dev.collection3 *' 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
|
- 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"
|
command: ansible-galaxy collection install namespace1.name1 -s galaxy_ng {{ galaxy_verbosity }} -p "{{ galaxy_dir }}/prod"
|
||||||
environment:
|
environment:
|
||||||
|
|
|
@ -41,6 +41,7 @@ def cliargs(collections_paths=None, collection_name=None):
|
||||||
'collections_path': collections_paths,
|
'collections_path': collections_paths,
|
||||||
'collection': collection_name,
|
'collection': collection_name,
|
||||||
'type': 'collection',
|
'type': 'collection',
|
||||||
|
'output_format': 'human'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue