Skip to content

Commit 885f001

Browse files
committed
Fixing wrapping of doctrine:migrations:diff command
This more selectively overrides output so that some output - including asking a confirmation question - can be shown to the user.
1 parent e278901 commit 885f001

File tree

4 files changed

+199
-4
lines changed

4 files changed

+199
-4
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MakerBundle\Console;
13+
14+
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
15+
use Symfony\Component\Console\Output\OutputInterface;
16+
17+
class MigrationDiffFilteredOutput implements OutputInterface
18+
{
19+
private $output;
20+
private $buffer = '';
21+
private $previousLineWasRemoved = false;
22+
23+
public function __construct(OutputInterface $output)
24+
{
25+
$this->output = $output;
26+
}
27+
28+
public function write($messages, bool $newline = false, int $options = 0)
29+
{
30+
$messages = $this->filterMessages($messages, $newline);
31+
32+
$this->output->write($messages, $newline, $options);
33+
}
34+
35+
public function writeln($messages, int $options = 0)
36+
{
37+
$messages = $this->filterMessages($messages, true);
38+
39+
$this->output->writeln($messages, $options);
40+
}
41+
42+
public function setVerbosity(int $level)
43+
{
44+
$this->output->setVerbosity($level);
45+
}
46+
47+
public function getVerbosity()
48+
{
49+
return $this->output->getVerbosity();
50+
}
51+
52+
public function isQuiet()
53+
{
54+
return $this->output->isQuiet();
55+
}
56+
57+
public function isVerbose()
58+
{
59+
return $this->output->isVerbose();
60+
}
61+
62+
public function isVeryVerbose()
63+
{
64+
return $this->output->isVeryVerbose();
65+
}
66+
67+
public function isDebug()
68+
{
69+
return $this->output->isDebug();
70+
}
71+
72+
public function setDecorated(bool $decorated)
73+
{
74+
$this->output->setDecorated($decorated);
75+
}
76+
77+
public function isDecorated()
78+
{
79+
return $this->output->isDecorated();
80+
}
81+
82+
public function setFormatter(OutputFormatterInterface $formatter)
83+
{
84+
$this->output->setFormatter($formatter);
85+
}
86+
87+
public function getFormatter()
88+
{
89+
return $this->output->getFormatter();
90+
}
91+
92+
public function fetch(): string
93+
{
94+
return $this->buffer;
95+
}
96+
97+
private function filterMessages($messages, bool $newLine)
98+
{
99+
if (!is_iterable($messages)) {
100+
$messages = [$messages];
101+
}
102+
103+
$hiddenPhrases = [
104+
'Generated new migration class',
105+
'To run just this migration',
106+
'To revert the migration you',
107+
];
108+
109+
foreach ($messages as $key => $message) {
110+
$this->buffer .= $message;
111+
112+
if ($newLine) {
113+
$this->buffer .= PHP_EOL;
114+
}
115+
116+
if ($this->previousLineWasRemoved && !trim($message)) {
117+
// hide a blank line after a filtered line
118+
unset($messages[$key]);
119+
$this->previousLineWasRemoved = false;
120+
121+
continue;
122+
}
123+
124+
$this->previousLineWasRemoved = false;
125+
foreach ($hiddenPhrases as $hiddenPhrase) {
126+
if (false !== strpos($message, $hiddenPhrase)) {
127+
$this->previousLineWasRemoved = true;
128+
unset($messages[$key]);
129+
130+
break;
131+
}
132+
}
133+
}
134+
135+
return array_values($messages);
136+
}
137+
}

src/ConsoleStyle.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Bundle\MakerBundle;
1313

14+
use Symfony\Component\Console\Input\InputInterface;
15+
use Symfony\Component\Console\Output\OutputInterface;
1416
use Symfony\Component\Console\Style\SymfonyStyle;
1517

