Extending lpcraft

lpcraft uses pluggy to customize the default behaviour. For example the following code snippet would extend the packages which need to be installed into an environment by additional requirements:

from lpcraft.plugin import hookimpl


@hookimpl
def lpcraft_install_packages():
    return ["tox"]

Plugin discovery

As currently only builtin plugins are supported, you need to define a plugin in lpcraft/plugins/<plugin> and import the module in lpcraft/plugins/__init__.py.

Plugin implementation

Please consult the pluggy documentation, and have a look at the lpcraft/plugins directory for inspiration.

Name of the hook

lpcraft.plugin.NAME = 'lpcraft'

name of the hook

Implementation marker

lpcraft.plugin.hookimpl

decorator to mark lpcraft plugin hooks

Available hooks

lpcraft.plugin.hookspecs.lpcraft_execute_after_run() str

Command to execute after the main execution body.

lpcraft.plugin.hookspecs.lpcraft_execute_before_run() str

Command to execute prior to the main execution body.

lpcraft.plugin.hookspecs.lpcraft_execute_run() str

Command to be executed.

lpcraft.plugin.hookspecs.lpcraft_install_packages() list[str]

System packages to be installed.

lpcraft.plugin.hookspecs.lpcraft_install_snaps() list[str]

Snaps to be installed.

lpcraft.plugin.hookspecs.lpcraft_set_environment() dict[str, str | None]

Environment variables to be set.

Additional configuration keys

Plugins can have their own configuration keys.

@register(name="miniconda")
class MiniCondaPlugin(BasePlugin):
    class Config(BaseConfig):
        conda_packages: Optional[List[StrictStr]]
        conda_python: Optional[StrictStr]

The above code defines the MiniCondaPlugin with two additional configuration keys.

These keys could be used in the .launchpad.yaml configuration file as following:

jobs:
    myjob:
        plugin: miniconda
        conda-packages:
            - mamba
            - numpy=1.17
            - scipy
            - pip
        conda-python: 3.8
        run: |
            pip install --upgrade pytest
            python -m build .

Interpolation of run commands

By default a run command in the configuration file overrides the command defined by the plugin, if any, unless the plugin class sets INTERPOLATES_RUN_COMMANDS to True, in which case the plugin can interpolate the command, like in the following example:

class MiniCondaPlugin(BasePlugin):
    INTERPOLATES_RUN_COMMAND = True

    @hookimpl
    def lpcraft_execute_run(self) -> str:
        run = self.config.run or ""
        return textwrap.dedent(
            f"""\
            export PATH=$HOME/miniconda3/bin:$PATH
            source activate $CONDA_ENV
            {run}"""
        )

This applies to the run-before, the run, and the run-after commands.

Builtin plugins

class lpcraft.plugins.plugins.CondaBuildPlugin(config: Job, plugin_settings: Dict[str, str] | None = None)

Sets up miniconda3 and performs a conda-build on a package.

Usage:

In .launchpad.yaml, create the following structure:

jobs:
    myjob:
       plugin: conda-build
       build-target: info/recipe/parent
       conda-channels:
         - conda-forge
         - defaults
       conda-packages:
         - mamba
         - numpy=1.17
         - scipy
         - pip
       conda-python: 3.8
       run: |
         conda install ....
         pip install --upgrade pytest
         python -m build .
class Config(**extra_data: Any)
get_plugin_config() Config

Return the properly typecast plugin configuration.

class lpcraft.plugins.plugins.GolangPlugin(config: Job, plugin_settings: Dict[str, str] | None = None)

Installs the required golang version.

Usage:

In .launchpad.yaml, create the following structure. Please note that the golang-version has to be a string.

pipeline:
    - build

jobs:
    build:
        plugin: golang
        golang-version: "1.17"
        series: focal
        architectures: amd64
        packages: [file, git]
        run: go build -x examples/go-top.go

Please note that the requested golang package needs to be available either in the standard repository or in a repository specified in package-repositories.

class Config(**extra_data: Any)
get_plugin_config() Config

Return the properly typecast plugin configuration.

class lpcraft.plugins.plugins.MiniCondaPlugin(config: Job, plugin_settings: Dict[str, str] | None = None)

Installs miniconda3 and resets the environment.

Usage:

In .launchpad.yaml, create the following structure:

jobs:
    myjob:
       plugin: miniconda
       conda-packages:
         - mamba
         - numpy=1.17
         - scipy
         - pip
       conda-python: 3.8
       run: |
         conda install ....
         pip install --upgrade pytest
         python -m build .
class Config(**extra_data: Any)
get_plugin_config() Config

Return the properly typecast plugin configuration.

class lpcraft.plugins.plugins.PyProjectBuildPlugin(config: Job, plugin_settings: Dict[str, str] | None = None)

Installs build and builds a Python package according to PEP 517.

Usage:

In .launchpad.yaml create a key/value pair with plugin and pyproject-build within the job definition.

class lpcraft.plugins.plugins.ToxPlugin(config: Job, plugin_settings: Dict[str, str] | None = None)

Installs tox and executes the configured environments.

Usage:

In .launchpad.yaml create a key/value pair with plugin and tox within the job definition.

Using a builtin plugin

In order to use a plugin, it has to be specified via the plugin key in the job definition.

pipeline:
    - test

jobs:
    test:
        series: focal
        architectures: amd64
        plugin: tox