- PVSM.RU - https://www.pvsm.ru -
При развертывании [1] Magento-приложений с использованием Magento Composer столкнулись с проблемой, что различные экземпляры одного и того же приложения (девелоперский, тестовый и т.д.) должны использовать различные локальные настройки (например, параметры подключения к БД). До этого, в другом проекте, использовался подход, когда в приложении (под контролем версий) находятся шаблоны конфигурационных файлов с placeholder'ами и скрипт, замещающий placeholder'ы локальными значениями и копирующий результат в нужное место. Локальные значения хранились отдельно для каждого экземпляра по месту развертывания. Хотелось привычный подход сохранить и для нового метода развертывания. Поиск устраивающего плагина на packagist.org/ [2] завершился ненахождением, в силу чего и родилась идея сделать подобный плагин самостоятельно. При создании плагина пришлось надергать информацию из различных источников — информации [3] с сайта Composer'а по плагинам оказалось недостаточно. Что и привело к написанию этой статьи.
Основной файл плагин-пакета выглядит примерно так:
{
"name": "praxigento/composer_plugin_templates",
"type": "composer-plugin",
"require": {
"composer-plugin-api": "1.0.0"
},
"autoload": {
"psr-4": {
"\Praxigento\Composer\Plugin\Templates\": "src/"
}
},
"extra": {
"class": "\Praxigento\Composer\Plugin\Templates\"
},
"scripts": {
"test": "phpunit"
}
}
Параметр name заполняется по своему вкусу, у меня получился praxigento/composer_plugin_templates [4].
С параметрами type и require все достаточно однозначно — они должны быть [5] и быть именно такими.
Параметр autoload.psr-4 определяет настройку автозагрузки классов плагина в соответствии с PSR-4 [6] (рекомендуется использовать именно этот стандарт, т.к. PSR-0 [7] устарел 21 октября 2014 года). Согласно этой настройки наши исходники располагаются в подкаталоге ./src/.
Параметр extra.class определяет [8] основной класс плагина, который подгружается Composer'ом (или набор классов, если значение параметра — массив).
Параметр scripts.test позволяет запускать тестирование плагина из командной строки: "$ composer test".
Класс, заданный в extra.class, является точкой входа Composer'а в наш плагин. Согласно требованиям [9] Composer'а этот класс должен имплементировать интерфейс ComposerPluginPluginInterface.
namespace PraxigentoComposerPluginTemplates;
use ComposerComposer;
use ComposerIOIOInterface;
use ComposerPluginPluginInterface;
class Main implements PluginInterface {
protected $composer;
protected $io;
public function activate(Composer $composer, IOInterface $io) {
$this->composer = $composer;
$this->io = $io;
}
}
Конфигурация параметров работы плагина осуществляется через секцию extra в composer.json основного пакета, в котором используется наш плагин.
{
"name": "vendor/package",
"type": "project",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/praxigento/composer_plugin_templates"
}
],
"require": {
"praxigento/composer_plugin_templates": "*"
},
"extra": {
"praxigento_templates_config": "./instance_cfg.json"
}
}
Плагин должен взять настройки для своей работы из файла, который задается через параметр extra.praxigento_templates_config конфигурационного файла проекта (composer.json). Мы это делаем при инициализации плагина:
class Main implements PluginInterface, EventSubscriberInterface {
public function activate(Composer $composer, IOInterface $io) {
$this->composer = $composer;
$this->io = $io;
$extra = $composer->getPackage()->getExtra();
$configFile = $extra['praxigento_templates_config'];
}
}
В своей реализации плагина мы хотели, чтобы он реагировал на события [10]:
Для этого наша точка входа должна также имплементировать интерфейс EventSubscriberInterface [11], подписаться на соответствующие события и зарегистрировать обработчки:
class Main implements PluginInterface, EventSubscriberInterface {
public static function getSubscribedEvents() {
$result = array(
ScriptEvents::POST_INSTALL_CMD => array(
array( 'onPostInstallCmd', 0 )
),
ScriptEvents::POST_UPDATE_CMD => array(
array( 'onPostUpdateCmd', 0 )
),
);
return $result;
}
public function onPostInstallCmd(CommandEvent $event) {
}
public function onPostUpdateCmd(CommandEvent $event) {
}
}
Подключение PhpUnit осуществляется в composer.json:
{
"require-dev": {
"phpunit/phpunit": "4.4.*"
}
}
Настройки юнит-тестирования — в файле phpunit.xml.dist:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="phpunit.bootstrap.php"
>
<testsuites>
<testsuite name="Plugin Test Suite">
<directory suffix="_Test.php">./src/</directory>
</testsuite>
</testsuites>
</phpunit>
Загрузка autoloader'а, совместимого с PSR-4 (без него не запускаются тесты через IDE PhpStorm) в скрипте phpunit.bootstrap.php:
require __DIR__.'/vendor/autoload.php';
Запуск тестов через composer:
$ composer test
Данной информации должно хватить для создания собственного плагина для Composer'а. Спасибо всем, кто дочитал до конца.
Автор: flancer
Источник [12]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/79287
Ссылки в тексте:
[1] развертывании: http://habrahabr.ru/post/246703/
[2] packagist.org/: https://packagist.org/
[3] информации: https://getcomposer.org/doc/articles/plugins.md
[4] praxigento/composer_plugin_templates: https://github.com/praxigento/composer_plugin_templates
[5] должны быть: https://getcomposer.org/doc/articles/plugins.md#plugin-package
[6] PSR-4: http://www.php-fig.org/psr/psr-4/ru/
[7] PSR-0: http://www.php-fig.org/psr/psr-0/ru/
[8] определяет: https://getcomposer.org/doc/articles/custom-installers.md#composer-json
[9] требованиям: https://getcomposer.org/doc/articles/plugins.md#plugin-class
[10] события: https://getcomposer.org/doc/articles/scripts.md#event-names
[11] EventSubscriberInterface: https://getcomposer.org/doc/articles/plugins.md#event-handler
[12] Источник: http://habrahabr.ru/post/247519/
Нажмите здесь для печати.