Using Plugins

We can use configuration files to customize Wiz, but we can also extend the configuration mapping with dynamic values using Python plugins.

Hint

Plugins are being discovered and loaded just after configuration mapping has been created from configuration files. So any modification to the configuration mapping done in the plugins will always overwrite the content of the configuration files.

Default plugins

The following plugins are located in wiz/package_data/plugins. They are used by default, unless modified during the installation process.

environ

This plugin adds initial environment variable to the configuration mapping.

# :coding: utf-8

import getpass
import os
import socket

#: Unique identifier of the plugin.
IDENTIFIER = "environ"


def register(config):
    """Register initial environment variables.

    The initial environment mapping contains basic variables from the external
    environment that can be used by the resolved environment, such as
    the *USER*, the *HOSTNAME* or the *HOME* variables.

    The *PATH* variable is initialized with default values to have access to the
    basic UNIX commands.

    """
    environ = {
        "USER": getpass.getuser(),
        "HOME": os.path.expanduser("~"),
        "HOSTNAME": socket.gethostname(),
        "PATH": os.pathsep.join([
            "/usr/local/sbin",
            "/usr/local/bin",
            "/usr/sbin",
            "/usr/bin",
            "/sbin",
            "/bin",
        ])
    }

    config.setdefault("environ", {})
    config["environ"].setdefault("initial", {})
    config["environ"]["initial"].update(environ)

installer

This plugin adds an installer callback to the configuration mapping to indicate how a definition can be installed using wiz install.

# :coding: utf-8

import wiz.registry

#: Unique identifier of the plugin.
IDENTIFIER = "installer"


def install_definitions(paths, registry_target, overwrite=False):
    """Install a definition file to a registry.

    *paths* is the path list to all definition files.

    *registry_target* should be a path to a local registry.

    If *overwrite* is True, any existing definitions in the target registry
    will be overwritten.

    Raises :exc:`wiz.exception.IncorrectDefinition` if data in *paths* cannot
    create a valid instance of :class:`wiz.definition.Definition`.

    Raises :exc:`wiz.exception.DefinitionExists` if definition already exists in
    the target registry and *overwrite* is False.

    Raises :exc:`OSError` if the definition can not be exported in a registry
    local *path*.

    """
    definitions = []

    for path in paths:
        _definition = wiz.load_definition(path)
        definitions.append(_definition)

    wiz.registry.install_to_path(
        definitions, registry_target, overwrite=overwrite
    )


def register(config):
    """Register definition installer callback."""
    config.setdefault("callback", {})
    config["callback"]["install"] = install_definitions

Adding new plugins

More plugins can be added in ~/.wiz/plugins for development purpose. The default plugins will always be loaded first, followed by the personal plugins.

A plugin is uniquely identified by the IDENTIFIER data string. Therefore, you can overwrite a plugin by re-using the same identifier.

Hint

It is highly recommended to deploy custom plugins when installing the package instead of using it from the personal plugin path as it can be error prone.