155 lines
5.5 KiB
Markdown
155 lines
5.5 KiB
Markdown
# Plugin Spec
|
|
|
|
- Authors: Ben Sherman
|
|
- Status: accepted
|
|
- Deciders: Ben Sherman, Paolo Di Tommaso
|
|
- Date: 2025-09-22
|
|
- Tags: plugins
|
|
|
|
## Summary
|
|
|
|
Provide a way for external systems to understand key information about third-party plugins.
|
|
|
|
## Problem Statement
|
|
|
|
Nextflow plugins need a way to statically declare extensions to the Nextflow language so that external systems can extract information about a plugin without loading it in the JVM.
|
|
|
|
Primary use cases:
|
|
|
|
- The Nextflow language server needs to know about any config scopes, custom functions, etc, defined by a plugin, in order to recognize them in Nextflow scripts and config files.
|
|
|
|
- The Nextflow plugin registry (or other user interfaces) can use this information to provide API documentation.
|
|
|
|
## Goals or Decision Drivers
|
|
|
|
- External systems (e.g. language server) need to be able to understand plugins without having to load them in the JVM.
|
|
|
|
## Non-goals
|
|
|
|
- Defining specs for the core runtime and core plugins: these definitions are handled separately, although they may share some functionality with plugin specs.
|
|
|
|
## Considered Options
|
|
|
|
### Nextflow plugin system
|
|
|
|
Require external systems to use Nextflow's plugin system to load plugins at runtime in order to extract information about them.
|
|
|
|
- **Pro:** Allows any information to be extracted since the entire plugin is loaded
|
|
|
|
- **Con:** Requires the entire Nextflow plugin system to be reused or reimplemented. Not ideal for Java applications since the plugin system is implemented in Groovy, incompatible with non-JVM applications
|
|
|
|
- **Con:** Requires plugins to be downloaded, cached, loaded in the JVM, even though there is no need to use the plugin.
|
|
|
|
### Plugin spec
|
|
|
|
Define a plugin spec for every plugin release which is stored and served by the plugin registry as JSON.
|
|
|
|
- **Pro:** Allows any system to inspect plugin definitions through a standard JSON document, instead of downloading plugins and loading them into a JVM.
|
|
|
|
- **Con:** Requires the plugin spec to be generated at build-time and stored in the plugin registry.
|
|
|
|
- **Con:** Requires a standard format to ensure interoperability across different versions of Nextflow, the language server, and third-party plugins.
|
|
|
|
## Solution
|
|
|
|
Define a plugin spec for every plugin release which is stored and served by the plugin registry as JSON.
|
|
|
|
- Plugin developers only need to define [extension points](https://nextflow.io/docs/latest/plugins/developing-plugins.html#extension-points) as usual, and the Gradle plugin will extract the plugin spec and store it in the plugin registry as part of each plugin release.
|
|
|
|
- The language server can infer which third-party plugins are required from the `plugins` block in a config file. It will retrieve the appropriate plugin specs from the plugin registry.
|
|
|
|
A plugin spec consists of a list of *definitions*. Each definition has a *type* and a *spec*.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"$schema": "https://raw.githubusercontent.com/nextflow-io/schemas/main/plugin/v1/schema.json",
|
|
"definitions": [
|
|
{
|
|
"type": "ConfigScope",
|
|
"spec": {
|
|
// ...
|
|
}
|
|
},
|
|
{
|
|
"type": "Function",
|
|
"spec": {
|
|
// ...
|
|
}
|
|
},
|
|
]
|
|
}
|
|
```
|
|
|
|
The following types of definitions are allowed:
|
|
|
|
**ConfigScope**
|
|
|
|
Defines a top-level config scope. The spec consists of a *name*, an optional *description*, and *children*.
|
|
|
|
The children should be a list of definitions corresponding to nested config scopes and options. The following definitions are allowed:
|
|
|
|
- **ConfigOption**: Defines a config option. The spec consists of a *description* and *type*.
|
|
|
|
- **ConfigScope**: Defines a nested config scope, using the same spec as for top-level scopes.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"type": "ConfigScope",
|
|
"spec": {
|
|
"name": "hello",
|
|
"description": "The `hello` scope controls the behavior of the `nf-hello` plugin.",
|
|
"children": [
|
|
{
|
|
"type": "ConfigOption",
|
|
"spec": {
|
|
"name": "message",
|
|
"description": "Message to print to standard output when the plugin is enabled.",
|
|
"type": "String"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
**Factory**
|
|
|
|
Defines a channel factory that can be included in Nextflow scripts. The spec is the same as for functions.
|
|
|
|
**Function**
|
|
|
|
Defines a function that can be included in Nextflow scripts. The spec consists of a *name*, an optional *description*, a *return type*, and a list of *parameters*. Each parameter consists of a *name* and a *type*.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"type": "Function",
|
|
"spec": {
|
|
"name": "sayHello",
|
|
"description": "Say hello to the given target",
|
|
"returnType": "void",
|
|
"parameters": [
|
|
{
|
|
"name": "target",
|
|
"type": "String"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
**Operator**
|
|
|
|
Defines a channel operator that can be included in Nextflow scripts. The spec is the same as for functions.
|
|
|
|
## Rationale & discussion
|
|
|
|
Now that there is a Gradle plugin for building Nextflow plugins and a registry to publish and retrieve plugins, it is possible to generate, publish, and retrieve plugin specs in a way that is transparent to plugin developers.
|
|
|
|
Plugins specs adhere to a pre-defined [schema](https://raw.githubusercontent.com/nextflow-io/schemas/main/plugin/v1/schema.json) to ensure consistency across different versions of Nextflow. In the future, new versions of the schema can be defined as needed to support new behaviors or requirements.
|