Skip to content

Latest commit

 

History

History
158 lines (118 loc) · 5.6 KB

plugins.md

File metadata and controls

158 lines (118 loc) · 5.6 KB

Plugins

Plugins are one of the key component of Tuleap. The code is structured around:

  • Core (everything under src/)
  • Plugins (located under plugins/pluginname)

Plugins can provide a new service (like Backlog or Git) or underlying plumbing with almost no dedicated UI (like LDAP). A plugin can depend on another (Cardwall depends on Tracker).

Plugins rely on events to change behaviour of a given part of the code (either Core or another Plugin).

Unless there is a very good reason, all new significant work MUST be done within a plugin. It's always true for new services.

Structure

See the corresponding ADR: ADR-0030 - PHP folder structure for plugins.

A plugin folder is structured like

/plugins/template/
├── db/                       # Plugin tables and start data creation, uninstall & upgrade buckets
│   ├── mysql/
│   │   └── updates/
│   │       └── 2024/
│   │           └── 202411041134_some_db_update.php
│   ├── install.sql
│   └── uninstal.sql
├── etc/                      # Configuration
├── include/                  # Plugin code
│   └── templatePlugin.php
├── scripts/                  # Front-end applications
│   └── my_script/
│       └── package.json
├── site-content/             # Localization strings
│   ├── fr_FR/LC_MESSAGES/tuleap-template.po
│   └── pt_BR/LC_MESSAGES/tuleap-template.po
├── tests/                    # Testing
│   ├── e2e/
│   ├── integration/
│   ├── rest/
│   └── unit/
├── composer.json
└── composer.lock

As a good start, you can copy plugins/template and rename all template stuff to your plugin name.

There is a handful of files already there, the most important ones are:

  • db/install.sql definition of tables and initial data
  • db/uninstall.sql clean-up the database when the plugin is removed (purge)
  • include/templatePlugin.class.php the entry point that defines the plugin behaviour

Note: if you copy the default plugin for "mercurial" plugin for instance, you will end up with:

  • mercurial/include/mercurialPlugin.class.php

include

This directory contains all the PHP plugin code and also Mustache template files. The main file is pluginnamePlugin.php, it declares the plugin, its events, its router, etc. This directory must be under namespace Tuleap\PluginName.

pluginnamePlugin.php is the central place for plugin interaction with the rest of the application.

Let's take a look at what our basic Mercurial plugin would look like:

<?php

declare(strict_types=1);

// code must not explicitly require PHP class definitions,
// everything should pass through the autoloader (automatically
// generated by Composer)
require_once __DIR__ . '/../vendor/autoload.php';

// phpcs:ignore PSR1.Classes.ClassDeclaration.MissingNamespace,Squiz.Classes.ValidClassName.NotCamelCaps
final class mercurialPlugin extends Plugin
{
    public function __construct($id)
    {
        parent::__construct($id);
        // define the scope to either `SCOPE_SYSTEM` (for system-wide
        // features like ldap, openidconnect, etc.) or `SCOPE_PROJECT` for
        // plugins that is relevant in the context of a project (here mercurial
        // would be a service of the project)
        $this->setScope(self::SCOPE_PROJECT);
        bindtextdomain('tuleap-mercurial', __DIR__ . '/../site-content');
    }

    // boilerplate to manage plugin description
    public function getPluginInfo() : PluginInfo
    {
        if (! $this->pluginInfo) {
            $plugin_info = new PluginInfo($this);
            $plugin_info->setPluginDescriptor(new PluginDescriptor(
                dgettext('tuleap-mercurial', 'Mercurial plugin'),
                dgettext('tuleap-mercurial', 'Description of mercurial plugin'),
            ));
            $this->pluginInfo = $plugin_info;
        }
        return $this->pluginInfo;
    }

    public function getServiceShortname() : string
    {
        return 'plugin_mercurial';
    }
}

For more, see this documentation:

tests

Plugins tests are all here (except typescript unit tests). There is mainly 4 test environments:

  • e2e ⟶ Cypress tests
  • integration ⟶ testing the database and queries on it
  • rest ⟶ testing rest API
  • unit ⟶ good old PHP unit testing

For the last three environments, all those tests are written in PHP under the Tuleap\PluginName namespace. If some stubs or builders are needed, add directories Tests\Stubs and Tests\Builders inside.

scripts

This directory is a collection of front-end applications. Each application must be under its own directory. See the front-end documentation.

site-content

It contains all localization strings for the plugin. See internationalization.

db

It must contain at least install.sql and uninstall.sql. Those SQL scripts are executed when the plugin is respectively installed and uninstalled.

install.sql create needed tables and initialize plugin data. uninstall.db drop previously created table.

When database schema is modified, a new update bucket can be created inside mysql/updates. This directory contains one subdir per year. Each one containing upgrades. More details in database section 'Database structure change with ForgeUpgrade'.

etc

If the plugin needs some configuration variables hosted on the server (not a ConfigKey) (e.g. gitolite config for git plugin)