--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 2023 by Frank Brehm, Digitas Pixelpark GmbH, Berlin
+@summary: A base module for encapsulating all information about a Puppet module
+"""
+from __future__ import absolute_import
+
+# Standard modules
+import logging
+import re
+
+# Third party modules
+from fb_tools.common import to_str
+from fb_tools.obj import FbBaseObjectError, FbBaseObject
+
+# Own modules
+from .errors import PuppetToolsError, ModuleInitError
+from .xlate import XLATOR
+
+__version__ = '0.1.0'
+
+LOG = logging.getLogger(__name__)
+
+_ = XLATOR.gettext
+ngettext = XLATOR.ngettext
+
+
+# =============================================================================
+class BaseModuleInfo(FbBaseObject):
+ """Base class for encapsulating information about a Puppet module."""
+
+ re_split_name = re.compile(r'^\s*([a-z0-9]+)[-/_](\S+)\s*$', re.IGNORECASE)
+
+ # -------------------------------------------------------------------------
+ def __init__(
+ self, appname=None, verbose=0, version=__version__, base_dir=None,
+ initialized=None, name=None, vendor=None, full_name=None):
+
+ self._name = None
+ self._vendor = None
+ self._full_name_orig = None
+
+ super(BaseModuleInfo, self).__init__(
+ appname=appname, verbose=verbose, version=version,
+ base_dir=base_dir, initialized=False,
+ )
+
+ _name = name
+ if name is not None:
+ _name = to_str(name).strip()
+
+ _vendor = vendor
+ if vendor is not None:
+ _vendor = to_str(vendor).strip()
+
+ _full_name = full_name
+ if full_name is not None:
+ _full_name = to_str(full_name).strip()
+
+ if _full_name:
+
+ match = self.re_split_name.match(_full_name)
+ if not match:
+ raise ModuleInitError(
+ _("Could not analyze given full module name {!r}.").format(
+ full_name))
+
+ self._full_name_orig = _full_name
+
+ if _name:
+ self._name = _name
+ else:
+ self._name = match.group(2).lower()
+
+ if _vendor:
+ self._vendor = _name
+ else:
+ self._vendor = match.group(1).lower()
+
+ else:
+
+ if not _name or not _vendor:
+ msg = _(
+ "There must be given a full module name or the base module name "
+ "and the vendor name (user name on Puppet Forge).")
+ raise ModuleInitError(msg)
+
+ self._name = _name
+ self._vendor = _vendor
+ self._full_name_orig = self.full_name
+
+ # -------------------------------------------------------------------------
+ @property
+ def name(self):
+ """The name of the module without the vendor."""
+ return self._name
+
+ # -------------------------------------------------------------------------
+ @property
+ def vendor(self):
+ """The vendor of the module - the username on Puppet forge."""
+ return self._vendor
+
+ # -------------------------------------------------------------------------
+ @property
+ def full_name(self):
+ """The full name of the module including vandor and name."""
+ if self.name is None:
+ return None
+ if self.vendor is None:
+ return None
+ return "{v}-{n}".format(v=self.vendor, n=self.name)
+
+ # -------------------------------------------------------------------------
+ @property
+ def full_name_orig(self):
+ """The original full name of the module."""
+ if self._full_name_orig:
+ return self._full_name_orig
+ return self.full_name
+
+ @full_name_orig.setter
+ def full_name_orig(self, value):
+ if value is None:
+ self._full_name_orig = None
+ return
+ val = to_str(value).strip()
+ if val:
+ self._full_name_orig = val
+ else:
+ self._full_name_orig = None
+
+ # -------------------------------------------------------------------------
+ def __repr__(self):
+ return str(self)
+
+ # -------------------------------------------------------------------------
+ def __eq__(self, other):
+ """The == - operator."""
+
+ if self.verbose > 4:
+ LOG.debug("Comparing {what!r} {cls}-objects ...".format(
+ what='==', cls=self.__class__.__name__))
+
+ if not isinstance(other, BaseModuleInfo):
+ return False
+
+ if self.name is None or self.vendor is None or other.name is None or other.vendor is None:
+ msg = _("Cannot compare an empty puppet module info with another module info.")
+ raise BaseModuleInfoError(msg)
+
+ if self.name.lower() != other.name.lower():
+ return False
+
+ if self.vendor.lower() != other.vendor.lower():
+ return False
+
+ return True
+
+ # -------------------------------------------------------------------------
+ def __lt__(self, other):
+ """The < - operator."""
+
+ if self.verbose > 4:
+ LOG.debug("Comparing {what!r} {cls}-objects ...".format(
+ what='<', cls=self.__class__.__name__))
+
+ if self.name is None or self.vendor is None or other.name is None or other.vendor is None:
+ msg = _("Cannot compare an empty puppet module info with another module info.")
+ raise BaseModuleInfoError(msg)
+
+ if self.vendor.lower() < other.vendor.lower():
+ return True
+ if self.vendor.lower() > other.vendor.lower():
+ return False
+ if self.name.lower() < other.name.lower():
+ return True
+ return False
+
+ # -------------------------------------------------------------------------
+ def __le__(self, other):
+ """The <= - operator."""
+
+ if self.verbose > 4:
+ LOG.debug("Comparing {what!r} {cls}-objects ...".format(
+ what='<=', cls=self.__class__.__name__))
+
+ if self.name is None or self.vendor is None or other.name is None or other.vendor is None:
+ msg = _("Cannot compare an empty puppet module info with another module info.")
+ raise BaseModuleInfoError(msg)
+
+ if self == other:
+ return True
+
+ return self < other
+
+ # -------------------------------------------------------------------------
+ def __gt__(self, other):
+ """The > - operator."""
+
+ if self.verbose > 4:
+ LOG.debug("Comparing {what!r} {cls}-objects ...".format(
+ what='>', cls=self.__class__.__name__))
+
+ if self.name is None or self.vendor is None or other.name is None or other.vendor is None:
+ msg = _("Cannot compare an empty puppet module info with another module info.")
+ raise BaseModuleInfoError(msg)
+
+ if self.vendor.lower() > other.vendor.lower():
+ return True
+ if self.vendor.lower() < other.vendor.lower():
+ return False
+ if self.name.lower() > other.name.lower():
+ return True
+ return False
+
+ # -------------------------------------------------------------------------
+ def __ge__(self, other):
+ """The >= - operator."""
+
+ if self.verbose > 4:
+ LOG.debug("Comparing {what!r} {cls}-objects ...".format(
+ what='>=', cls=self.__class__.__name__))
+
+ if self.name is None or self.vendor is None or other.name is None or other.vendor is None:
+ msg = _("Cannot compare an empty puppet module info with another module info.")
+ raise BaseModuleInfoError(msg)
+
+ if self == other:
+ return True
+
+ return self > other
+
+ # -------------------------------------------------------------------------
+ def as_dict(self, short=True):
+ """
+ Transforms the elements of the object into a dict
+
+ @return: structure as dict
+ @rtype: dict
+ """
+
+ res = super(BaseModuleInfo, self).as_dict(short=short)
+
+ res['name'] = self.name
+ res['vendor'] = self.vendor
+ res['full_name'] = self.full_name
+ res['full_name_orig'] = self.full_name_orig
+
+ return res
+
+ # -------------------------------------------------------------------------
+ def to_data(self):
+ """Returning a dict, which can be used to re-instantiate this module info."""
+
+ res = {}
+
+ res['name'] = self.name
+ res['vendor'] = self.vendor
+ res['full_name'] = self.full_name
+ res['full_name_orig'] = self.full_name_orig
+
+ return res
+
+ # -------------------------------------------------------------------------
+ def __copy__(self):
+
+ module_info = BaseModuleInfo(
+ name=self.name, vendor=self.vendor,
+ appname=self.appname, verbose=self.verbose, base_dir=self.base_dir)
+
+ if self.full_name_orig:
+ module_info.full_name_orig = self.full_name_orig
+
+ module_info.initialized = self.initialized
+ return module_info
+
+
+# =============================================================================
+if __name__ == "__main__":
+
+ pass
+
+# =============================================================================
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list