Update to drupal 8.0.0-rc1. For more information, see https://www.drupal.org/node/2582663

This commit is contained in:
Greg Anderson 2015-10-08 11:40:12 -07:00
parent eb34d130a8
commit f32e58e4b1
8476 changed files with 211648 additions and 170042 deletions

View file

@ -0,0 +1,66 @@
<?php
/**
* This file is part of the Composer Merge plugin.
*
* Copyright (C) 2015 Bryan Davis, Wikimedia Foundation, and contributors
*
* This software may be modified and distributed under the terms of the MIT
* license. See the LICENSE file for details.
*/
namespace Wikimedia\Composer;
use Composer\IO\IOInterface;
/**
* Simple logging wrapper for Composer\IO\IOInterface
*
* @author Bryan Davis <bd808@bd808.com>
*/
class Logger
{
/**
* @var string $name
*/
protected $name;
/**
* @var IOInterface $inputOutput
*/
protected $inputOutput;
/**
* @param string $name
* @param IOInterface $io
*/
public function __construct($name, IOInterface $io)
{
$this->name = $name;
$this->inputOutput = $io;
}
/**
* Log a debug message
*
* Messages will be output at the "verbose" logging level (eg `-v` needed
* on the Composer command).
*
* @param string $message
*/
public function debug($message)
{
if ($this->inputOutput->isVerbose()) {
$message = " <info>[{$this->name}]</info> {$message}";
if (method_exists($this->inputOutput, 'writeError')) {
$this->inputOutput->writeError($message);
} else {
// @codeCoverageIgnoreStart
// Backwards compatiblity for Composer before cb336a5
$this->inputOutput->write($message);
// @codeCoverageIgnoreEnd
}
}
}
}
// vim:sw=4:ts=4:sts=4:et:

View file