1618
/**
@@ -19,6 +21,15 @@
1921
*/
2022
final class ConsoleStyle extends SymfonyStyle
2123
{
24+
private $output;
25+
26+
public function __construct(InputInterface $input, OutputInterface $output)
27+
{
28+
$this->output = $output;
29+
30+
parent::__construct($input, $output);
31+
}
32+
2233
public function success($message)
2334
{
2435
$this->writeln('<fg=green;options=bold,underscore>OK</> '.$message);
@@ -28,4 +39,9 @@ public function comment($message)
2839
{
2940
$this->text($message);
3041
}
42+
43+
public function getOutput(): OutputInterface
44+
{
45+
return $this->output;
46+
}
3147
}

src/Maker/MakeMigration.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle;
1515
use Symfony\Bundle\MakerBundle\ApplicationAwareMakerInterface;
16+
use Symfony\Bundle\MakerBundle\Console\MigrationDiffFilteredOutput;
1617
use Symfony\Bundle\MakerBundle\ConsoleStyle;
1718
use Symfony\Bundle\MakerBundle\DependencyBuilder;
1819
use Symfony\Bundle\MakerBundle\Generator;
@@ -22,7 +23,6 @@
2223
use Symfony\Component\Console\Input\ArgvInput;
2324
use Symfony\Component\Console\Input\InputInterface;
2425
use Symfony\Component\Console\Input\InputOption;
25-
use Symfony\Component\Console\Output\BufferedOutput;
2626

2727
/**
2828
* @author Amrouche Hamza <[email protected]>
@@ -78,9 +78,16 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
7878

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

81-
$commandOutput = new BufferedOutput($io->getVerbosity());
81+
$commandOutput = new MigrationDiffFilteredOutput($io->getOutput());
8282
try {
83-
$generateMigrationCommand->run(new ArgvInput($options), $commandOutput);
83+
$returnCode = $generateMigrationCommand->run(new ArgvInput($options), $commandOutput);
84+
85+
// non-zero code would ideally mean the internal command has already printed an errror
86+
// this happens if you "decline" generating a migration when you already
87+
// have some available
88+
if (0 !== $returnCode) {
89+
return $returnCode;
90+
}
8491

8592
$migrationOutput = $commandOutput->fetch();
8693

tests/Maker/MakeMigrationTest.php

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,49 @@ public function getTestDetails()
5151
$this->getMakerInstance(MakeMigration::class),
5252
[/* no input */])
5353
->setFixtureFilesPath(__DIR__.'/../fixtures/MakeMigration')
54-
->configureDatabase()
5554
// sync the database, so no changes are needed
55+
->configureDatabase()
5656
->addExtraDependencies('doctrine/orm:@stable')
5757
->assert(function (string $output, string $directory) {
5858
$this->assertNotContains('Success', $output);
5959

6060
$this->assertStringContainsString('No database changes were detected', $output);
6161
}),
6262
];
63+
64+
yield 'migration_with_previous_migration_question' => [MakerTestDetails::createTest(
65+
$this->getMakerInstance(MakeMigration::class),
66+
[
67+
// confirm migration
68+
'y',
69+
])
70+
->setFixtureFilesPath(__DIR__.'/../fixtures/MakeMigration')
71+
->configureDatabase(false)
72+
->addExtraDependencies('doctrine/orm:@stable')
73+
// generate a migration first
74+
->addPreMakeCommand('php bin/console make:migration')
75+
->assert(function (string $output, string $directory) {
76+
$this->assertStringContainsString('You have 1 available migrations to execute', $output);
77+
$this->assertStringContainsString('Success', $output);
78+
$this->assertCount(14, explode("\n", $output), 'Asserting that very specific output is shown - some should be hidden');
79+
var_dump($output);
80+
}),
81+
];
82+
83+
yield 'migration_with_previous_migration_decline_question' => [MakerTestDetails::createTest(
84+
$this->getMakerInstance(MakeMigration::class),
85+
[
86+
// no to confirm
87+
'n',
88+
])
89+
->setFixtureFilesPath(__DIR__.'/../fixtures/MakeMigration')
90+
->configureDatabase(false)
91+
->addExtraDependencies('doctrine/orm:@stable')
92+
// generate a migration first
93+
->addPreMakeCommand('php bin/console make:migration')
94+
->assert(function (string $output, string $directory) {
95+
$this->assertStringNotContainsString('Success', $output);
96+
}),
97+
];
6398
}
6499
}

0 commit comments

Comments
 (0)