Статьи

Автоматизация сборки с помощью скриптов Composer

После введения Александра Конье в управление зависимостями с помощью Composer вы теперь знаете, что Composer — это средство разрешения внешних зависимостей проекта и ограничений версий. Но это все, что он делает? В этой статье я покажу вам, как Composer также можно использовать в качестве базового средства автоматизации сборки.

Композитор Сценарии

Любой инструмент автоматизации сборки, достойный всяческих усилий, должен обеспечивать возможность написания сценариев для целого ряда автоматизированных задач — от сборки, упаковки и запуска наборов тестов до развертывания в промежуточных и производственных системах. Например, Phing основан на Ant и позволяет вам определять такие задачи в файлах сборки XML.

Композитор отличается в этом отношении тем, что он не делает никаких предположений относительно того, что представляют собой эти задачи или они вообще должны быть выполнены. Вместо этого Composer выставляет свои перехватчики событий до и после установки / обновления / удаления во время выполнения, которые можно вызвать с помощью «сценариев», почти так же, как Pyrus предоставляет возможность определять пользовательские команды в package.xml через --plugin для команд install , upgrade и uninstall .

Свойство scripts определено в корневом объекте JSON файла composer.json вашего корневого пакета. Вы можете определить любое количество статических методов PHP (которые должны автоматически загружаться механизмом автозагрузки Composer), исполняемые файлы командной строки или их комбинацию.

Любой пользовательский код или специфичные для пакета команды, определенные этими сценариями, затем вызываются в процессе выполнения Composer. Предостережение заключается в том, что выполняются только те сценарии, которые определены в корневом пакете composer.json . Composer не будет выполнять сценарии, указанные в зависимости от корневого пакета.

В процессе выполнения Composer генерируются следующие события:

  • pre-install-cmd — происходит перед выполнением команды установки
  • post-install-cmd — происходит после выполнения команды установки
  • pre-update-cmd — происходит перед выполнением команды обновления
  • post-update-cmd — происходит после выполнения команды обновления
  • pre-package-install — происходит перед установкой пакета
  • post-package-install — происходит после установки пакета
  • pre-package-update — происходит до обновления пакета
  • post-package-update — происходит после обновления пакета
  • pre-package-uninstall — происходит перед удалением пакета
  • post-package-uninstall — происходит после удаления пакета

Это довольно очевидно, и я думаю, вы согласитесь, что красота заключается в ее простоте. Но чтобы проиллюстрировать это, вот пример корневого пакета composer.json :

 { "name": "MyProject", "description": "An example to demonstrate the use of Composer scripts", "version": "1.0.0", "require": { "php": ">=5.3", "ext-xsl": "*", "ext-imap": "*", "ext-gd": "*" }, "autoload": { "psr-0": { "MyProject": "src/" } }, "scripts": { "pre-install-cmd": "MyProject\Installer::preInstall", "post-install-cmd": [ "MyProject\Installer::postInstall" ], "post-package-install": [ "MyProject\Installer::postPackageInstall", "phpunit -c /tests", "./bin/install.sh" ] } } 

Я определил некоторые сценарии для событий pre-install-cmd , post-install-cmd и post-package-install . Как видите, мы можем определить любую комбинацию статических методов PHP и исполняемых файлов командной строки. В случае post-package-install event он также выполняет некоторые модульные тесты и пользовательский сценарий установки.

Вот как выглядит наш пример скрипта:

 <?php namespace MyProject; use ComposerScriptEvent; class Installer { public static function preInstall(Event $event) { // provides access to the current ComposerIOConsoleIO // stream for terminal input/output $io = $event->getIO(); if ($io->askConfirmation("Are you sure you want to proceed? ", false)) { // ok, continue on to composer install return true; } // exit composer and terminate installation process exit; } public static function postInstall(Event $event) { // provides access to the current Composer instance $composer = $event->getComposer(); // run any post install tasks here } public static function postPackageInstall(Event $event) { $installedPackage = $event->getComposer()->getPackage(); // any tasks to run after the package is installed? } } 

Когда каждое из этих событий запускается, внутренний обработчик событий ComposerScriptEvent передает объект ComposerScriptEvent в качестве первого (и единственного) аргумента каждому из обратных вызовов. Объект Event предоставляет обратный вызов следующим получателям для других объектов Composer:

  • getComposer() — возвращает текущий экземпляр ComposerComposer
  • getName() — возвращает имя запускаемого события
  • getIO() — возвращает текущий поток ввода / вывода, который реализует ComposerIOIOInterface для чтения / записи в консоль

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

Хотя эта, казалось бы, элементарная реализация может показаться не такой «мощной», как определения Phing, ее простота противоречит ее невероятной гибкости. Он использует ваши существующие знания в области PHP, и, проявив немного творческого подхода и воображения, вы можете использовать средство разрешения зависимостей Composer и собственный PHP-сценарий для создания довольно сложных задач сборки и развертывания. Вы можете даже интегрировать это в Jenkins для непрерывной интеграции.

Резюме

В этой статье я представил простейший пример использования сценариев Composer для автоматизации сборки. Эти задачи могут быть настолько простыми или сложными, насколько вам нужно, поскольку они используют ваши существующие инвестиции в знания PHP. И, надеюсь, эта статья вдохновит вас на использование Composer не только для управления зависимостями. Для получения дополнительной информации о том, как использовать сценарии Composer, см. Getcomposer.org/doc/articles/scripts.md .

Изображение через Fotolia