mirror of https://github.com/ansible/ansible.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
3.1 KiB
Python
104 lines
3.1 KiB
Python
# (c) 2019 Ansible Project
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
# CAUTION: This implementation of the collection loader is used by ansible-test.
|
|
# Because of this, it must be compatible with all Python versions supported on the controller or remote.
|
|
|
|
from __future__ import (absolute_import, division, print_function)
|
|
__metaclass__ = type
|
|
|
|
from ansible.module_utils.common.text.converters import to_text
|
|
from ansible.module_utils.six import add_metaclass
|
|
|
|
|
|
class _EventSource:
|
|
def __init__(self):
|
|
self._handlers = set()
|
|
|
|
def __iadd__(self, handler):
|
|
if not callable(handler):
|
|
raise ValueError('handler must be callable')
|
|
self._handlers.add(handler)
|
|
return self
|
|
|
|
def __isub__(self, handler):
|
|
try:
|
|
self._handlers.remove(handler)
|
|
except KeyError:
|
|
pass
|
|
|
|
return self
|
|
|
|
def _on_exception(self, handler, exc, *args, **kwargs):
|
|
# if we return True, we want the caller to re-raise
|
|
return True
|
|
|
|
def fire(self, *args, **kwargs):
|
|
for h in self._handlers:
|
|
try:
|
|
h(*args, **kwargs)
|
|
except Exception as ex:
|
|
if self._on_exception(h, ex, *args, **kwargs):
|
|
raise
|
|
|
|
|
|
class _AnsibleCollectionConfig(type):
|
|
def __init__(cls, meta, name, bases):
|
|
cls._collection_finder = None
|
|
cls._default_collection = None
|
|
cls._on_collection_load = _EventSource()
|
|
|
|
@property
|
|
def collection_finder(cls):
|
|
return cls._collection_finder
|
|
|
|
@collection_finder.setter
|
|
def collection_finder(cls, value):
|
|
if cls._collection_finder:
|
|
raise ValueError('an AnsibleCollectionFinder has already been configured')
|
|
|
|
cls._collection_finder = value
|
|
|
|
@property
|
|
def collection_paths(cls):
|
|
cls._require_finder()
|
|
return [to_text(p) for p in cls._collection_finder._n_collection_paths]
|
|
|
|
@property
|
|
def default_collection(cls):
|
|
return cls._default_collection
|
|
|
|
@default_collection.setter
|
|
def default_collection(cls, value):
|
|
|
|
cls._default_collection = value
|
|
|
|
@property
|
|
def on_collection_load(cls):
|
|
return cls._on_collection_load
|
|
|
|
@on_collection_load.setter
|
|
def on_collection_load(cls, value):
|
|
if value is not cls._on_collection_load:
|
|
raise ValueError('on_collection_load is not directly settable (use +=)')
|
|
|
|
@property
|
|
def playbook_paths(cls):
|
|
cls._require_finder()
|
|
return [to_text(p) for p in cls._collection_finder._n_playbook_paths]
|
|
|
|
@playbook_paths.setter
|
|
def playbook_paths(cls, value):
|
|
cls._require_finder()
|
|
cls._collection_finder.set_playbook_paths(value)
|
|
|
|
def _require_finder(cls):
|
|
if not cls._collection_finder:
|
|
raise NotImplementedError('an AnsibleCollectionFinder has not been installed in this process')
|
|
|
|
|
|
# concrete class of our metaclass type that defines the class properties we want
|
|
@add_metaclass(_AnsibleCollectionConfig)
|
|
class AnsibleCollectionConfig(object):
|
|
pass
|