Skip to content

Commit

Permalink
Updating DoctrineMigrationsBundle for Doctrine Migrations 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
jwage committed Jun 4, 2018
1 parent 04109e6 commit 8c2f5bc
Show file tree
Hide file tree
Showing 21 changed files with 5,074 additions and 190 deletions.
3 changes: 2 additions & 1 deletion .gitignore
@@ -1,2 +1,3 @@
composer.lock
/vendor/
/.phpcs-cache

30 changes: 30 additions & 0 deletions .scrutinizer.yml
@@ -0,0 +1,30 @@
build:
nodes:
analysis:
environment:
php:
version: 7.1
cache:
disabled: false
directories:
- ~/.composer/cache
project_setup:
override: true
tests:
override:
- php-scrutinizer-run
- phpcs-run
dependencies:
override:
- composer install --ignore-platform-reqs --no-interaction

tools:
external_code_coverage:
timeout: 600

build_failure_conditions:
- 'elements.rating(<= C).new.exists' # No new classes/methods with a rating of C or worse allowed
- 'issues.label("coding-style").new.exists' # No new coding style issues allowed
- 'issues.severity(>= MAJOR).new.exists' # New issues of major or higher severity
- 'project.metric_change("scrutinizer.test_coverage", < 0)' # Code Coverage decreased from previous inspection

43 changes: 27 additions & 16 deletions .travis.yml
Expand Up @@ -3,42 +3,53 @@ sudo: false
language: php

php:
- 5.4
- 5.5
- 5.6
- 7.0
- 7.1
- 7.2
- nightly

cache:
directories:
- $HOME/.composer/cache

before_install:
- mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{,.disabled} || echo "xdebug not available"
- composer self-update
- travis_retry composer self-update

install: travis_retry composer update --prefer-dist
install:
- rm composer.lock
- travis_retry composer update --prefer-dist

script:
- ./vendor/bin/phpunit -v
- ./vendor/bin/phpunit

jobs:
allow_failures:
- php: nightly

include:
- stage: Test
env: DEPENDENCIES=low
install: travis_retry composer update --prefer-dist --prefer-lowest
install:
- rm composer.lock
- travis_retry composer update --prefer-dist --prefer-lowest

- stage: Coverage
- stage: Test
env: COVERAGE
before_script:
- mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{.disabled,}
- if [[ ! $(php -m | grep -si xdebug) ]]; then echo "xdebug required for coverage"; exit 1; fi
script:
- ./vendor/bin/phpunit -v --coverage-clover ./build/logs/clover.xml
- ./vendor/bin/phpunit --coverage-clover clover.xml
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml
- php ocular.phar code-coverage:upload --format=php-clover clover.xml

allow_failures:
- php: nightly
- stage: Code Quality
env: CODING_STANDARDS
install: travis_retry composer install --prefer-dist
script: ./vendor/bin/phpcs

cache:
directories:
- $HOME/.composer/cache
- stage: Code Quality
env: STATIC_ANALYSIS
install: travis_retry composer install --prefer-dist
script: vendor/bin/phpstan analyse -l 7 -c phpstan.neon lib
86 changes: 61 additions & 25 deletions Command/DoctrineCommand.php
@@ -1,66 +1,101 @@
<?php

declare(strict_types=1);

namespace Doctrine\Bundle\MigrationsBundle\Command;

use Doctrine\Bundle\DoctrineBundle\Command\DoctrineCommand as BaseCommand;
use Doctrine\DBAL\Migrations\Configuration\AbstractFileConfiguration;
use Doctrine\DBAL\Migrations\Configuration\Configuration;
use Doctrine\Migrations\Configuration\AbstractFileConfiguration;
use Doctrine\Migrations\Configuration\Configuration;
use Doctrine\Migrations\Version\Version;
use ErrorException;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use function error_get_last;
use function is_dir;
use function method_exists;
use function mkdir;
use function preg_match;
use function sprintf;
use function str_replace;