@ -0,0 +1,437 @@
<?php
/**
* This file is part of the Composer Merge plugin.
*
* Copyright (C) 2015 Bryan Davis, Wikimedia Foundation, and contributors
*
* This software may be modified and distributed under the terms of the MIT
* license. See the LICENSE file for details.
*/
namespace Wikimedia\Composer\Merge;
use Wikimedia\Composer\Logger;
use Composer\Composer;
use Composer\Json\JsonFile;
use Composer\Package\BasePackage;
use Composer\Package\CompletePackage;
use Composer\Package\Loader\ArrayLoader;
use Composer\Package\RootPackage;
use Composer\Package\Version\VersionParser;
use UnexpectedValueException;
/**
* Processing for a composer.json file that will be merged into a RootPackage
*
* @author Bryan Davis <bd808@bd808.com>
*/
class ExtraPackage
{
/**
* @var Composer $composer
*/
protected $composer;
/**
* @var Logger $logger
*/
protected $logger;
/**
* @var string $path
*/
protected $path;
/**
* @var array $json
*/
protected $json;
/**
* @var CompletePackage $package
*/
protected $package;
/**
* @param string $path Path to composer.json file
* @param Composer $composer
* @param Logger $logger
*/
public function __construct($path, Composer $composer, Logger $logger)
{
$this->path = $path;
$this->composer = $composer;
$this->logger = $logger;
$this->json = $this->readPackageJson($path);
$this->package = $this->loadPackage($this->json);
}
/**
* Get list of additional packages to include if precessing recursively.
*
* @return array
*/
public function getIncludes()
{
return isset($this->json['extra']['merge-plugin']['include']) ?
$this->json['extra']['merge-plugin']['include'] : array();
}
/**
* Read the contents of a composer.json style file into an array.
*
* The package contents are fixed up to be usable to create a Package
* object by providing dummy "name" and "version" values if they have not
* been provided in the file. This is consistent with the default root
* package loading behavior of Composer.
*
* @param string $path
* @return array
*/
protected function readPackageJson($path)
{
$file = new JsonFile($path);
$json = $file->read();
if (!isset($json['name'])) {
$json['name'] = 'merge-plugin/' .
strtr($path, DIRECTORY_SEPARATOR, '-');
}
if (!isset($json['version'])) {
$json['version'] = '1.0.0';
}
return $json;
}
/**
* @return CompletePackage
*/
protected function loadPackage($json)
{
$loader = new ArrayLoader();
$package = $loader->load($json);
// @codeCoverageIgnoreStart
if (!$package instanceof CompletePackage) {
throw new UnexpectedValueException(
'Expected instance of CompletePackage, got ' .
get_class($package)
);
}
// @codeCoverageIgnoreEnd
return $package;
}
/**
* Merge this package into a RootPackage
*
* @param RootPackage $root
* @param PluginState $state
*/
public function mergeInto(RootPackage $root, PluginState $state)
{
$this->addRepositories($root);
$this->mergeRequires($root, $state);
$this->mergeDevRequires($root, $state);
$this->mergeConflicts($root);
$this->mergeReplaces($root);
$this->mergeProvides($root);
$this->mergeSuggests($root);
$this->mergeAutoload($root);
$this->mergeDevAutoload($root);
$this->mergeExtra($root, $state);
}
/**
* Add a collection of repositories described by the given configuration
* to the given package and the global repository manager.
*
* @param RootPackage $root
*/
protected function addRepositories(RootPackage $root)
{
if (!isset($this->json['repositories'])) {
return;
}
$repoManager = $this->composer->getRepositoryManager();
$newRepos = array();
foreach ($this->json['repositories'] as $repoJson) {
if (!isset($repoJson['type'])) {
continue;
}
$this->logger->debug("Adding {$repoJson['type']} repository");
$repo = $repoManager->createRepository(
$repoJson['type'],
$repoJson
);
$repoManager->addRepository($repo);
$newRepos[] = $repo;
}
$root->setRepositories(array_merge(
$newRepos,
$root->getRepositories()
));
}
/**
* Merge require into a RootPackage
*
* @param RootPackage $root
* @param PluginState $state
*/
protected function mergeRequires(RootPackage $root, PluginState $state)
{
$requires = $this->package->getRequires();
if (empty($requires)) {
return;
}
$this->mergeStabilityFlags($root, $requires);
$dups = array();
$root->setRequires($this->mergeLinks(
$root->getRequires(),
$requires,
$state->replaceDuplicateLinks(),
$dups
));
$state->addDuplicateLinks('require', $dups);
}
/**
* Merge require-dev into RootPackage
*
* @param RootPackage $root
* @param PluginState $state
*/
protected function mergeDevRequires(RootPackage $root, PluginState $state)
{
$requires = $this->package->getDevRequires();
if (empty($requires)) {
return;
}
$this->mergeStabilityFlags($root, $requires);
$dups = array();
$root->setDevRequires($this->mergeLinks(
$root->getDevRequires(),
$requires,
$state->replaceDuplicateLinks(),
$dups
));
$state->addDuplicateLinks('require-dev', $dups);
}
/**
* Merge two collections of package links and collect duplicates for
* subsequent processing.
*
* @param array $origin Primary collection
* @param array $merge Additional collection
* @param bool $replace Replace exising links?
* @param array &dups Duplicate storage
* @return array Merged collection
*/
protected function mergeLinks(
array $origin,
array $merge,
$replace,
array &$dups
) {
foreach ($merge as $name => $link) {
if (!isset($origin[$name]) || $replace) {
$this->logger->debug("Merging <comment>{$name}</comment>");
$origin[$name] = $link;
} else {
// Defer to solver.
$this->logger->debug(
"Deferring duplicate <comment>{$name}</comment>"
);
$dups[] = $link;
}
}
return $origin;
}
/**
* Merge autoload into a RootPackage
*
* @param RootPackage $root
*/
protected function mergeAutoload(RootPackage $root)
{
$autoload = $this->package->getAutoload();
if (empty($autoload)) {
return;
}
$root->setAutoload(array_merge_recursive(
$root->getAutoload(),
$this->fixRelativePaths($autoload)
));
}
/**
* Merge autoload-dev into a RootPackage
*
* @param RootPackage $root
*/
protected function mergeDevAutoload(RootPackage $root)
{
$autoload = $this->package->getDevAutoload();
if (empty($autoload)) {
return;
}
$root->setDevAutoload(array_merge_recursive(
$root->getDevAutoload(),
$this->fixRelativePaths($autoload)
));
}
/**
* Fix a collection of paths that are relative to this package to be
* relative to the base package.
*
* @param array $paths
* @return array
*/
protected function fixRelativePaths(array $paths)
{
$base = dirname($this->path);
$base = ($base === '.') ? '' : "{$base}/";
array_walk_recursive(
$paths,
function (&$path) use ($base) {
$path = "{$base}{$path}";
}
);
return $paths;
}
/**
* Extract and merge stability flags from the given collection of
* requires and merge them into a RootPackage
*
* @param RootPackage $root
* @param array $requires
*/
protected function mergeStabilityFlags(
RootPackage $root,
array $requires
) {
$flags = $root->getStabilityFlags();
foreach ($requires as $name => $link) {
$name = strtolower($name);
$version = $link->getPrettyConstraint();
$stability = VersionParser::parseStability($version);
$flags[$name] = BasePackage::$stabilities[$stability];
}
$root->setStabilityFlags($flags);
}
/**
* Merge conflicting packages into a RootPackage
*
* @param RootPackage $root
*/
protected function mergeConflicts(RootPackage $root)
{
$conflicts = $this->package->getConflicts();
if (!empty($conflicts)) {
$root->setconflicts(array_merge(
$root->getConflicts(),
$conflicts
));
}
}
/**
* Merge replaced packages into a RootPackage
*
* @param RootPackage $root
*/
protected function mergeReplaces(RootPackage $root)
{
$replaces = $this->package->getReplaces();
if (!empty($replaces)) {
$root->setReplaces(array_merge(
$root->getReplaces(),
$replaces
));
}
}
/**
* Merge provided virtual packages into a RootPackage
*
* @param RootPackage $root
*/
protected function mergeProvides(RootPackage $root)
{
$provides = $this->package->getProvides();
if (!empty($provides)) {
$root->setProvides(array_merge(
$root->getProvides(),
$provides
));
}
}
/**
* Merge suggested packages into a RootPackage
*
* @param RootPackage $root
*/
protected function mergeSuggests(RootPackage $root)
{
$suggests = $this->package->getSuggests();
if (!empty($suggests)) {
$root->setSuggests(array_merge(
$root->getSuggests(),
$suggests
));
}
}
/**
* Merge extra config into a RootPackage
*
* @param RootPackage $root
* @param PluginState $state
*/
public function mergeExtra(RootPackage $root, PluginState $state)
{
$extra = $this->package->getExtra();
unset($extra['merge-plugin']);
if (!$state->shouldMergeExtra() || empty($extra)) {
return;
}
$rootExtra = $root->getExtra();
if ($state->replaceDuplicateLinks()) {
$root->setExtra(array_merge($rootExtra, $extra));
} else {
foreach ($extra as $key => $value) {
if (isset($rootExtra[$key])) {
$this->logger->debug(
"Ignoring duplicate <comment>{$key}</comment> in ".
"<comment>{$this->path}</comment> extra config."
);
}
}
$root->setExtra(array_merge($extra, $rootExtra));
}
}
}
// vim:sw=4:ts=4:sts=4:et:

