Spec-Zone.ru › Composer

Настройка и использование пользовательских установщиков

Описание

В некоторых случаях пакет может потребовать дополнительных действий во время установки, таких как установка пакетов за пределами стандартной vendor библиотеки.

В таких случаях можно рассмотреть создание пользовательского установщика для обработки специфической логики.

Альтернатива пользовательским установщикам с Composer 2.1+

Начиная с Composer 2.1, класс Composer\InstalledVersions имеет метод getInstalledPackagesByType, который позволяет определить во время выполнения, какие плагины/модули/расширения установлены.

Сильно рекомендуется использовать этот метод вместо разработки новых пользовательских установщиков при создании нового приложения. Это преимущество заключается в том, что весь код поставщика остается в каталоге поставщика, и не требуется код пользовательского установщика.

Вызов пользовательского установщика

Предположим, что ваш проект уже имеет пользовательский установщик для определенных модулей. Тогда вызов этого установщика сводится к определению правильного типа в файле пакета.

См. следующую главу для получения инструкций по созданию пользовательских установщиков.

Каждый пользовательский установщик определяет строку типа, которую он будет распознавать. После распознавания он полностью переопределяет стандартный установщик и применяет только собственную логику.

Пример использования:

phpDocumentor использует шаблоны, которые необходимо устанавливать вне стандартной структуры каталога /vendor. Поэтому они выбрали тип phpdocumentor-template типа и создали плагин, предоставляющий пользовательский установщик для отправки этих шаблонов в соответствующий каталог.

Пример composer.json такого пакета шаблонов:

{
    "name": "phpdocumentor/template-responsive",
    "type": "phpdocumentor-template",
    "require": {
        "phpdocumentor/template-installer-plugin": "*"
    }
}

ВАЖНО: чтобы убедиться, что установщик шаблонов присутствует во время установки пакета шаблонов, пакеты шаблонов должны зависеть от пакета плагина.

Создание установщика

Пользовательский установщик определяется как класс, который реализует Composer\Installer\InstallerInterface и обычно распространяется в Composer плагине.

Базовый плагин установщика будет состоять из трех файлов:

  1. файл пакета: composer.json
  2. Класс плагина, например: My\Project\Composer\Plugin.php, содержащий класс, который реализует Composer\Plugin\PluginInterface.
  3. Класс установщика, например: My\Project\Composer\Installer.php, содержащий класс, который реализует Composer\Installer\InstallerInterface.

composer.json

Файл пакета такой же, как и любой другой файл пакета, но с следующими требованиями:

  1. атрибут типа должен быть composer-plugin.
  2. атрибут extra должен содержать элемент class, определяющий имя класса плагина (включая имя пространства). Если пакет содержит несколько плагинов, это может быть массив имен классов.

Пример:

{
    "name": "phpdocumentor/template-installer-plugin",
    "type": "composer-plugin",
    "license": "MIT",
    "autoload": {
        "psr-0": {"phpDocumentor\\Composer": "src/"}
    },
    "extra": {
        "class": "phpDocumentor\\Composer\\TemplateInstallerPlugin"
    },
    "require": {
        "composer-plugin-api": "^1.0"
    },
    "require-dev": {
        "composer/composer": "^1.3"
    }
}

В примере выше сам Composer указан в require-dev, что позволяет использовать классы Composer в вашем наборе тестов, например.

Класс плагина

Класс, определяющий Composer плагин, должен реализовывать Composer\Plugin\PluginInterface. Затем он может зарегистрировать пользовательский установщик в методе activate().

Класс может быть размещён в любом месте и иметь любое имя, при условии, что он загружается автоматически и соответствует элементу extra.class в определении пакета.

Пример:

<?php

namespace phpDocumentor\Composer;

use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;

class TemplateInstallerPlugin implements PluginInterface
{
    public function activate(Composer $composer, IOInterface $io)
    {
        $installer = new TemplateInstaller($io, $composer);
        $composer->getInstallationManager()->addInstaller($installer);
    }
}

Класс пользовательского установщика

Класс, который выполняет пользовательскую установку, должен реализовывать Composer\Installer\InstallerInterface (или расширять другой установщик, который реализует этот интерфейс). Он определяет строку типа, как она будет распознаваться пакетами, которые будут использовать этот установщик в методе supports().

ПРИМЕЧАНИЕ: тщательно выбирайте имя типа, рекомендуется использовать формат: vendor-type. Например: phpdocumentor-template.

Класс InstallerInterface определяет следующие методы (см. исходный код для точного подписи):

  • supports(), здесь вы проверяете, соответствует ли переданный тип имени, которое вы объявили для этого установщика (см. пример).
  • isInstalled(), определяет, установлен ли поддерживаемый пакет или нет.
  • install(), здесь вы можете определить действия, которые необходимо выполнить при установке.
  • update(), здесь вы определяете поведение, необходимое при вызове Composer с аргументом обновления.
  • uninstall(), здесь вы можете определить действия, которые необходимо выполнить при удалении пакета.
  • getInstallPath(), этот метод должен возвращать местоположение, куда должен быть установлен пакет, относительно расположения composer.json. Путь не должен заканчиваться слешем.

Пример:

<?php

namespace phpDocumentor\Composer;

use Composer\Package\PackageInterface;
use Composer\Installer\LibraryInstaller;

class TemplateInstaller extends LibraryInstaller
{
    /**
     * @inheritDoc
     */
    public function getInstallPath(PackageInterface $package)
    {
        $prefix = substr($package->getPrettyName(), 0, 23);
        if ('phpdocumentor/template-' !== $prefix) {
            throw new \InvalidArgumentException(
                'Unable to install template, phpdocumentor templates '
                .'should always start their package name with '
                .'"phpdocumentor/template-"'
            );
        }

        return 'data/templates/'.substr($package->getPrettyName(), 23);
    }

    /**
     * @inheritDoc
     */
    public function supports($packageType)
    {
        return 'phpdocumentor-template' === $packageType;
    }
}

Пример демонстрирует возможность расширения класса Composer\Installer\LibraryInstaller для удаления префикса (phpdocumentor/template-) и использования оставшейся части для создания совершенно другого пути установки.

Вместо установки в /vendor любой пакет, установленный с помощью этого установщика, будет помещен в папку /data/templates/<stripped name>

© Nils Adermann, Jordi Boggiano
Licensed under the MIT License.
https://getcomposer.org/doc/articles/custom-installers.md

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API