anod.qualifiers_manager
=======================

.. py:module:: anod.qualifiers_manager


Attributes
----------

.. autoapisummary::

   anod.qualifiers_manager.VALID_NAME


Classes
-------

.. autoapisummary::

   anod.qualifiers_manager.QualifierDeclaration
   anod.qualifiers_manager.KeyValueDeclaration
   anod.qualifiers_manager.TagDeclaration
   anod.qualifiers_manager.KeySetDeclaration
   anod.qualifiers_manager.QualifiersManager


Functions
---------

.. autoapisummary::

   anod.qualifiers_manager.check_valid_name


Module Contents
---------------

.. py:data:: VALID_NAME

.. py:function:: check_valid_name(name: str, value_kind: str, origin: str) -> str

   Check if a value is a valid qualifier name or component name.

   A valid name is any non empty string containg alphanumeric character, dot,
   dashes and underscores.

   :param name: the name to check
   :param value_kind: a name to describe the kind of value (used in error message)
   :param origin: a string giving the origin of the check
   :return: name if name is valid otherwise raise AnodError


.. py:class:: QualifierDeclaration(origin: str, name: str, description: str, repr_in_hash: bool = False, repr_name: str | None = None)

   Root class for qualifiers declaration.


   .. py:attribute:: origin


   .. py:attribute:: name


   .. py:attribute:: description


   .. py:attribute:: repr_in_hash
      :value: False



   .. py:attribute:: repr_name


   .. py:property:: default
      :type: str | bool | frozenset[str] | None


      Return default value for qualifier.

      :return: if None is returned it means the qualifier has not
          default Value. Otherwise the default value is returned.



   .. py:method:: value(value: str | bool | Iterable[str] | None) -> str | bool | frozenset[str]
      :abstractmethod:


      Compute the value of qualifier given the user input.



   .. py:method:: repr(value: str | bool | frozenset[str], hash_pool: list[str] | None) -> str
      :abstractmethod:


      Compute a string representation of a qualifier.

      :param value: the effective value associated with the qualifier
      :param hash_pool: if not None and repr_in_hash is True, the represantion
          is added to that list. The list is used then to compute a hash and
          thus reduce the build space length.
      :return: the qualifier representation if self.repr_in_hash is False
          or hash_pool is None. if hash_pool is not None and self.repr_in_hash
          is True, the string representation is appended to hash_pool and the
          method returns the empty string.



.. py:class:: KeyValueDeclaration(origin: str, name: str, description: str, repr_in_hash: bool = False, repr_name: str | None = None, repr_omit_key: bool = False, default: str | None = None, choices: list[str] | None = None)

   Bases: :py:obj:`QualifierDeclaration`


   Root class for qualifiers declaration.


   .. py:attribute:: repr_omit_key
      :value: False



   .. py:attribute:: choices
      :value: None



   .. py:attribute:: _default
      :value: None



   .. py:property:: default
      :type: str | bool | frozenset[str] | None


      See QualifierDeclaration.default.



   .. py:method:: value(value: str | bool | Iterable[str] | None) -> str | bool | frozenset[str]

      See QualifierDeclaration.value.



   .. py:method:: repr(value: str | bool | frozenset[str], hash_pool: list[str] | None) -> str

      See QualifierDeclaration.repr.



.. py:class:: TagDeclaration(origin: str, name: str, description: str, repr_in_hash: bool = False, repr_name: str | None = None)

   Bases: :py:obj:`QualifierDeclaration`


   Tag qualifier declaration.


   .. py:property:: default
      :type: str | bool | frozenset[str] | None


      See QualifierDeclaration.value.



   .. py:method:: value(value: str | bool | Iterable[str] | None) -> str | bool | frozenset[str]

      See QualifierDeclaration.value.



   .. py:method:: repr(value: str | bool | frozenset[str], hash_pool: list[str] | None) -> str

      See QualifierDeclaration.repr.



.. py:class:: KeySetDeclaration(origin: str, name: str, description: str, repr_in_hash: bool = False, repr_name: str | None = None, repr_omit_key: bool = False, default: set[str] | None = None, choices: list[str] | None = None)

   Bases: :py:obj:`QualifierDeclaration`


   Root class for qualifiers declaration.


   .. py:attribute:: LIST_SEPARATOR
      :value: ';'



   .. py:attribute:: repr_omit_key
      :value: False



   .. py:attribute:: choices
      :value: None



   .. py:attribute:: _default
      :type:  frozenset[str] | None


   .. py:property:: default
      :type: str | bool | frozenset[str] | None


      See QualifierDeclaration.default.



   .. py:method:: value(value: str | bool | Iterable[str] | None) -> str | bool | frozenset[str]

      See QualifierDeclaration.value.



   .. py:method:: repr(value: str | bool | frozenset[str], hash_pool: list[str] | None) -> str

      See QualifierDeclaration.repr.



