diff options
Diffstat (limited to 'lib/ansible/collections')
-rw-r--r-- | lib/ansible/collections/__init__.py | 29 | ||||
-rw-r--r-- | lib/ansible/collections/list.py | 124 |
2 files changed, 36 insertions, 117 deletions
diff --git a/lib/ansible/collections/__init__.py b/lib/ansible/collections/__init__.py index 6b3e2a7..e69de29 100644 --- a/lib/ansible/collections/__init__.py +++ b/lib/ansible/collections/__init__.py @@ -1,29 +0,0 @@ -# (c) 2019 Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import os - -from ansible.module_utils._text import to_bytes - -B_FLAG_FILES = frozenset([b'MANIFEST.json', b'galaxy.yml']) - - -def is_collection_path(path): - """ - Verify that a path meets min requirements to be a collection - :param path: byte-string path to evaluate for collection containment - :return: boolean signifying 'collectionness' - """ - - is_coll = False - b_path = to_bytes(path) - if os.path.isdir(b_path): - for b_flag in B_FLAG_FILES: - if os.path.exists(os.path.join(b_path, b_flag)): - is_coll = True - break - - return is_coll diff --git a/lib/ansible/collections/list.py b/lib/ansible/collections/list.py index af3c1ca..ef858ae 100644 --- a/lib/ansible/collections/list.py +++ b/lib/ansible/collections/list.py @@ -1,65 +1,28 @@ # (c) 2019 Ansible Project # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import os - -from collections import defaultdict - from ansible.errors import AnsibleError -from ansible.collections import is_collection_path -from ansible.module_utils._text import to_bytes -from ansible.utils.collection_loader import AnsibleCollectionConfig +from ansible.cli.galaxy import with_collection_artifacts_manager +from ansible.galaxy.collection import find_existing_collections +from ansible.module_utils.common.text.converters import to_bytes from ansible.utils.collection_loader._collection_finder import _get_collection_name_from_path from ansible.utils.display import Display display = Display() -def list_collections(coll_filter=None, search_paths=None, dedupe=False): +@with_collection_artifacts_manager +def list_collections(coll_filter=None, search_paths=None, dedupe=True, artifacts_manager=None): collections = {} - for candidate in list_collection_dirs(search_paths=search_paths, coll_filter=coll_filter): - if os.path.exists(candidate): - collection = _get_collection_name_from_path(candidate) - if collection not in collections or not dedupe: - collections[collection] = candidate + 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 return collections -def list_valid_collection_paths(search_paths=None, warn=False): - """ - Filter out non existing or invalid search_paths for collections - :param search_paths: list of text-string paths, if none load default config - :param warn: display warning if search_path does not exist - :return: subset of original list - """ - - if search_paths is None: - search_paths = [] - - search_paths.extend(AnsibleCollectionConfig.collection_paths) - - for path in search_paths: - - b_path = to_bytes(path) - if not os.path.exists(b_path): - # warn for missing, but not if default - if warn: - display.warning("The configured collection path {0} does not exist.".format(path)) - continue - - if not os.path.isdir(b_path): - if warn: - display.warning("The configured collection path {0}, exists, but it is not a directory.".format(path)) - continue - - yield path - - -def list_collection_dirs(search_paths=None, coll_filter=None): +@with_collection_artifacts_manager +def list_collection_dirs(search_paths=None, coll_filter=None, artifacts_manager=None, dedupe=True): """ Return paths for the specific collections found in passed or configured search paths :param search_paths: list of text-string paths, if none load default config @@ -67,48 +30,33 @@ def list_collection_dirs(search_paths=None, coll_filter=None): :return: list of collection directory paths """ - collection = None - namespace = None + namespace_filter = None + collection_filter = None + has_pure_namespace_filter = False # whether at least one coll_filter is a namespace-only filter if coll_filter is not None: - if '.' in coll_filter: - try: - (namespace, collection) = coll_filter.split('.') - except ValueError: - raise AnsibleError("Invalid collection pattern supplied: %s" % coll_filter) - else: - namespace = coll_filter - - collections = defaultdict(dict) - for path in list_valid_collection_paths(search_paths): - - if os.path.basename(path) != 'ansible_collections': - path = os.path.join(path, 'ansible_collections') - - b_coll_root = to_bytes(path, errors='surrogate_or_strict') - - if os.path.exists(b_coll_root) and os.path.isdir(b_coll_root): - - if namespace is None: - namespaces = os.listdir(b_coll_root) + if isinstance(coll_filter, str): + coll_filter = [coll_filter] + namespace_filter = set() + for coll_name in coll_filter: + if '.' in coll_name: + try: + namespace, collection = coll_name.split('.') + except ValueError: + raise AnsibleError("Invalid collection pattern supplied: %s" % coll_name) + namespace_filter.add(namespace) + if not has_pure_namespace_filter: + if collection_filter is None: + collection_filter = [] + collection_filter.append(collection) else: - namespaces = [namespace] - - for ns in namespaces: - b_namespace_dir = os.path.join(b_coll_root, to_bytes(ns)) + namespace_filter.add(coll_name) + has_pure_namespace_filter = True + collection_filter = None + namespace_filter = sorted(namespace_filter) - if os.path.isdir(b_namespace_dir): + for req in find_existing_collections(search_paths, artifacts_manager, namespace_filter=namespace_filter, + collection_filter=collection_filter, dedupe=dedupe): - if collection is None: - colls = os.listdir(b_namespace_dir) - else: - colls = [collection] - - for mycoll in colls: - - # skip dupe collections as they will be masked in execution - if mycoll not in collections[ns]: - b_coll = to_bytes(mycoll) - b_coll_dir = os.path.join(b_namespace_dir, b_coll) - if is_collection_path(b_coll_dir): - collections[ns][mycoll] = b_coll_dir - yield b_coll_dir + if not has_pure_namespace_filter and coll_filter is not None and req.fqcn not in coll_filter: + continue + yield to_bytes(req.src) |