.. _module-tags:

Module tags
===========

Configuration
-------------

- No specific configuration

Specification
-------------

- Introduce one new modulefile command to set tags on modulefiles: :mfcmd:`module-tag`

    - A tag is a piece of information associated to individual modulefiles
    - That is reported along module name on ``avail`` or ``list`` sub-command results
    - This piece of information could lead to specific behaviors when handling modulefile over the different module sub-commands or modulefile evaluation modes

        - For instance, a module with a ``sticky`` tag set on it cannot be unloaded

- 3 different kind of tag exist:

    - Those inherited from module state, consequence of a specific modulefile command or module action

        - This kind of tag cannot be defined with the ``module-tag`` command

            - An error is returned otherwise
            - Specific modulefile command should be used instead as such tag may have specific properties that should also be defined along
            - Easier for everybody to only have one way to define such tags and not 2 different commands

        - Every tag holding specific properties should have its dedicated modulefile command to define it

    - Those set with ``module-tag`` that lead to a specific behavior
    - Those set with ``module-tag`` that are purely informational, no specific behavior

- Tags inherited from module state:

    - ``hidden``: module not visible, not reported by default in ``avail`` result (tag acquired through :mfcmd:`module-hide`)
    - ``hidden-loaded``: loaded module not reported by default in ``list`` result (tag acquired through ``module-hide --hidden-loaded``)
    - ``forbidden``: module that cannot be loaded (tag acquired through :mfcmd:`module-forbid`)
    - ``nearly-forbidden``: module that soon cannot be loaded (tag acquired through ``module-forbid``)
    - ``loaded``: loaded module
    - ``auto-loaded``: module automatically loaded by another module

- Tags set with ``module-tag`` associated to a specific behavior:

    - ``sticky``: loaded module cannot be unloaded unless forced or reloaded (see :ref:`sticky-modules`)
    - ``super-sticky``: loaded module cannot be unloaded even if forced, it stills can be unloaded if reloaded afterward (see :ref:`sticky-modules`)

- Tags inherited from module state cannot be set with ``module-tag`` command

    - An error is otherwise thrown

- Modules project may introduce in the future new tags inherited from new states or new specific behaviors

    - These new tags will supersede tags set by users using the same naming


Defining
^^^^^^^^

- ``module-tag [options] tag modspec...``

    - Apply ``tag`` to all modules matching ``modspec`` module specification
    - :ref:`advanced-module-version-specifiers` are supported if relative module option is enabled
    - Full path module specification is not supported, as modulerc are not evaluated when reaching a modulefile specified as full path
    - One tag could be applied to multiple module specifications with a single ``module-tag`` command call

- ``module-tag`` accepts the following options:

    - ``--not-user``: specify a list of users unaffected by specified tagging
    - ``--not-group``: specify a list of groups whose member are unaffected by specified tagging

- ``--not-user`` and ``--not-group`` specification is only supported on Unix platform

    - These 2 options raise an error when used on Windows platform
    - In which case relative ``module-tag`` command is made ineffective as well as remaining content of the modulerc script hosting them
    - Error message is clearly seen when trying to load related modules and indicate where to find the erroneous command

- ``module-tag`` is intended to be used in modulerc files

    - to be easily fetched during ``avail`` sub-command processing
    - they also need to be enabled in modulefile context as global/user rc files are evaluated as modulefile, not modulerc
    - it enables to dissociate environment changes described in the modulefile from the properties of this modulefile

        - as these properties are usually site-specific
        - and modulefile are automatically generated by a build tool
        - but properties are not always related and set by the build tool


Persistency
^^^^^^^^^^^

- The :envvar:`MODULES_LMTAG` environment variable holds all tag information applying to loaded modules

    - Following the same syntax scheme than ``MODULES_LMCONFLICT``
    - For instance ``module/vers&tag&tag:module2&tag``

- The ``loaded`` tag is not recorded in ``MODULES_LMTAG`` environment variable

    - As it obviously applies to all loaded modules defined in ``LOADEDMODULES`` environment variable

- The ``auto-loaded`` tag is not recorded in ``MODULES_LMTAG`` environment variable

    - Auto loaded modules are currently listed in the ``MODULES_LMNOTUASKED`` environment variable


Reporting
^^^^^^^^^

- Defined tags are reported on ``avail`` and ``list`` sub-command results

    - Reported along modulefile name, within angle brackets (following the HTML tag fashion)
    - Each tag separated by a colon
    - For instance ``module/version <tag1:tag2>``
    - Tags are right-aligned on each column
    - One space character at least separates module name and version or list of symbolic version from tag list

