Настройка и использование программ индивидуальной установки Composer
Настройка и использование настраиваемых установщиков Composer
  1. Описание задачи пользовательской установки в Composer
  2. Альтернатива пользовательским установщикам в Composer 2.1+
  3. Вызов пользовательского инсталлятора в Composer
  4. Создание инсталлятора для Composer
    1. composer.json
    2. Класс Plugin
    3. Класс пользовательского установщика для Composer


Описание задачи пользовательской установки в Composer

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

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

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

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

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

Вызов пользовательского инсталлятора для Composer

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

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

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

В качестве примера можно привести следующий случай:

phpDocumentor имеет шаблоны (Templates), которые должны быть установлены вне стандартной структуры папок /vendor. В связи с этим разработчики решили принять тип (type) phpdocumentor-template и создать плагин, предоставляющий Custom Installer для передачи этих шаблонов в нужную папку.

Пример composer.json такого пакета шаблонов выглядит следующим образом:

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

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

Создание инсталлятора в Composer

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

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

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

composer.json

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

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

Пример:

{
    "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"
    }
}

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

Класс Plugin

Класс, определяющий плагин Composer, должен реализовать интерфейс Composer\Plugin\PluginInterface. Затем он может зарегистрировать Custom Installer в своем методе 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

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

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

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

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

Пример:

<?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(
                'Невозможно установить шаблон, '
                .'шаблоны phpdocumentor всегда должны начинать свое имя пакета с '
                .'"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>.

Перевод с английского официальной документации Composer:
https://getcomposer.org/doc/articles/custom-installers.md

Заберите ссылку на статью к себе, чтобы потом легко её найти!
Раз уж досюда дочитали, то может может есть желание рассказать об этом месте своим друзьям, знакомым и просто мимо проходящим?
Не надо себя сдерживать! ;)

Старт! Горячий старт на просторы интернета
Старт! Горячий старт на просторы интернета
Старт! Меню