From 13aede85bf4719f3c5117d38e0e15ed7de6ccb66 Mon Sep 17 00:00:00 2001 From: Matthew Grasmick Date: Fri, 9 Sep 2016 09:57:48 -0400 Subject: [PATCH] Fixes #341 #284: Automating alias installation and template updates. --- composer.json | 10 ++- composer.lock | 8 +- phing/tasks/blt.xml | 2 +- src/Composer/BltPlugin.php | 174 +++++++++++++++++++++++++++++++++++++ 4 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 src/Composer/BltPlugin.php diff --git a/composer.json b/composer.json index d95c9f13a6..189fc64a84 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,7 @@ { "name": "acquia/blt", "description": "BLT", + "type": "composer-plugin", "license": "GPL-2.0", "require": { "drupal/console": "~1", @@ -11,7 +12,9 @@ "symfony/yaml": "~2.7", "drupal/coder": "~8.2", "symfony/console": "~2", - "symfony/twig-bridge": "~2" + "symfony/twig-bridge": "~2", + "php": ">=5.6", + "composer-plugin-api": "^1.0.0" }, "autoload": { "psr-4": { @@ -19,6 +22,9 @@ "Acquia\\Blt\\Tests\\": "tests/phpunit/src/" } }, + "extra": { + "class": "Acquia\\Blt\\Composer\\BltPlugin" + }, "bin": [ "bin/blt", "bin/blt-console" @@ -29,6 +35,6 @@ "minimum-stability": "beta", "prefer-stable": true, "scripts": { - "install-blt-alias": "./blt.sh install-alias" + "install-blt-alias": "yes | ./blt.sh install-alias" } } diff --git a/composer.lock b/composer.lock index b34bc01b34..c89f63f241 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "2423149def7560fd1866a80e77d9eee7", - "content-hash": "dc83ee695cd8276b601fb2ff5867f4fb", + "hash": "3a94d7da4921e599a2ee5da0682b114a", + "content-hash": "775b7572a266f8ee2789b56d25fa35b4", "packages": [ { "name": "alchemy/zippy", @@ -3627,6 +3627,8 @@ }, "prefer-stable": true, "prefer-lowest": false, - "platform": [], + "platform": { + "php": ">=5.6" + }, "platform-dev": [] } diff --git a/phing/tasks/blt.xml b/phing/tasks/blt.xml index 63d54f72a2..8c91f11671 100644 --- a/phing/tasks/blt.xml +++ b/phing/tasks/blt.xml @@ -28,7 +28,7 @@ - + Some of your customized files may have been modified. diff --git a/src/Composer/BltPlugin.php b/src/Composer/BltPlugin.php new file mode 100644 index 0000000000..4e6ffd5e48 --- /dev/null +++ b/src/Composer/BltPlugin.php @@ -0,0 +1,174 @@ +composer = $composer; + $this->io = $io; + $this->eventDispatcher = $composer->getEventDispatcher(); + $this->executor = new ProcessExecutor($this->io); + } + + /** + * Returns an array of event names this subscriber wants to listen to. + */ + public static function getSubscribedEvents() { + return array( + PackageEvents::POST_PACKAGE_INSTALL => "onPostPackageEvent", + PackageEvents::POST_PACKAGE_UPDATE => "onPostPackageEvent", + ScriptEvents::POST_UPDATE_CMD => 'onPostCmdEvent', + ScriptEvents::POST_INSTALL_CMD => 'onPostCmdEvent', + ); + } + + /** + * Marks blt to be processed after an install or update command. + * + * @param \Composer\Installer\PackageEvent $event + */ + public function onPostPackageEvent(\Composer\Installer\PackageEvent $event){ + $package = $this->getBltPackage($event->getOperation()); + if ($package) { + // By explicitly setting the blt package, the onPostCmdEvent() will + // process the update automatically. + $this->bltPackage = $package; + } + } + + /** + * Post install command event to execute the blt update. + * + * @param \Composer\Script\Event $event + */ + public function onPostCmdEvent(\Composer\Script\Event $event) { + // Only install the scaffolding if acquia/blt was installed, + if (isset($this->bltPackage)) { + $this->executeBltUpdate(); + } + } + + /** + * @param $operation + * @return mixed + */ + protected function getBltPackage($operation) { + if ($operation instanceof InstallOperation) { + $package = $operation->getPackage(); + } + elseif ($operation instanceof UpdateOperation) { + $package = $operation->getTargetPackage(); + } + if (isset($package) && $package instanceof PackageInterface && $package->getName() == 'acquia/blt') { + return $package; + } + return NULL; + } + + protected function executeBltUpdate() { + // @todo cd into project root from getVendorPath? + $this->io->write('Updating BLT templated files'); + $this->executeCommand('blt update'); + $this->io->write('BLT template files were updated'); + $this->io->write('This may have modified your composer.json and require a subsequent `composer update`'); + } + + /** + * Get the path to the 'vendor' directory. + * + * @return string + */ + public function getVendorPath() { + $config = $this->composer->getConfig(); + $filesystem = new Filesystem(); + $filesystem->ensureDirectoryExists($config->get('vendor-dir')); + $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir'))); + return $vendorPath; + } + + /** + * Executes a shell command with escaping. + * + * @param string $cmd + * @return bool + */ + protected function executeCommand($cmd) { + // Shell-escape all arguments except the command. + $args = func_get_args(); + foreach ($args as $index => $arg) { + if ($index !== 0) { + $args[$index] = escapeshellarg($arg); + } + } + // And replace the arguments. + $command = call_user_func_array('sprintf', $args); + $output = ''; + if ($this->io->isVerbose()) { + $this->io->write(' > ' . $command . ''); + $io = $this->io; + $output = function ($type, $buffer) use ($io) { + if ($type == Process::ERR) { + $io->write('' . $buffer . ''); + } + else { + // @todo Figure out how to preserve color! + $io->write($buffer); + } + }; + } + return ($this->executor->execute($command, $output) == 0); + } + +}