- Tags applying to module alias are reported on ``avail`` reports only

    - Where the module alias stands for itself in the report
    - On ``list`` reports, alias is reported along its modulefile target

        - So the tags applying to the alias are not reported
        - Also these tags of the alias are not inherited by alias' target

- Tags applying to symbolic version are never reported

    - As symbols are never reported alone on ``avail`` or ``list`` reports
    - Always reported along their modulefile target
    - Also these tags of the symbolic versions are not inherited by symbol's target

- Some tags are not reported on ``avail`` output:

    - ``hidden-loaded``: correspond to hiding module from loaded list, not from available list

- Some tags are not reported on ``list`` output:

    - ``loaded``: as every modules reported on ``list`` are loaded
    - ``forbidden``: forbidden module cannot be loaded, so it cannot be found among loaded module list
    - ``hidden``: correspond to hiding module from availabilities, not from loaded list

- When reported in JSON output format

    - tags are listed under the ``tags`` key

- Default ``--long`` report does not contain tag information

    - Not to exceed the 80-column output limit by default

Abbreviations
"""""""""""""

- Tag abbreviations are used to translate tag names when reporting them on ``avail`` or ``list`` sub-command output

- The :mconfig:`tag_abbrev` configuration defines the abbreviations to apply to each tag

    - Set by default at configure time to ``auto-loaded=aL:loaded=L:hidden=H:hidden-loaded=H:forbidden=F:nearly-forbidden=nF:sticky=S:super-sticky=sS``

        - Note that by default, *hidden* and *hidden-loaded* tags share the same abbreviation, as they operate on separate contexts (respectively avail and list contexts)

    - Configuration value consists in a ``key=val`` pair value, each key pair are separated by a ``:`` character

        - Follow the same syntax than ``colors`` configuration

    - If an existing tag name is not part of the configuration, it means no abbreviation applies to it

    - If a tag name has an empty string abbreviation defined it is not reported

        - Unless if there is an SGR color configuration defined for this tag

    - The :envvar:`MODULES_TAG_ABBREV` environment variable is used to set a specific value for ``tag_abbrev`` configuration

        - If ``MODULES_TAG_ABBREV`` is set to an empty string, no tag abbreviation applies

- In case default value or environment value of ``tag_abbrev`` is badly set

    - a warning message is returned
    - value is ignored
    - if nor the environment nor the default value is correct then no abbreviation applies to tag

- Tags are not translated to their defined abbreviation in JSON output format

SGR
"""

- If a tag name or tag abbreviation has an SGR code defined in the color list, this SGR code is applied to the module name this tag refer to

    - Tag name or abbreviation is not reported by itself in this case
    - As it is now represented by the SGR applied to module name
    - If an abbreviation exists for a tag, SGR code should be defined for this abbreviation in color list

        - An SGR code set for tag full name does not apply on the abbreviation of this tag

- If multiple tags apply to the same modules and have an SGR code defined for them in the color list

    - All these SGR codes are rendered one after the other over the module name
    - For instance if 2 tags apply, the first one will be rendered over the first half of the module name, the second tag over the second half of

- Tags use by default background color change to stand out

    - As module kind (alias, directory, etc) is mainly represented with foreground color change by default,

- In case if there are more tags to graphically render than character in module name

    - The remaining tags are reported by there name or abbreviation and SGR applies over this name or abbreviation

- The :envvar:`MODULES_TAG_COLOR_NAME` environment variable is used to define the tags whose name (or abbreviation if set) should be reported

    - Their name does not vanish if a SGR code is defined in the color list for them
    - Their SGR code is not rendered over the module name
    - Instead the SGR is applied to the reported tag name (or tag abbreviation if set)
    - ``MODULES_TAG_COLOR_NAME`` is bound to the :mconfig:`tag_color_name` configuration
    - ``MODULES_TAG_COLOR_NAME`` contains the list of tag name (or abbreviation), each tag separated with colon character (``:``)
    - If an abbreviation is defined for a tag and one want it to be reported by itself not rendered over module name

        - This abbreviation should be set in ``MODULES_TAG_COLOR_NAME``
        - Not the full tag name this abbreviation refers to

Querying
^^^^^^^^

- The ``tags`` sub-command of :mfcmd:`module-info` modulefile command enables modulefile to know what tags apply to itself

    - ``module-info tags`` returns a list of all the tags applying to currently evaluated module
    - an empty list is returned when called from a modulerc evaluation context or if no tag applies to current modulefile

- Tags cannot be queried to select modules

    - Symbolic versions or variants can be used to select modules