/**
* Base class for Doctrine console commands to extend from.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
abstract class DoctrineCommand extends BaseCommand
{
public static function configureMigrations(ContainerInterface $container, Configuration $configuration)
public static function configureMigrations(ContainerInterface $container, Configuration $configuration) : void
{
if (!$configuration->getMigrationsDirectory()) {
$dir = $configuration->getMigrationsDirectory();

if (empty($dir)) {
$dir = $container->getParameter('doctrine_migrations.dir_name');
if (!is_dir($dir) && !@mkdir($dir, 0777, true) && !is_dir($dir)) {

if (! is_dir($dir) && ! @mkdir($dir, 0777, true) && ! is_dir($dir)) {
$error = error_get_last();
throw new \ErrorException($error['message']);

throw new ErrorException(sprintf(
'Failed to create directory %s with message %s',
$dir,
$error['message']
));
}

$configuration->setMigrationsDirectory($dir);
} else {
$dir = $configuration->getMigrationsDirectory();
// class Kernel has method getKernelParameters with some of the important path parameters
$pathPlaceholderArray = array('kernel.root_dir', 'kernel.cache_dir', 'kernel.logs_dir');
$pathPlaceholderArray = ['kernel.root_dir', 'kernel.cache_dir', 'kernel.logs_dir'];

foreach ($pathPlaceholderArray as $pathPlaceholder) {
if ($container->hasParameter($pathPlaceholder) && preg_match('/\%'.$pathPlaceholder.'\%/', $dir)) {
$dir = str_replace('%'.$pathPlaceholder.'%', $container->getParameter($pathPlaceholder), $dir);
if (! $container->hasParameter($pathPlaceholder) || ! preg_match('/\%' . $pathPlaceholder . '\%/', $dir)) {
continue;
}

$dir = str_replace('%' . $pathPlaceholder . '%', $container->getParameter($pathPlaceholder), $dir);
}
if (!is_dir($dir) && !@mkdir($dir, 0777, true) && !is_dir($dir)) {

if (! is_dir($dir) && ! @mkdir($dir, 0777, true) && ! is_dir($dir)) {
$error = error_get_last();
throw new \ErrorException($error['message']);

throw new ErrorException(sprintf(
'Failed to create directory %s with message %s',
$dir,
$error['message']
));
}

$configuration->setMigrationsDirectory($dir);
}
if (!$configuration->getMigrationsNamespace()) {

if (empty($configuration->getMigrationsNamespace())) {
$configuration->setMigrationsNamespace($container->getParameter('doctrine_migrations.namespace'));
}
if (!$configuration->getName()) {

if (empty($configuration->getName())) {
$configuration->setName($container->getParameter('doctrine_migrations.name'));
}

// For backward compatibility, need use a table from parameters for overwrite the default configuration
if (!($configuration instanceof AbstractFileConfiguration) || !$configuration->getMigrationsTableName()) {
if (! ($configuration instanceof AbstractFileConfiguration) || empty($configuration->getMigrationsTableName())) {
$configuration->setMigrationsTableName($container->getParameter('doctrine_migrations.table_name'));
}

// Migrations is not register from configuration loader
if (!($configuration instanceof AbstractFileConfiguration)) {
$configuration->registerMigrationsFromDirectory($configuration->getMigrationsDirectory());
if (! ($configuration instanceof AbstractFileConfiguration)) {
$migrationsDirectory = $configuration->getMigrationsDirectory();

if ($migrationsDirectory !== null) {
$configuration->registerMigrationsFromDirectory($migrationsDirectory);
}
}

if (method_exists($configuration, 'getCustomTemplate') && !$configuration->getCustomTemplate()) {
if (method_exists($configuration, 'getCustomTemplate') && empty($configuration->getCustomTemplate())) {
$configuration->setCustomTemplate($container->getParameter('doctrine_migrations.custom_template'));
}

$organizeMigrations = $container->getParameter('doctrine_migrations.organize_migrations');

switch ($organizeMigrations) {
case Configuration::VERSIONS_ORGANIZATION_BY_YEAR:
$configuration->setMigrationsAreOrganizedByYear(true);
Expand All @@ -81,18 +116,19 @@ public static function configureMigrations(ContainerInterface $container, Config
}

/**
* @param ContainerInterface $container
* @param array $versions
* @param Version[] $versions
*
* Injects the container to migrations aware of it
*/
private static function injectContainerToMigrations(ContainerInterface $container, array $versions)
private static function injectContainerToMigrations(ContainerInterface $container, array $versions) : void
{
foreach ($versions as $version) {
$migration = $version->getMigration();
if ($migration instanceof ContainerAwareInterface) {
$migration->setContainer($container);
if (! ($migration instanceof ContainerAwareInterface)) {
continue;
}

$migration->setContainer($container);
}
}
}
48 changes: 34 additions & 14 deletions Command/Helper/DoctrineCommandHelper.php
@@ -1,43 +1,63 @@
<?php

declare(strict_types=1);

namespace Doctrine\Bundle\MigrationsBundle\Command\Helper;

use Doctrine\Bundle\DoctrineBundle\Command\Proxy\DoctrineCommandHelper as BaseDoctrineCommandHelper;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Doctrine\DBAL\Sharding\PoolingShardConnection;
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
use LogicException;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\InputInterface;
use function count;
use function sprintf;

/**
* Provides some helper and convenience methods to configure doctrine commands in the context of bundles
* and multiple connections/entity managers.
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
abstract class DoctrineCommandHelper extends BaseDoctrineCommandHelper
{
public static function setApplicationHelper(Application $application, InputInterface $input)
public static function setApplicationHelper(Application $application, InputInterface $input) : void
{
$container = $application->getKernel()->getContainer();
$doctrine = $container->get('doctrine');

/** @var Registry $doctrine */
$doctrine = $container->get('doctrine');

$managerNames = $doctrine->getManagerNames();

if ($input->getOption('db') || empty($managerNames)) {
if ($input->getOption('db') !== null || count($managerNames) === 0) {
self::setApplicationConnection($application, $input->getOption('db'));
} else {
self::setApplicationEntityManager($application, $input->getOption('em'));
}

if ($input->getOption('shard')) {
$connection = $application->getHelperSet()->get('db')->getConnection();
if (!$connection instanceof PoolingShardConnection) {
if (empty($managerNames)) {
throw new \LogicException(sprintf("Connection '%s' must implement shards configuration.", $input->getOption('db')));
} else {
throw new \LogicException(sprintf("Connection of EntityManager '%s' must implement shards configuration.", $input->getOption('em')));
}
if ($input->getOption('shard') === null) {
return;
}

/** @var ConnectionHelper $dbHelper */
$dbHelper = $application->getHelperSet()->get('db');

$connection = $dbHelper->getConnection();

if (! $connection instanceof PoolingShardConnection) {
if (count($managerNames) === 0) {
throw new LogicException(sprintf(
"Connection '%s' must implement shards configuration.",
$input->getOption('db')
));
}

$connection->connect($input->getOption('shard'));
throw new LogicException(sprintf(
"Connection of EntityManager '%s' must implement shards configuration.",
$input->getOption('em')
));
}

$connection->connect($input->getOption('shard'));
}
}
19 changes: 11 additions & 8 deletions Command/MigrationsDiffDoctrineCommand.php
@@ -1,9 +1,11 @@
<?php

declare(strict_types=1);

namespace Doctrine\Bundle\MigrationsBundle\Command;

use Doctrine\DBAL\Migrations\Tools\Console\Command\DiffCommand;
use Doctrine\Migrations\Tools\Console\Command\DiffCommand;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -12,12 +14,10 @@
* Command for generate migration classes by comparing your current database schema
* to your mapping information.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
class MigrationsDiffDoctrineCommand extends DiffCommand
{
protected function configure()
protected function configure() : void
{
parent::configure();

Expand All @@ -29,13 +29,16 @@ protected function configure()
;
}

public function execute(InputInterface $input, OutputInterface $output)
public function initialize(InputInterface $input, OutputInterface $output) : void
{
Helper\DoctrineCommandHelper::setApplicationHelper($this->getApplication(), $input);
/** @var Application $application */
$application = $this->getApplication();

Helper\DoctrineCommandHelper::setApplicationHelper($application, $input);

$configuration = $this->getMigrationConfiguration($input, $output);
DoctrineCommand::configureMigrations($this->getApplication()->getKernel()->getContainer(), $configuration);
DoctrineCommand::configureMigrations($application->getKernel()->getContainer(), $configuration);

return parent::execute($input, $output);
parent::initialize($input, $output);
}
}

0 comments on commit 8c2f5bc

Please sign in to comment.