View file

@ -0,0 +1,326 @@
<?php
/**
* This file is part of the Composer Merge plugin.
*
* Copyright (C) 2015 Bryan Davis, Wikimedia Foundation, and contributors
*
* This software may be modified and distributed under the terms of the MIT
* license. See the LICENSE file for details.
*/
namespace Wikimedia\Composer\Merge;
use Composer\Composer;
use Composer\Package\AliasPackage;
use Composer\Package\RootPackage;
use UnexpectedValueException;
/**
* Mutable plugin state
*
* @author Bryan Davis <bd808@bd808.com>
*/
class PluginState
{
/**
* @var Composer $composer
*/
protected $composer;
/**
* @var array $includes
*/
protected $includes = array();
/**
* @var array $duplicateLinks
*/
protected $duplicateLinks = array();
/**
* @var bool $devMode
*/
protected $devMode = false;
/**
* @var bool $recurse
*/
protected $recurse = true;
/**
* @var bool $replace
*/
protected $replace = false;
/**
* Whether to merge the extra section.
*
* By default, the extra section is not merged and there will be many
* cases where the merge of the extra section is performed too late
* to be of use to other plugins. When enabled, merging uses one of
* two strategies - either 'first wins' or 'last wins'. When enabled,
* 'first wins' is the default behaviour. If Replace mode is activated
* then 'last wins' is used.
*
* @var bool $mergeExtra
*/
protected $mergeExtra = false;
/**
* @var bool $firstInstall
*/
protected $firstInstall = false;
/**
* @var bool $locked
*/
protected $locked = false;
/**
* @var bool $dumpAutoloader
*/
protected $dumpAutoloader = false;
/**
* @var bool $optimizeAutoloader
*/
protected $optimizeAutoloader = false;
/**
* @param Composer $composer
*/
public function __construct(Composer $composer)
{
$this->composer = $composer;
}
/**
* Load plugin settings
*/
public function loadSettings()
{
$extra = $this->getRootPackage()->getExtra();
$config = array_merge(
array(
'include' => array(),
'recurse' => true,
'replace' => false,
'merge-extra' => false,
),
isset($extra['merge-plugin']) ? $extra['merge-plugin'] : array()
);
$this->includes = (is_array($config['include'])) ?
$config['include'] : array($config['include']);
$this->recurse = (bool)$config['recurse'];
$this->replace = (bool)$config['replace'];
$this->mergeExtra = (bool)$config['merge-extra'];
}
/**
* Get the root package
*
* @return RootPackage
*/
public function getRootPackage()
{
$root = $this->composer->getPackage();
if ($root instanceof AliasPackage) {
$root = $root->getAliasOf();
}
// @codeCoverageIgnoreStart
if (!$root instanceof RootPackage) {
throw new UnexpectedValueException(
'Expected instance of RootPackage, got ' .
get_class($root)
);
}
// @codeCoverageIgnoreEnd
return $root;
}
/**
* Get list of filenames and/or glob patterns to include
*
* @return array
*/
public function getIncludes()
{
return $this->includes;
}
/**
* Set the first install flag
*
* @param bool $flag
*/
public function setFirstInstall($flag)
{
$this->firstInstall = (bool)$flag;
}
/**
* Is this the first time that the plugin has been installed?
*
* @return bool
*/
public function isFirstInstall()
{
return $this->firstInstall;
}
/**
* Set the locked flag
*
* @param bool $flag
*/
public function setLocked($flag)
{
$this->locked = (bool)$flag;
}
/**
* Was a lockfile present when the plugin was installed?
*
* @return bool
*/
public function isLocked()
{
return $this->locked;
}
/**
* Should an update be forced?
*
* @return true If packages are not locked
*/
public function forceUpdate()
{
return !$this->locked;
}
/**
* Set the devMode flag
*
* @param bool $flag
*/
public function setDevMode($flag)
{
$this->devMode = (bool)$flag;
}
/**
* Should devMode settings be processed?
*
* @return bool
*/
public function isDevMode()
{
return $this->devMode;
}
/**
* Set the dumpAutoloader flag
*
* @param bool $flag
*/
public function setDumpAutoloader($flag)
{
$this->dumpAutoloader = (bool)$flag;
}
/**
* Is the autoloader file supposed to be written out?
*
* @return bool
*/
public function shouldDumpAutoloader()
{
return $this->dumpAutoloader;
}
/**
* Set the optimizeAutoloader flag
*
* @param bool $flag
*/
public function setOptimizeAutoloader($flag)
{
$this->optimizeAutoloader = (bool)$flag;
}
/**
* Should the autoloader be optimized?
*
* @return bool
*/
public function shouldOptimizeAutoloader()
{
return $this->optimizeAutoloader;
}
/**
* Add duplicate packages
*
* @param string $type Package type
* @param array $packages
*/
public function addDuplicateLinks($type, array $packages)
{
if (!isset($this->duplicateLinks[$type])) {
$this->duplicateLinks[$type] = array();
}
$this->duplicateLinks[$type] =
array_merge($this->duplicateLinks[$type], $packages);
}
/**
* Get duplicate packages
*
* @param string $type Package type
* @return array
*/
public function getDuplicateLinks($type)
{
return isset($this->duplicateLinks[$type]) ?
$this->duplicateLinks[$type] : array();
}
/**
* Should includes be recursively processed?
*
* @return bool
*/
public function recurseIncludes()
{
return $this->recurse;
}
/**
* Should duplicate links be replaced in a 'last definition wins' order?
*
* @return bool
*/
public function replaceDuplicateLinks()
{
return $this->replace;
}
/**
* Should the extra section be merged?
*
* By default, the extra section is not merged and there will be many
* cases where the merge of the extra section is performed too late
* to be of use to other plugins. When enabled, merging uses one of
* two strategies - either 'first wins' or 'last wins'. When enabled,
* 'first wins' is the default behaviour. If Replace mode is activated
* then 'last wins' is used.
*
* @return bool
*/
public function shouldMergeExtra()
{
return $this->mergeExtra;
}
}
// vim:sw=4:ts=4:sts=4:et:

