Skip to content

Commit

Permalink
[BUGFIX] Fix handling of chatty upgrade wizards (#757)
Browse files Browse the repository at this point in the history
The TYPO3 code introduced a ChattyInterface for upgrade
wizards in d336193d86e3c2b99da6d59870f56116277e89c3.

When one of those wizards tries to output something it crashes
because the output is not initialized.

This is fixed by using a BufferedOutput and attaching the collected
messages to the upgrade wizard result.
  • Loading branch information
astehlik authored and helhum committed Oct 21, 2018
1 parent 6e84412 commit fe1b754
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
8 changes: 8 additions & 0 deletions Classes/Console/Install/Upgrade/UpgradeWizardExecutor.php
Expand Up @@ -15,9 +15,11 @@
*/

use Helhum\Typo3Console\Tests\Unit\Install\Upgrade\Fixture\DummyUpgradeWizard;
use Symfony\Component\Console\Output\BufferedOutput;
use TYPO3\CMS\Core\Registry;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Install\Updates\AbstractUpdate;
use TYPO3\CMS\Install\Updates\ChattyInterface;
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;

/**
Expand Down Expand Up @@ -71,11 +73,17 @@ public function executeWizard(string $identifier, array $rawArguments = [], bool
'install'
);

$output = new BufferedOutput();
if ($upgradeWizard instanceof ChattyInterface) {
$upgradeWizard->setOutput($output);
}

$dbQueries = [];
$message = '';
if ($wizardImplementsInterface) {
$hasPerformed = $upgradeWizard->executeUpdate();
GeneralUtility::makeInstance(Registry::class)->set('installUpdate', $upgradeWizard->getIdentifier(), 1);
$message = trim($message . PHP_EOL . $output->fetch());
} else {
$hasPerformed = $upgradeWizard->performUpdate($dbQueries, $message);
}
Expand Down
26 changes: 14 additions & 12 deletions Classes/Console/Install/Upgrade/UpgradeWizardResultRenderer.php
Expand Up @@ -38,19 +38,21 @@ public function render(array $upgradeWizardResults, ConsoleOutput $output)
$output->outputLine('<warning>Skipped upgrade wizard "%s" because it was not scheduled for execution or marked as done.</warning>', [$identifier]);
} else {
$output->outputLine('<em>Successfully executed upgrade wizard "%s".</em>', [$identifier]);
if (!empty($messages = array_filter($result->getMessages()))) {
$output->outputLine('<info>Messages:</info>');
foreach ($messages as $message) {
$output->outputLine(html_entity_decode(strip_tags($message)));
}
}
if (!empty($queries = array_filter($result->getSqlQueries()))) {
$output->outputLine('<info>SQL Queries executed:</info>');
foreach ($queries as $query) {
$output->outputLine(html_entity_decode(($query)));
}
}
}
if (!empty($messages = array_filter($result->getMessages()))) {
$this->printMessages($messages, 'Messages', $output);
}
if (!empty($queries = array_filter($result->getSqlQueries()))) {
$this->printMessages($queries, 'SQL Queries executed', $output);
}
}
}

private function printMessages(array $messages, string $title, ConsoleOutput $output)
{
$output->outputLine('<info>%s:</info>', [$title]);
foreach ($messages as $message) {
$output->outputLine(html_entity_decode(strip_tags($message)));
}
}
}
22 changes: 22 additions & 0 deletions Tests/Console/Unit/Install/Upgrade/UpgradeWizardExecutorTest.php
Expand Up @@ -18,6 +18,10 @@
use Helhum\Typo3Console\Install\Upgrade\UpgradeWizardFactory;
use Helhum\Typo3Console\Tests\Unit\Install\Upgrade\Fixture\DummyUpgradeWizard;
use Nimut\TestingFramework\TestCase\UnitTestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\MethodProphecy;
use Prophecy\Prophecy\ObjectProphecy;
use Symfony\Component\Console\Output\OutputInterface;

class UpgradeWizardExecutorTest extends UnitTestCase
{
Expand All @@ -44,6 +48,7 @@ public function wizardIsCalledWhenNotDone()
{
$factoryProphecy = $this->prophesize(UpgradeWizardFactory::class);
$upgradeWizardProphecy = $this->prophesize(DummyUpgradeWizard::class);
$this->assertOutputInitForChattyWizard($upgradeWizardProphecy);
$upgradeWizardProphecy->shouldRenderWizard()->willReturn(true);
$upgradeWizardProphecy->performUpdate($queries = [], $message = '')->willReturn(true);

Expand All @@ -61,6 +66,7 @@ public function wizardIsCalledWhenNotDoneButCanStillNotPerform()
{
$factoryProphecy = $this->prophesize(UpgradeWizardFactory::class);
$upgradeWizardProphecy = $this->prophesize(DummyUpgradeWizard::class);
$this->assertOutputInitForChattyWizard($upgradeWizardProphecy);
$upgradeWizardProphecy->shouldRenderWizard()->willReturn(true);
$upgradeWizardProphecy->performUpdate($queries = [], $message = '')->willReturn(false);

Expand Down Expand Up @@ -88,4 +94,20 @@ public function wizardIsDoneButCalledWhenForced()
$result = $subject->executeWizard('Foo\\Test', [], true);
$this->assertFalse($result->hasPerformed());
}

/**
* @param DummyUpgradeWizard|ObjectProphecy $upgradeWizardProphecy
*/
private function assertOutputInitForChattyWizard(ObjectProphecy $upgradeWizardProphecy)
{
if (!interface_exists('TYPO3\\CMS\\Install\\Updates\\ChattyInterface')) {
return;
}

/** @var OutputInterface $outputInterfaceArgument */
$outputInterfaceArgument = Argument::type(OutputInterface::class);
/** @var MethodProphecy $setOutputMethod */
$setOutputMethod = $upgradeWizardProphecy->setOutput($outputInterfaceArgument);
$setOutputMethod->shouldBeCalled();
}
}

0 comments on commit fe1b754

Please sign in to comment.