.. py:class:: QualifiersManager(anod_instance: e3.anod.spec.Anod)

   Parse the qualifiers and build an unique name.

   This class is used to manage the qualifiers, declare the components and generate
   the components and build_space names.

   The qualifiers must all be declared using the declare_tag_qualifier or
   declare_key_value_qualifier method to be usable in the spec. The declaration is a
   way for the spec (i.e. the QualifiersManager) to know which are the authorized
   qualifiers and how to use them (default values...).

   'key_value' qualifiers are qualifiers associated with a value. For example,
   'version' is likely to have a value (the actual version number) and thus would be
   declared as a 'key_value' qualifier.

   A 'tag' qualifier has no value. More precisely, its value is True when the
   qualifier is passed to spec and False otherwise.

   The component must also be declared using the declare_component method.
   The 'component' is the name of the Cathod entry related to the spec
   (None if it has no entry). A component is bound to a particular configuration of
   qualifiers (set of pair qualifier/value). If the current qualifier configuration
   has been bound to a component then this name is used for both the build_space name
   and the component name. Otherwise, the component name is None (there is no
   component to be uploaded in Cathod)

   This class is also used to generate the build_space name. The build_space name is
   computed using all the declared qualifiers and their values (at runtime).
   This allow the build_space names to be different for each different builds
   (assuming that different build <=> different set of qualifier values).


   .. py:attribute:: anod_instance


   .. py:attribute:: origin


   .. py:attribute:: qualifier_decls
      :type:  dict[str, QualifierDeclaration]


   .. py:attribute:: component_decls
      :type:  dict[str, tuple[dict[str, str], bool]]


   .. py:attribute:: component_names
      :type:  dict[tuple[tuple[str, str | bool | frozenset[str]], Ellipsis], str]


   .. py:attribute:: build_space_names
      :type:  dict[tuple[tuple[str, str | bool | frozenset[str]], Ellipsis], str]


   .. py:attribute:: qualifier_values
      :type:  dict[str, str | bool | frozenset[str]]


   .. py:attribute:: is_declaration_phase_finished
      :type:  bool
      :value: False



   .. py:attribute:: base_name
      :type:  str


   .. py:attribute:: component
      :type:  str | None
      :value: None



   .. py:attribute:: build_space_name
      :type:  str
      :value: ''



   .. py:attribute:: machine_aliases
      :type:  dict[str, str]


   .. py:attribute:: os_version_aliases
      :type:  dict[str, str]


   .. py:attribute:: add_target_info_to_bs
      :value: False



   .. py:method:: add_target_info(machine_aliases: dict[str, str] | None = None, os_version_aliases: dict[str, str] | None = None) -> None

      Enable target os information in build space name computation.

      Note that target information is added only if in a cross context.

      :param machine_aliases: aliases for server name. Can be used to shorten
          build space name
      :param os_version_aliases: aliases for OS versions. Can be used to shorten
          build space name



   .. py:method:: remove_target_info() -> None

      Disable target os information in build space name computation.



   .. py:method:: declare_tag_qualifier(name: str, description: str, test_only: bool = False, repr_alias: str | None = None, repr_in_hash: bool = False) -> None

      Declare a new tag qualifier.

      Declare a tag qualifier to allow it use in the spec. It will have an impact on
      the build_space and component names.

      A tag qualifier is a qualifier with an implicit value. Their value is True if
      the qualifier is passed at runtime and False else.

      This method cannot be called after the end of the declaration phase.

      :param name: The name of the qualifier. It used to identify it and pass it to
          the spec.
      :param description: A description of the qualifier purposes. It is used to
          make the help/error clearer.
      :param test_only: By default the qualifier are used by all anod actions
          (install, build, test...). If test_only is True, then this qualifier is
          only available for test.
      :param repr_alias: An alias for the qualifier name used by the name generation.
          By default, the repr_alias is the qualifier name itself.
      :param repr_in_hash: False by default. If True, the qualifier is included in
       the hash at the end of the generated name. The result is less readable but
       shorter.



   .. py:method:: declare_key_value_qualifier(name: str, description: str, test_only: bool = False, default: str | None = None, choices: list[str] | None = None, repr_alias: str | None = None, repr_in_hash: bool = False, repr_omit_key: bool = False) -> None

      Declare a new key value qualifier.

      Declare a key value qualifier to allow it use in the spec. It will have an
      impact on the build_space and component names.

      A key value qualifier is a 'standard' qualifier. They require the user to
      provide their value.

      This method cannot be called after the end of the declaration phase.

      :param name: The name of the qualifier. It used to identify it and pass it to
          the spec.
      :param description: A description of the qualifier purposes. It is used to
          make the help/error clearer.
      :param test_only: By default the qualifier are used by all anod actions
          (install, build, test...). If test_only is True, then this qualifier is
          only available for test.
      :param default: The default value given to the qualifier if no value was
          provided by the user. If no default value is set, then the user must
          provide a qualifier value at runtime.
      :param choices: The list of all authorized values for the qualifier.
      :param repr_alias: An alias for the qualifier name used by the name generation.
          By default, the repr_alias is the qualifier name itself.
      :param repr_in_hash: False by default. If True, the qualifier is included in
          the hash at the end of the generated name. The result is less readable but
          shorter.
      :param repr_omit_key: If True, then the name generation don't display the
          qualifier name/alias. It only use its value.



   .. py:method:: declare_key_set_qualifier(name: str, description: str, test_only: bool = False, default: set[str] | None = None, choices: list[str] | None = None, repr_alias: str | None = None, repr_in_hash: bool = False, repr_omit_key: bool = False) -> None

      Declare a new key set qualifier.

      Declare a key set qualifier to allow it use in the spec. It will have an
      impact on the build_space and component names.

      A key set qualifier is a 'list' qualifier. They require the user to
      provide their values as a semi-colon separated list.

      This method cannot be called after the end of the declaration phase.

      :param name: The name of the qualifier. It used to identify it and pass it to
          the spec.
      :param description: A description of the qualifier purposes. It is used to
          make the help/error clearer.
      :param test_only: By default the qualifier are used by all anod actions
          (install, build, test...). If test_only is True, then this qualifier is
          only available for test.
      :param default: The default value given to the qualifier if no value was
          provided by the user. If no default value is set, then the user must
          provide a qualifier value at runtime.
      :param choices: The list of all authorized values for the qualifier.
      :param repr_alias: An alias for the qualifier name used by the name generation.
          By default, the repr_alias is the qualifier name itself.
      :param repr_in_hash: False by default. If True, the qualifier is included in
          the hash at the end of the generated name. The result is less readable but
          shorter.
      :param repr_omit_key: If True, then the name generation don't display the
          qualifier name/alias. It only use its value.



   .. py:method:: declare_component(name: str, required_qualifier_configuration: dict[str, str]) -> None

      Declare a new component.

      A component is bound to a qualifier configuration (i.e. a dictionary mapping
      the qualifiers to their values as provided by the user at runtime). The
      provided component name is used if the qualifier meet the provided qualifier
      values.

      This method cannot be called after the end of the declaration phase.

      :param name: A string representing the component name.
      :param required_qualifier_configuration: The dictionary of qualifiers
          value corresponding to the build linked to the component.



   .. py:method:: declare_build_space_name(name: str, required_qualifier_configuration: dict[str, str], has_component: bool = False) -> None

      Declare a new component.

      A component is bound to a qualifier configuration (i.e. a dictionary mapping
      the qualifiers to their values as provided by the user at runtime). The
      provided component name is used if the qualifier meet the provided qualifier
      values.

      This method cannot be called after the end of the declaration phase.

      :param name: A string representing the component name.
      :param required_qualifier_configuration: The dictionary of qualifiers
          value corresponding to the build linked to the component.



   .. py:method:: compute_qualifier_values(qualifier_dict: dict[str, str]) -> dict[str, str | bool | frozenset[str]]

      Given a user qualifier dict compute and validate final values.

      :param qualifier_dict: User qualifiers
      :return: the computed qualifier values (applying default and validity checks).



   .. py:method:: serialize_qualifier_values(qualifier_values: dict[str, str | bool | frozenset[str]]) -> tuple[tuple[str, str | bool | frozenset[str]], Ellipsis]

      Return a hashable and deterministic representation of qualifier values.

      :param qualifier_values: qualifier values as returned by
          compute_qualifier_values
      :return: a tuple of couple (key, value) sorted by key



   .. py:method:: parse(user_qualifiers: dict[str, str]) -> None

      Parse the provided qualifiers.

      This function first makes sure that all the user_qualifiers
      follow the rules:
      * Have been declared.
      * Set a value if they don't have a default one.
      * Have a value which respect the choices attribute.

      After the first call to this method, it is no longer possible to declare new
      component nor qualifier. This ensure the consistency of the generated names.

      After the call to parse, the qualifier_values are available using
      __getparsed_qualifiers.

      :param user_qualifiers: a dictionary containing the passed qualifier
          values.



   .. py:method:: compute_build_space_name() -> None

      Compute the final build_space_name.

      Aggregate the build_space name. It is made of four parts:
      base + qualifier_suffix + hash + test

       * base: The component_prefix or, by default, the spec name.
       * qualifier_suffix: The concatenation of the contribution of
          all qualifiers.
       * hash: The hash of the aggregation of all qualifiers marked with
          'repr_in_hash'.
       * test: '-test' if the current anod primitive is test.

      If the generated component is not None, then use it for consistency reason.



   .. py:method:: __getitem__(key: str) -> str | bool | frozenset[str]

      Return the parsed value of the requested qualifier.

      :return: The qualifier value after the parsing.