View file

@ -0,0 +1,296 @@
<?php
/**
* This file is part of the Composer Merge plugin.
*
* Copyright (C) 2015 Bryan Davis, Wikimedia Foundation, and contributors
*
* This software may be modified and distributed under the terms of the MIT
* license. See the LICENSE file for details.
*/
namespace Wikimedia\Composer;
use Wikimedia\Composer\Merge\ExtraPackage;
use Wikimedia\Composer\Merge\PluginState;
use Composer\Composer;
use Composer\DependencyResolver\Operation\InstallOperation;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\Factory;
use Composer\Installer;
use Composer\Installer\InstallerEvent;
use Composer\Installer\InstallerEvents;
use Composer\Installer\PackageEvent;
use Composer\Installer\PackageEvents;
use Composer\IO\IOInterface;
use Composer\Package\RootPackage;
use Composer\Plugin\PluginInterface;
use Composer\Script\Event;
use Composer\Script\ScriptEvents;
/**
* Composer plugin that allows merging multiple composer.json files.
*
* When installed, this plugin will look for a "merge-plugin" key in the
* composer configuration's "extra" section. The value of this setting can be
* either a single value or an array of values. Each value is treated as
* a glob() pattern identifying additional composer.json style configuration
* files to merge into the configuration for the current compser execution.
*
* The "require", "require-dev", "repositories", "extra" and "suggest" sections
* of the found configuration files will be merged into the root package
* configuration as though they were directly included in the top-level
* composer.json file.
*
* If included files specify conflicting package versions for "require" or
* "require-dev", the normal Composer dependency solver process will be used
* to attempt to resolve the conflict. Specifying the 'replace' key as true will
* change this default behaviour so that the last-defined version of a package
* will win, allowing for force-overrides of package defines.
*
* By default the "extra" section is not merged. This can be enabled with the
* 'merge-extra' key by setting it to true. In normal mode, when the same key
* is found in both the original and the imported extra section, the version
* in the original config is used and the imported version is skipped. If
* 'replace' mode is active, this behaviour changes so the imported version of
* the key is used, replacing the version in the original config.
*
*
* @code
* {
* "require": {
* "wikimedia/composer-merge-plugin": "dev-master"
* },
* "extra": {
* "merge-plugin": {
* "include": [
* "composer.local.json"
* ]
* }
* }
* }
* @endcode
*
* @author Bryan Davis <bd808@bd808.com>
*/
class MergePlugin implements PluginInterface, EventSubscriberInterface
{
/**
* Offical package name
*/
const PACKAGE_NAME = 'wikimedia/composer-merge-plugin';
/**
* @var Composer $composer
*/
protected $composer;
/**
* @var PluginState $state
*/
protected $state;
/**
* @var Logger $logger
*/
protected $logger;
/**
* Files that have already been processed
*
* @var string[] $loadedFiles
*/
protected $loadedFiles = array();
/**
* {@inheritdoc}
*/
public function activate(Composer $composer, IOInterface $io)
{
$this->composer = $composer;
$this->state = new PluginState($this->composer);
$this->logger = new Logger('merge-plugin', $io);
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(
InstallerEvents::PRE_DEPENDENCIES_SOLVING => 'onDependencySolve',
PackageEvents::POST_PACKAGE_INSTALL => 'onPostPackageInstall',
ScriptEvents::POST_INSTALL_CMD => 'onPostInstallOrUpdate',
ScriptEvents::POST_UPDATE_CMD => 'onPostInstallOrUpdate',
ScriptEvents::PRE_AUTOLOAD_DUMP => 'onInstallUpdateOrDump',
ScriptEvents::PRE_INSTALL_CMD => 'onInstallUpdateOrDump',
ScriptEvents::PRE_UPDATE_CMD => 'onInstallUpdateOrDump',
);
}
/**
* Handle an event callback for an install, update or dump command by
* checking for "merge-plugin" in the "extra" data and merging package
* contents if found.
*
* @param Event $event
*/
public function onInstallUpdateOrDump(Event $event)
{
$this->state->loadSettings();
$this->state->setDevMode($event->isDevMode());
$this->mergeIncludes($this->state->getIncludes());
if ($event->getName() === ScriptEvents::PRE_AUTOLOAD_DUMP) {
$this->state->setDumpAutoloader(true);
$flags = $event->getFlags();
if (isset($flags['optimize'])) {
$this->state->setOptimizeAutoloader($flags['optimize']);
}
}
}
/**
* Find configuration files matching the configured glob patterns and
* merge their contents with the master package.
*
* @param array $includes List of files/glob patterns
*/
protected function mergeIncludes(array $includes)
{
$root = $this->state->getRootPackage();
foreach (array_reduce(
array_map('glob', $includes),
'array_merge',
array()
) as $path) {
$this->mergeFile($root, $path);
}
}
/**
* Read a JSON file and merge its contents
*
* @param RootPackage $root
* @param string $path
*/
protected function mergeFile(RootPackage $root, $path)
{
if (isset($this->loadedFiles[$path])) {
$this->logger->debug(
"Skipping duplicate <comment>$path</comment>..."
);
return;
} else {
$this->loadedFiles[$path] = true;
}
$this->logger->debug("Loading <comment>{$path}</comment>...");
$package = new ExtraPackage($path, $this->composer, $this->logger);
$package->mergeInto($root, $this->state);
if ($this->state->recurseIncludes()) {
$this->mergeIncludes($package->getIncludes());
}
}
/**
* Handle an event callback for pre-dependency solving phase of an install
* or update by adding any duplicate package dependencies found during
* initial merge processing to the request that will be processed by the
* dependency solver.
*
* @param InstallerEvent $event
*/
public function onDependencySolve(InstallerEvent $event)
{
$request = $event->getRequest();
foreach ($this->state->getDuplicateLinks('require') as $link) {
$this->logger->debug(
"Adding dependency <comment>{$link}</comment>"
);
$request->install($link->getTarget(), $link->getConstraint());
}
if ($this->state->isDevMode()) {
foreach ($this->state->getDuplicateLinks('require-dev') as $link) {
$this->logger->debug(
"Adding dev dependency <comment>{$link}</comment>"
);
$request->install($link->getTarget(), $link->getConstraint());
}
}
}
/**
* Handle an event callback following installation of a new package by
* checking to see if the package that was installed was our plugin.
*
* @param PackageEvent $event
*/
public function onPostPackageInstall(PackageEvent $event)
{
$op = $event->getOperation();
if ($op instanceof InstallOperation) {
$package = $op->getPackage()->getName();
if ($package === self::PACKAGE_NAME) {
$this->logger->debug('composer-merge-plugin installed');
$this->state->setFirstInstall(true);
$this->state->setLocked(
$event->getComposer()->getLocker()->isLocked()
);
}
}
}
/**
* Handle an event callback following an install or update command. If our
* plugin was installed during the run then trigger an update command to
* process any merge-patterns in the current config.
*
* @param Event $event
*/
public function onPostInstallOrUpdate(Event $event)
{
// @codeCoverageIgnoreStart
if ($this->state->isFirstInstall()) {
$this->state->setFirstInstall(false);
$this->logger->debug(
'<comment>' .
'Running additional update to apply merge settings' .
'</comment>'
);
$config = $this->composer->getConfig();
$preferSource = $config->get('preferred-install') == 'source';
$preferDist = $config->get('preferred-install') == 'dist';
$installer = Installer::create(
$event->getIO(),
// Create a new Composer instance to ensure full processing of
// the merged files.
Factory::create($event->getIO(), null, false)
);
$installer->setPreferSource($preferSource);
$installer->setPreferDist($preferDist);
$installer->setDevMode($event->isDevMode());
$installer->setDumpAutoloader($this->state->shouldDumpAutoloader());
$installer->setOptimizeAutoloader(
$this->state->shouldOptimizeAutoloader()
);
if ($this->state->forceUpdate()) {
// Force update mode so that new packages are processed rather
// than just telling the user that composer.json and
// composer.lock don't match.
$installer->setUpdate(true);
}
$installer->run();
}
// @codeCoverageIgnoreEnd
}
}
// vim:sw=4:ts=4:sts=4:et: