Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"symfony/http-kernel": "^3.4|^4.0|^5.0"
},
"require-dev": {
"composer/semver": "^3.0@dev",
"doctrine/doctrine-bundle": "^1.8|^2.0",
"doctrine/orm": "^2.3",
"friendsofphp/php-cs-fixer": "^2.8",
Expand Down
137 changes: 137 additions & 0 deletions src/Console/MigrationDiffFilteredOutput.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php

/*
* This file is part of the Symfony MakerBundle package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\MakerBundle\Console;

use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Output\OutputInterface;

class MigrationDiffFilteredOutput implements OutputInterface
{
private $output;
private $buffer = '';
private $previousLineWasRemoved = false;

public function __construct(OutputInterface $output)
{
$this->output = $output;
}

public function write($messages, $newline = false, $options = 0)
{
$messages = $this->filterMessages($messages, $newline);

$this->output->write($messages, $newline, $options);
}

public function writeln($messages, $options = 0)
{
$messages = $this->filterMessages($messages, true);

$this->output->writeln($messages, $options);
}

public function setVerbosity($level)
{
$this->output->setVerbosity($level);
}

public function getVerbosity()
{
return $this->output->getVerbosity();
}

public function isQuiet()
{
return $this->output->isQuiet();
}

public function isVerbose()
{
return $this->output->isVerbose();
}

public function isVeryVerbose()
{
return $this->output->isVeryVerbose();
}

public function isDebug()
{
return $this->output->isDebug();
}

public function setDecorated($decorated)
{
$this->output->setDecorated($decorated);
}

public function isDecorated()
{
return $this->output->isDecorated();
}

public function setFormatter(OutputFormatterInterface $formatter)
{
$this->output->setFormatter($formatter);
}

public function getFormatter()
{
return $this->output->getFormatter();
}

public function fetch(): string
{
return $this->buffer;
}

private function filterMessages($messages, bool $newLine)
{
if (!is_iterable($messages)) {
$messages = [$messages];
}

$hiddenPhrases = [
'Generated new migration class',
'To run just this migration',
'To revert the migration you',
];

foreach ($messages as $key => $message) {
$this->buffer .= $message;

if ($newLine) {
$this->buffer .= PHP_EOL;
}

if ($this->previousLineWasRemoved && !trim($message)) {
// hide a blank line after a filtered line
unset($messages[$key]);
$this->previousLineWasRemoved = false;

continue;
}

$this->previousLineWasRemoved = false;
foreach ($hiddenPhrases as $hiddenPhrase) {
if (false !== strpos($message, $hiddenPhrase)) {
$this->previousLineWasRemoved = true;
unset($messages[$key]);

break;
}
}
}

return array_values($messages);
}
}
16 changes: 16 additions & 0 deletions src/ConsoleStyle.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace Symfony\Bundle\MakerBundle;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
Expand All @@ -19,6 +21,15 @@
*/
final class ConsoleStyle extends SymfonyStyle
{
private $output;

public function __construct(InputInterface $input, OutputInterface $output)
{
$this->output = $output;

parent::__construct($input, $output);
}

public function success($message)
{
$this->writeln('<fg=green;options=bold,underscore>OK</> '.$message);
Expand All @@ -28,4 +39,9 @@ public function comment($message)
{
$this->text($message);
}

public function getOutput(): OutputInterface
{
return $this->output;
}
}
35 changes: 26 additions & 9 deletions src/Maker/MakeMigration.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@

namespace Symfony\Bundle\MakerBundle\Maker;

use Doctrine\Bundle\MigrationsBundle\Command\MigrationsDiffDoctrineCommand;
use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle;
use Symfony\Bundle\MakerBundle\ApplicationAwareMakerInterface;
use Symfony\Bundle\MakerBundle\Console\MigrationDiffFilteredOutput;
use Symfony\Bundle\MakerBundle\ConsoleStyle;
use Symfony\Bundle\MakerBundle\DependencyBuilder;
use Symfony\Bundle\MakerBundle\Generator;
Expand All @@ -22,7 +24,6 @@
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\BufferedOutput;

/**
* @author Amrouche Hamza <[email protected]>
Expand Down Expand Up @@ -56,31 +57,47 @@ public function configureCommand(Command $command, InputConfiguration $inputConf
{
$command
->setDescription('Creates a new migration based on database changes')
->addOption('db', null, InputOption::VALUE_REQUIRED, 'The database connection name')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager name')
->addOption('shard', null, InputOption::VALUE_REQUIRED, 'The shard connection name')
->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeMigration.txt'))
;

if (class_exists(MigrationsDiffDoctrineCommand::class)) {
// support for DoctrineMigrationsBundle 2.x
$command
->addOption('db', null, InputOption::VALUE_REQUIRED, 'The database connection name')
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager name')
->addOption('shard', null, InputOption::VALUE_REQUIRED, 'The shard connection name')
;
}
}

public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator)
{
$options = ['doctrine:migrations:diff'];
if (null !== $input->getOption('db')) {

// DoctrineMigrationsBundle 2.x support
if ($input->hasOption('db') && null !== $input->getOption('db')) {
$options[] = '--db='.$input->getOption('db');
}
if (null !== $input->getOption('em')) {
if ($input->hasOption('em') && null !== $input->getOption('em')) {
$options[] = '--em='.$input->getOption('em');
}
if (null !== $input->getOption('shard')) {
if ($input->hasOption('shard') && null !== $input->getOption('shard')) {
$options[] = '--shard='.$input->getOption('shard');
}
// end 2.x support

$generateMigrationCommand = $this->application->find('doctrine:migrations:diff');

$commandOutput = new BufferedOutput($io->getVerbosity());
$commandOutput = new MigrationDiffFilteredOutput($io->getOutput());
try {
$generateMigrationCommand->run(new ArgvInput($options), $commandOutput);
$returnCode = $generateMigrationCommand->run(new ArgvInput($options), $commandOutput);

// non-zero code would ideally mean the internal command has already printed an errror
// this happens if you "decline" generating a migration when you already
// have some available
if (0 !== $returnCode) {
return $returnCode;
}

$migrationOutput = $commandOutput->fetch();

Expand Down
33 changes: 33 additions & 0 deletions src/Test/MakerTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Bundle\MakerBundle\Test;

use Composer\Semver\Semver;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\MakerBundle\MakerInterface;
use Symfony\Bundle\MakerBundle\Str;
Expand Down Expand Up @@ -40,6 +41,10 @@ protected function executeMakerCommand(MakerTestDetails $testDetails)
// prepare environment to test
$testEnv->prepare();

if (!$this->hasRequiredDependencyVersions($testDetails, $testEnv)) {
$this->markTestSkipped('Some dependencies versions are too low');
}

// run tests
$makerTestProcess = $testEnv->runMaker();
$files = $testEnv->getGeneratedFilesFromOutputText();
Expand Down Expand Up @@ -95,4 +100,32 @@ protected function getMakerInstance(string $makerClass): MakerInterface

return $this->kernel->getContainer()->get($serviceId);
}

private function hasRequiredDependencyVersions(MakerTestDetails $testDetails, MakerTestEnvironment $testEnv): bool
{
if (empty($testDetails->getRequiredPackageVersions())) {
return true;
}

$installedPackages = json_decode($testEnv->readFile('vendor/composer/installed.json'), true);
$packageVersions = [];
foreach ($installedPackages as $installedPackage) {
$packageVersions[$installedPackage['name']] = $installedPackage['version_normalized'];
}

foreach ($testDetails->getRequiredPackageVersions() as $requiredPackageData) {
$name = $requiredPackageData['name'];
$versionConstraint = $requiredPackageData['version_constraint'];

if (!isset($packageVersions[$name])) {
throw new \Exception(sprintf('Package "%s" is required in the test project at version "%s" but it is not installed?', $name, $versionConstraint));
}

if (!Semver::satisfies($packageVersions[$name], $versionConstraint)) {
return false;
}
}

return true;
}
}
14 changes: 14 additions & 0 deletions src/Test/MakerTestDetails.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ final class MakerTestDetails

private $requiredPhpVersion;

private $requiredPackageVersions = [];

private $guardAuthenticators = [];

/**
Expand Down Expand Up @@ -216,6 +218,13 @@ public function setRequiredPhpVersion(int $version): self
return $this;
}

public function addRequiredPackageVersion(string $packageName, string $versionConstraint): self
{
$this->requiredPackageVersions[] = ['name' => $packageName, 'version_constraint' => $versionConstraint];

return $this;
}

public function setGuardAuthenticator(string $firewallName, string $id): self
{
$this->guardAuthenticators[$firewallName] = $id;
Expand Down Expand Up @@ -316,4 +325,9 @@ public function getGuardAuthenticators(): array
{
return $this->guardAuthenticators;
}

public function getRequiredPackageVersions(): array
{
return $this->requiredPackageVersions;
}
}
9 changes: 9 additions & 0 deletions src/Test/MakerTestEnvironment.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ public function getPath(): string
return $this->path;
}

public function readFile(string $path): string
{
if (!file_exists($this->path.'/'.$path)) {
throw new \InvalidArgumentException(sprintf('Cannot find file "%s"', $path));
}

return file_get_contents($this->path.'/'.$path);
}

private function changeRootNamespaceIfNeeded()
{
if ('App' === ($rootNamespace = $this->testDetails->getRootNamespace())) {
Expand Down
Loading