From 6b5eb11458283aca6fdc2a0a21dbaca0a29e7796 Mon Sep 17 00:00:00 2001
From: Oskar Stark <oskarstark@googlemail.com>
Date: Thu, 23 Nov 2017 11:18:21 +0100
Subject: [PATCH] Use SymfonyStyle for command output

---
 .../ClearCache/CollectionRegionCommand.php    | 24 +++++--
 .../ClearCache/EntityRegionCommand.php        | 17 +++--
 .../Command/ClearCache/MetadataCommand.php    | 16 ++++-
 .../Command/ClearCache/QueryCommand.php       | 15 ++++-
 .../Command/ClearCache/QueryRegionCommand.php | 14 +++-
 .../Command/ClearCache/ResultCommand.php      | 15 ++++-
 .../Console/Command/ConvertMappingCommand.php | 35 ++++++----
 .../EnsureProductionSettingsCommand.php       |  9 ++-
 .../Command/GenerateEntitiesCommand.php       | 57 ++++++++--------
 .../Command/GenerateProxiesCommand.php        | 31 +++++----
 .../Command/GenerateRepositoriesCommand.php   | 56 +++++++++-------
 .../ORM/Tools/Console/Command/InfoCommand.php | 28 +++++---
 .../Command/MappingDescribeCommand.php        | 20 +++---
 .../Tools/Console/Command/RunDqlCommand.php   |  7 +-
 .../Command/SchemaTool/AbstractCommand.php    | 16 ++---
 .../Command/SchemaTool/CreateCommand.php      | 31 ++++++---
 .../Command/SchemaTool/DropCommand.php        | 46 ++++++++-----
 .../Command/SchemaTool/UpdateCommand.php      | 50 +++++++++-----
 .../Console/Command/ValidateSchemaCommand.php | 33 +++++----
 phpunit.xml.dist                              |  4 ++
 .../ClearCacheCollectionRegionCommandTest.php | 19 ++++--
 .../ClearCacheEntityRegionCommandTest.php     | 19 ++++--
 .../ClearCacheQueryRegionCommandTest.php      | 17 +++--
 .../GenerateRepositoriesCommandTest.php       | 34 ++++++++++
 .../Tools/Console/Command/InfoCommandTest.php | 67 +++++++++++++++++++
 .../Console/Command/RunDqlCommandTest.php     |  2 +-
 tests/travis/mariadb.travis.xml               |  2 +
 tests/travis/mysql.travis.xml                 |  2 +
 tests/travis/pgsql.travis.xml                 |  2 +
 tests/travis/sqlite.travis.xml                |  4 ++
 30 files changed, 496 insertions(+), 196 deletions(-)

diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/CollectionRegionCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/CollectionRegionCommand.php
index 8c73cf793..33f003a19 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/CollectionRegionCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/CollectionRegionCommand.php
@@ -26,6 +26,7 @@ use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to clear a collection cache region.
@@ -79,6 +80,8 @@ EOT
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         $em          = $this->getHelper('em')->getEntityManager();
         $ownerClass  = $input->getArgument('owner-class');
         $assoc       = $input->getArgument('association');
@@ -105,13 +108,19 @@ EOT
 
             $collectionRegion->getCache()->flushAll();
 
-            $output->writeln(sprintf('Flushing cache provider configured for <info>"%s#%s"</info>', $ownerClass, $assoc));
+            $ui->comment(
+                sprintf(
+                    'Flushing cache provider configured for <info>"%s#%s"</info>',
+                    $ownerClass,
+                    $assoc
+                )
+            );
 
             return;
         }
 
         if ($input->getOption('all')) {
-            $output->writeln('Clearing <info>all</info> second-level cache collection regions');
+            $ui->comment('Clearing <info>all</info> second-level cache collection regions');
 
             $cache->evictEntityRegions();
 
@@ -119,13 +128,20 @@ EOT
         }
 
         if ($ownerId) {
-            $output->writeln(sprintf('Clearing second-level cache entry for collection <info>"%s#%s"</info> owner entity identified by <info>"%s"</info>', $ownerClass, $assoc, $ownerId));
+            $ui->comment(
+                sprintf(
+                    'Clearing second-level cache entry for collection <info>"%s#%s"</info> owner entity identified by <info>"%s"</info>',
+                    $ownerClass,
+                    $assoc,
+                    $ownerId
+                )
+            );
             $cache->evictCollection($ownerClass, $assoc, $ownerId);
 
             return;
         }
 
-        $output->writeln(sprintf('Clearing second-level cache for collection <info>"%s#%s"</info>', $ownerClass, $assoc));
+        $ui->comment(sprintf('Clearing second-level cache for collection <info>"%s#%s"</info>', $ownerClass, $assoc));
         $cache->evictCollectionRegion($ownerClass, $assoc);
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/EntityRegionCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/EntityRegionCommand.php
index ff9e3688b..67a73093f 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/EntityRegionCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/EntityRegionCommand.php
@@ -26,6 +26,7 @@ use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to clear a entity cache region.
@@ -78,6 +79,8 @@ EOT
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         $em          = $this->getHelper('em')->getEntityManager();
         $entityClass = $input->getArgument('entity-class');
         $entityId    = $input->getArgument('entity-id');
@@ -103,13 +106,13 @@ EOT
 
             $entityRegion->getCache()->flushAll();
 
-            $output->writeln(sprintf('Flushing cache provider configured for entity named <info>"%s"</info>', $entityClass));
+            $ui->comment(sprintf('Flushing cache provider configured for entity named <info>"%s"</info>', $entityClass));
 
             return;
         }
 
         if ($input->getOption('all')) {
-            $output->writeln('Clearing <info>all</info> second-level cache entity regions');
+            $ui->comment('Clearing <info>all</info> second-level cache entity regions');
 
             $cache->evictEntityRegions();
 
@@ -117,13 +120,19 @@ EOT
         }
 
         if ($entityId) {
-            $output->writeln(sprintf('Clearing second-level cache entry for entity <info>"%s"</info> identified by <info>"%s"</info>', $entityClass, $entityId));
+            $ui->comment(
+                sprintf(
+                    'Clearing second-level cache entry for entity <info>"%s"</info> identified by <info>"%s"</info>',
+                    $entityClass,
+                    $entityId
+                )
+            );
             $cache->evictEntity($entityClass, $entityId);
 
             return;
         }
 
-        $output->writeln(sprintf('Clearing second-level cache for entity <info>"%s"</info>', $entityClass));
+        $ui->comment(sprintf('Clearing second-level cache for entity <info>"%s"</info>', $entityClass));
         $cache->evictEntityRegion($entityClass);
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php
index 64b6a0615..e6531f222 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php
@@ -25,6 +25,7 @@ use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to clear the metadata cache of the various cache drivers.
@@ -71,6 +72,8 @@ EOT
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         $em = $this->getHelper('em')->getEntityManager();
         $cacheDriver = $em->getConfiguration()->getMetadataCacheImpl();
 
@@ -86,8 +89,7 @@ EOT
             throw new \LogicException("Cannot clear XCache Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
         }
 
-
-        $output->writeln('Clearing ALL Metadata cache entries');
+        $ui->comment('Clearing <info>all</info> Metadata cache entries');
 
         $result  = $cacheDriver->deleteAll();
         $message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.';
@@ -97,6 +99,14 @@ EOT
             $message = ($result) ? 'Successfully flushed cache entries.' : $message;
         }
 
-        $output->writeln($message);
+        if ( ! $result) {
+            $ui->error($message);
+
+            return 1;
+        }
+
+        $ui->success($message);
+
+        return 0;
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php
index b4619bd7f..95bec91de 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php
@@ -25,6 +25,7 @@ use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to clear the query cache of the various cache drivers.
@@ -71,6 +72,8 @@ EOT
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         $em = $this->getHelper('em')->getEntityManager();
         $cacheDriver = $em->getConfiguration()->getQueryCacheImpl();
 
@@ -85,7 +88,7 @@ EOT
             throw new \LogicException("Cannot clear XCache Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
         }
 
-        $output->write('Clearing ALL Query cache entries' . PHP_EOL);
+        $ui->comment('Clearing <info>all</info> Query cache entries');
 
         $result  = $cacheDriver->deleteAll();
         $message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.';
@@ -95,6 +98,14 @@ EOT
             $message = ($result) ? 'Successfully flushed cache entries.' : $message;
         }
 
-        $output->write($message . PHP_EOL);
+        if ( ! $result) {
+            $ui->error($message);
+
+            return 1;
+        }
+
+        $ui->success($message);
+
+        return 0;
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryRegionCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryRegionCommand.php
index 9492958b1..f1578bc64 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryRegionCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryRegionCommand.php
@@ -26,6 +26,7 @@ use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to clear a query cache region.
@@ -77,6 +78,8 @@ EOT
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         $em    = $this->getHelper('em')->getEntityManager();
         $name  = $input->getArgument('region-name');
         $cache = $em->getCache();
@@ -102,20 +105,25 @@ EOT
 
             $queryRegion->getCache()->flushAll();
 
-            $output->writeln(sprintf('Flushing cache provider configured for second-level cache query region named <info>"%s"</info>', $name));
+            $ui->comment(
+                sprintf(
+                    'Flushing cache provider configured for second-level cache query region named <info>"%s"</info>',
+                    $name
+                )
+            );
 
             return;
         }
 
         if ($input->getOption('all')) {
-            $output->writeln('Clearing <info>all</info> second-level cache query regions');
+            $ui->comment('Clearing <info>all</info> second-level cache query regions');
 
             $cache->evictQueryRegions();
 
             return;
         }
 
-        $output->writeln(sprintf('Clearing second-level cache query region named <info>"%s"</info>', $name));
+        $ui->comment(sprintf('Clearing second-level cache query region named <info>"%s"</info>', $name));
         $cache->evictQueryRegion($name);
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php
index 6b00c1233..42ad79c50 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php
@@ -25,6 +25,7 @@ use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to clear the result cache of the various cache drivers.
@@ -71,6 +72,8 @@ EOT
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         $em = $this->getHelper('em')->getEntityManager();
         $cacheDriver = $em->getConfiguration()->getResultCacheImpl();
 
@@ -86,7 +89,7 @@ EOT
             throw new \LogicException("Cannot clear XCache Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
         }
 
-        $output->writeln('Clearing ALL Result cache entries');
+        $ui->comment('Clearing <info>all</info> Result cache entries');
 
         $result  = $cacheDriver->deleteAll();
         $message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.';
@@ -96,6 +99,14 @@ EOT
             $message = ($result) ? 'Successfully flushed cache entries.' : $message;
         }
 
-        $output->writeln($message);
+        if ( ! $result) {
+            $ui->error($message);
+
+            return 1;
+        }
+
+        $ui->success($message);
+
+        return 0;
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
index 6b9153f01..f67566411 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
@@ -29,6 +29,7 @@ use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to convert your mapping information between the various formats.
@@ -89,6 +90,8 @@ EOT
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         $em = $this->getHelper('em')->getEntityManager();
 
         if ($input->getOption('from-database') === true) {
@@ -144,20 +147,26 @@ EOT
             }
         }
 
-        if (count($metadata)) {
-            foreach ($metadata as $class) {
-                $output->writeln(sprintf('Processing entity "<info>%s</info>"', $class->name));
-            }
-
-            $exporter->setMetadata($metadata);
-            $exporter->export();
-
-            $output->writeln(PHP_EOL . sprintf(
-                'Exporting "<info>%s</info>" mapping information to "<info>%s</info>"', $toType, $destPath
-            ));
-        } else {
-            $output->writeln('No Metadata Classes to process.');
+        if (empty($metadata)) {
+            $ui->success('No Metadata Classes to process.');
+            return;
         }
+
+        foreach ($metadata as $class) {
+            $ui->text(sprintf('Processing entity "<info>%s</info>"', $class->name));
+        }
+
+        $exporter->setMetadata($metadata);
+        $exporter->export();
+
+        $ui->newLine();
+        $ui->text(
+            sprintf(
+                'Exporting "<info>%s</info>" mapping information to "<info>%s</info>"',
+                $toType,
+                $destPath
+            )
+        );
     }
 
     /**
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php
index 0a986bce1..eb0ff1756 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php
@@ -23,6 +23,7 @@ use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 use Throwable;
 
 /**
@@ -54,6 +55,8 @@ class EnsureProductionSettingsCommand extends Command
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         $em = $this->getHelper('em')->getEntityManager();
 
         try {
@@ -63,11 +66,13 @@ class EnsureProductionSettingsCommand extends Command
                 $em->getConnection()->connect();
             }
         } catch (Throwable $e) {
-            $output->writeln('<error>' . $e->getMessage() . '</error>');
+            $ui->error($e->getMessage());
 
             return 1;
         }
 
-        $output->writeln('<info>Environment is correctly configured for production.</info>');
+        $ui->success('Environment is correctly configured for production.');
+
+        return 0;
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
index 58d19774c..063cb244c 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
@@ -27,6 +27,7 @@ use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to generate entity classes and method stubs from your mapping information.
@@ -85,6 +86,8 @@ EOT
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         $em = $this->getHelper('em')->getEntityManager();
 
         $cmf = new DisconnectedClassMetadataFactory();
@@ -107,33 +110,33 @@ EOT
             );
         }
 
-        if (count($metadatas)) {
-            $entityGenerator = new EntityGenerator();
-
-            $entityGenerator->setGenerateAnnotations($input->getOption('generate-annotations'));
-            $entityGenerator->setGenerateStubMethods($input->getOption('generate-methods'));
-            $entityGenerator->setRegenerateEntityIfExists($input->getOption('regenerate-entities'));
-            $entityGenerator->setUpdateEntityIfExists($input->getOption('update-entities'));
-            $entityGenerator->setNumSpaces($input->getOption('num-spaces'));
-            $entityGenerator->setBackupExisting(!$input->getOption('no-backup'));
-
-            if (($extend = $input->getOption('extend')) !== null) {
-                $entityGenerator->setClassToExtend($extend);
-            }
-
-            foreach ($metadatas as $metadata) {
-                $output->writeln(
-                    sprintf('Processing entity "<info>%s</info>"', $metadata->name)
-                );
-            }
-
-            // Generating Entities
-            $entityGenerator->generate($metadatas, $destPath);
-
-            // Outputting information message
-            $output->writeln(PHP_EOL . sprintf('Entity classes generated to "<info>%s</INFO>"', $destPath));
-        } else {
-            $output->writeln('No Metadata Classes to process.');
+        if (empty($metadatas)) {
+            $ui->success('No Metadata Classes to process.');
+            return;
         }
+
+        $entityGenerator = new EntityGenerator();
+
+        $entityGenerator->setGenerateAnnotations($input->getOption('generate-annotations'));
+        $entityGenerator->setGenerateStubMethods($input->getOption('generate-methods'));
+        $entityGenerator->setRegenerateEntityIfExists($input->getOption('regenerate-entities'));
+        $entityGenerator->setUpdateEntityIfExists($input->getOption('update-entities'));
+        $entityGenerator->setNumSpaces($input->getOption('num-spaces'));
+        $entityGenerator->setBackupExisting(!$input->getOption('no-backup'));
+
+        if (($extend = $input->getOption('extend')) !== null) {
+            $entityGenerator->setClassToExtend($extend);
+        }
+
+        foreach ($metadatas as $metadata) {
+            $ui->text(sprintf('Processing entity "<info>%s</info>"', $metadata->name));
+        }
+
+        // Generating Entities
+        $entityGenerator->generate($metadatas, $destPath);
+
+        // Outputting information message
+        $ui->newLine();
+        $ui->success(sprintf('Entity classes generated to "%s"', $destPath));
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php
index 682b0fc4c..c792b0067 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php
@@ -26,6 +26,7 @@ use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to (re)generate the proxy classes used by doctrine.
@@ -57,6 +58,8 @@ class GenerateProxiesCommand extends Command
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         /** @var EntityManagerInterface $em */
         $em = $this->getHelper('em')->getEntityManager();
 
@@ -86,20 +89,20 @@ class GenerateProxiesCommand extends Command
             );
         }
 
-        if ( count($metadatas)) {
-            foreach ($metadatas as $metadata) {
-                $output->writeln(
-                    sprintf('Processing entity "<info>%s</info>"', $metadata->name)
-                );
-            }
-
-            // Generating Proxies
-            $em->getProxyFactory()->generateProxyClasses($metadatas, $destPath);
-
-            // Outputting information message
-            $output->writeln(PHP_EOL . sprintf('Proxy classes generated to "<info>%s</INFO>"', $destPath));
-        } else {
-            $output->writeln('No Metadata Classes to process.');
+        if (empty($metadatas)) {
+            $ui->success('No Metadata Classes to process.');
+            return;
         }
+
+        foreach ($metadatas as $metadata) {
+            $ui->text(sprintf('Processing entity "<info>%s</info>"', $metadata->name));
+        }
+
+        // Generating Proxies
+        $em->getProxyFactory()->generateProxyClasses($metadatas, $destPath);
+
+        // Outputting information message
+        $ui->newLine();
+        $ui->text(sprintf('Proxy classes generated to "<info>%s</INFO>"', $destPath));
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php
index 81081a442..787fb8bc5 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php
@@ -26,6 +26,7 @@ use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to generate repository classes for mapping information.
@@ -57,6 +58,8 @@ class GenerateRepositoriesCommand extends Command
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         $em = $this->getHelper('em')->getEntityManager();
 
         $metadatas = $em->getMetadataFactory()->getAllMetadata();
@@ -79,32 +82,33 @@ class GenerateRepositoriesCommand extends Command
             );
         }
 
-        if (count($metadatas)) {
-            $numRepositories = 0;
-            $generator = new EntityRepositoryGenerator();
-
-            $generator->setDefaultRepositoryName($repositoryName);
-
-            foreach ($metadatas as $metadata) {
-                if ($metadata->customRepositoryClassName) {
-                    $output->writeln(
-                        sprintf('Processing repository "<info>%s</info>"', $metadata->customRepositoryClassName)
-                    );
-
-                    $generator->writeEntityRepositoryClass($metadata->customRepositoryClassName, $destPath);
-
-                    $numRepositories++;
-                }
-            }
-
-            if ($numRepositories) {
-                // Outputting information message
-                $output->writeln(PHP_EOL . sprintf('Repository classes generated to "<info>%s</INFO>"', $destPath));
-            } else {
-                $output->writeln('No Repository classes were found to be processed.');
-            }
-        } else {
-            $output->writeln('No Metadata Classes to process.');
+        if (empty($metadatas)) {
+            $ui->success('No Metadata Classes to process.');
+            return;
         }
+
+        $numRepositories = 0;
+        $generator       = new EntityRepositoryGenerator();
+
+        $generator->setDefaultRepositoryName($repositoryName);
+
+        foreach ($metadatas as $metadata) {
+            if ($metadata->customRepositoryClassName) {
+                $ui->text(sprintf('Processing repository "<info>%s</info>"', $metadata->customRepositoryClassName));
+
+                $generator->writeEntityRepositoryClass($metadata->customRepositoryClassName, $destPath);
+
+                ++$numRepositories;
+            }
+        }
+
+        if ($numRepositories === 0) {
+            $ui->text('No Repository classes were found to be processed.');
+            return;
+        }
+
+        // Outputting information message
+        $ui->newLine();
+        $ui->text(sprintf('Repository classes generated to "<info>%s</INFO>"', $destPath));
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php
index 6cf73ee76..89f6c3185 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php
@@ -23,6 +23,7 @@ use Doctrine\ORM\Mapping\MappingException;
 use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Show information about mapped entities.
@@ -53,6 +54,8 @@ EOT
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         /* @var $entityManager \Doctrine\ORM\EntityManager */
         $entityManager = $this->getHelper('em')->getEntityManager();
 
@@ -61,24 +64,33 @@ EOT
                                           ->getAllClassNames();
 
         if ( ! $entityClassNames) {
-            throw new \Exception(
-                'You do not have any mapped Doctrine ORM entities according to the current configuration. '.
-                'If you have entities or mapping files you should check your mapping configuration for errors.'
+            $ui->caution(
+                [
+                    'You do not have any mapped Doctrine ORM entities according to the current configuration.',
+                    'If you have entities or mapping files you should check your mapping configuration for errors.'
+                ]
             );
+
+            return 1;
         }
 
-        $output->writeln(sprintf("Found <info>%d</info> mapped entities:", count($entityClassNames)));
+        $ui->text(sprintf("Found <info>%d</info> mapped entities:", count($entityClassNames)));
+        $ui->newLine();
 
         $failure = false;
 
         foreach ($entityClassNames as $entityClassName) {
             try {
                 $entityManager->getClassMetadata($entityClassName);
-                $output->writeln(sprintf("<info>[OK]</info>   %s", $entityClassName));
+                $ui->text(sprintf("<info>[OK]</info>   %s", $entityClassName));
             } catch (MappingException $e) {
-                $output->writeln("<error>[FAIL]</error> ".$entityClassName);
-                $output->writeln(sprintf("<comment>%s</comment>", $e->getMessage()));
-                $output->writeln('');
+                $ui->text(
+                    [
+                        sprintf("<error>[FAIL]</error> %s", $entityClassName),
+                        sprintf("<comment>%s</comment>", $e->getMessage()),
+                        ''
+                    ]
+                );
 
                 $failure = true;
             }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/MappingDescribeCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/MappingDescribeCommand.php
index f6814407e..355246731 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/MappingDescribeCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/MappingDescribeCommand.php
@@ -22,10 +22,10 @@ namespace Doctrine\ORM\Tools\Console\Command;
 use Doctrine\Common\Persistence\Mapping\MappingException;
 use Doctrine\ORM\EntityManagerInterface;
 use Symfony\Component\Console\Command\Command;
-use Symfony\Component\Console\Helper\Table;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Show information about mapped entities.
@@ -61,10 +61,12 @@ EOT
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         /* @var $entityManager \Doctrine\ORM\EntityManagerInterface */
         $entityManager = $this->getHelper('em')->getEntityManager();
 
-        $this->displayEntity($input->getArgument('entityName'), $entityManager, $output);
+        $this->displayEntity($input->getArgument('entityName'), $entityManager, $ui);
 
         return 0;
     }
@@ -74,18 +76,14 @@ EOT
      *
      * @param string                 $entityName    Full or partial entity class name
      * @param EntityManagerInterface $entityManager
-     * @param OutputInterface        $output
+     * @param SymfonyStyle           $ui
      */
-    private function displayEntity($entityName, EntityManagerInterface $entityManager, OutputInterface $output)
+    private function displayEntity($entityName, EntityManagerInterface $entityManager, SymfonyStyle $ui)
     {
-        $table = new Table($output);
-
-        $table->setHeaders(['Field', 'Value']);
-
         $metadata = $this->getClassMetadata($entityName, $entityManager);
 
-        array_map(
-            [$table, 'addRow'],
+        $ui->table(
+            ['Field', 'Value'],
             array_merge(
                 [
                     $this->formatField('Name', $metadata->name),
@@ -124,8 +122,6 @@ EOT
                 $this->formatMappings($metadata->fieldMappings)
             )
         );
-
-        $table->render();
     }
 
     /**
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php
index 14191515b..4e6b69bb4 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php
@@ -25,6 +25,7 @@ use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to execute DQL queries in a given EntityManager.
@@ -59,6 +60,8 @@ class RunDqlCommand extends Command
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         /* @var $em \Doctrine\ORM\EntityManagerInterface */
         $em = $this->getHelper('em')->getEntityManager();
 
@@ -100,12 +103,12 @@ class RunDqlCommand extends Command
         }
 
         if ($input->getOption('show-sql')) {
-            $output->writeln(Debug::dump($query->getSQL(), 2, true, false));
+            $ui->text($query->getSQL());
             return;
         }
 
         $resultSet = $query->execute([], constant($hydrationMode));
 
-        $output->writeln(Debug::dump($resultSet, $input->getOption('depth'), true, false));
+        $ui->text(Debug::dump($resultSet, $input->getOption('depth'), true, false));
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php
index ed9d754ed..21907d094 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php
@@ -23,6 +23,7 @@ use Doctrine\ORM\Tools\SchemaTool;
 use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Base class for CreateCommand, DropCommand and UpdateCommand.
@@ -44,13 +45,15 @@ abstract class AbstractCommand extends Command
      *
      * @return null|int Null or 0 if everything went fine, or an error code.
      */
-    abstract protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas);
+    abstract protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas, SymfonyStyle $ui);
 
     /**
      * {@inheritdoc}
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         $emHelper = $this->getHelper('em');
 
         /* @var $em \Doctrine\ORM\EntityManager */
@@ -58,15 +61,12 @@ abstract class AbstractCommand extends Command
 
         $metadatas = $em->getMetadataFactory()->getAllMetadata();
 
-        if ( ! empty($metadatas)) {
-            // Create SchemaTool
-            $tool = new SchemaTool($em);
-
-            return $this->executeSchemaCommand($input, $output, $tool, $metadatas);
-        } else {
-            $output->writeln('No Metadata Classes to process.');
+        if (empty($metadatas)) {
+            $ui->success('No Metadata Classes to process.');
 
             return 0;
         }
+
+        return $this->executeSchemaCommand($input, $output, new SchemaTool($em), $metadatas, $ui);
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php
index a4486469d..0c2137417 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php
@@ -23,6 +23,7 @@ use Doctrine\ORM\Tools\SchemaTool;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to create the database schema for a set of classes based on their mappings.
@@ -59,19 +60,31 @@ EOT
     /**
      * {@inheritdoc}
      */
-    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
+    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas, SymfonyStyle $ui)
     {
-        if ($input->getOption('dump-sql')) {
-            $sqls = $schemaTool->getCreateSchemaSql($metadatas);
-            $output->writeln(implode(';' . PHP_EOL, $sqls) . ';');
-        } else {
-            $output->writeln('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL);
+        $dumpSql = true === $input->getOption('dump-sql');
 
-            $output->writeln('Creating database schema...');
-            $schemaTool->createSchema($metadatas);
-            $output->writeln('Database schema created successfully!');
+        if ($dumpSql) {
+            $sqls = $schemaTool->getCreateSchemaSql($metadatas);
+            $ui->text('The following SQL statements will be executed:');
+            $ui->newLine();
+
+            foreach ($sqls as $sql) {
+                $ui->text(sprintf('    %s;', $sql));
+            }
+
+            return 0;
         }
 
+        $ui->caution('This operation should not be executed in a production environment!');
+
+        $ui->text('Creating database schema...');
+        $ui->newLine();
+
+        $schemaTool->createSchema($metadatas);
+
+        $ui->success('Database schema created successfully!');
+
         return 0;
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
index be4d55a95..3d77fc8fd 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
@@ -23,6 +23,7 @@ use Doctrine\ORM\Tools\SchemaTool;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to drop the database schema for a set of classes based on their mappings.
@@ -62,23 +63,31 @@ EOT
     /**
      * {@inheritdoc}
      */
-    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
+    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas, SymfonyStyle $ui)
     {
         $isFullDatabaseDrop = $input->getOption('full-database');
+        $dumpSql = true === $input->getOption('dump-sql');
+        $force   = true === $input->getOption('force');
 
-        if ($input->getOption('dump-sql')) {
+        if ($dumpSql) {
             if ($isFullDatabaseDrop) {
                 $sqls = $schemaTool->getDropDatabaseSQL();
             } else {
                 $sqls = $schemaTool->getDropSchemaSQL($metadatas);
             }
-            $output->writeln(implode(';' . PHP_EOL, $sqls));
+            $ui->text('The following SQL statements will be executed:');
+            $ui->newLine();
+
+            foreach ($sqls as $sql) {
+                $ui->text(sprintf('    %s;', $sql));
+            }
 
             return 0;
         }
 
-        if ($input->getOption('force')) {
-            $output->writeln('Dropping database schema...');
+        if ($force) {
+            $ui->text('Dropping database schema...');
+            $ui->newLine();
 
             if ($isFullDatabaseDrop) {
                 $schemaTool->dropDatabase();
@@ -86,12 +95,12 @@ EOT
                 $schemaTool->dropSchema($metadatas);
             }
 
-            $output->writeln('Database schema dropped successfully!');
+            $ui->success('Database schema dropped successfully!');
 
             return 0;
         }
 
-        $output->writeln('<comment>ATTENTION</comment>: This operation should not be executed in a production environment.' . PHP_EOL);
+        $ui->caution('This operation should not be executed in a production environment!');
 
         if ($isFullDatabaseDrop) {
             $sqls = $schemaTool->getDropDatabaseSQL();
@@ -99,18 +108,23 @@ EOT
             $sqls = $schemaTool->getDropSchemaSQL($metadatas);
         }
 
-        if (count($sqls)) {
-            $output->writeln(sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)));
-            $output->writeln('Please run the operation by passing one - or both - of the following options:');
+        if (empty($sqls)) {
+            $ui->success('Nothing to drop. The database is empty!');
 
-            $output->writeln(sprintf('    <info>%s --force</info> to execute the command', $this->getName()));
-            $output->writeln(sprintf('    <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()));
-
-            return 1;
+            return 0;
         }
 
-        $output->writeln('Nothing to drop. The database is empty!');
+        $ui->text(
+            [
+                sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)),
+                '',
+                'Please run the operation by passing one - or both - of the following options:',
+                '',
+                sprintf('    <info>%s --force</info> to execute the command', $this->getName()),
+                sprintf('    <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()),
+            ]
+        );
 
-        return 0;
+        return 1;
     }
 }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php
index 39df55d96..c9059775b 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php
@@ -23,6 +23,7 @@ use Doctrine\ORM\Tools\SchemaTool;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to generate the SQL needed to update the database schema to match
@@ -89,15 +90,15 @@ EOT
     /**
      * {@inheritdoc}
      */
-    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
+    protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas, SymfonyStyle $ui)
     {
         // Defining if update is complete or not (--complete not defined means $saveMode = true)
         $saveMode = ! $input->getOption('complete');
 
         $sqls = $schemaTool->getUpdateSchemaSql($metadatas, $saveMode);
 
-        if (0 === count($sqls)) {
-            $output->writeln('Nothing to update - your database is already in sync with the current entity metadata.');
+        if (empty($sqls)) {
+            $ui->success('Nothing to update - your database is already in sync with the current entity metadata.');
 
             return 0;
         }
@@ -106,35 +107,52 @@ EOT
         $force   = true === $input->getOption('force');
 
         if ($dumpSql) {
-            $output->writeln(implode(';' . PHP_EOL, $sqls) . ';');
+            $ui->text('The following SQL statements will be executed:');
+            $ui->newLine();
+
+            foreach ($sqls as $sql) {
+                $ui->text(sprintf('    %s;', $sql));
+            }
         }
 
         if ($force) {
             if ($dumpSql) {
-                $output->writeln('');
+                $ui->newLine();
             }
-            $output->writeln('Updating database schema...');
+            $ui->text('Updating database schema...');
+            $ui->newLine();
+
             $schemaTool->updateSchema($metadatas, $saveMode);
 
             $pluralization = (1 === count($sqls)) ? 'query was' : 'queries were';
 
-            $output->writeln(sprintf('Database schema updated successfully! "<info>%s</info>" %s executed', count($sqls), $pluralization));
+            $ui->text(sprintf('    <info>%s</info> %s executed', count($sqls), $pluralization));
+            $ui->success('Database schema updated successfully!');
         }
 
         if ($dumpSql || $force) {
             return 0;
         }
 
-        $output->writeln('<comment>ATTENTION</comment>: This operation should not be executed in a production environment.');
-        $output->writeln('           Use the incremental update to detect changes during development and use');
-        $output->writeln('           the SQL DDL provided to manually update your database in production.');
-        $output->writeln('');
+        $ui->caution(
+            [
+                'This operation should not be executed in a production environment!',
+                '',
+                'Use the incremental update to detect changes during development and use',
+                'the SQL DDL provided to manually update your database in production.',
+            ]
+        );
 
-        $output->writeln(sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)));
-        $output->writeln('Please run the operation by passing one - or both - of the following options:');
-
-        $output->writeln(sprintf('    <info>%s --force</info> to execute the command', $this->getName()));
-        $output->writeln(sprintf('    <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()));
+        $ui->text(
+            [
+                sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)),
+                '',
+                'Please run the operation by passing one - or both - of the following options:',
+                '',
+                sprintf('    <info>%s --force</info> to execute the command', $this->getName()),
+                sprintf('    <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()),
+            ]
+        );
 
         return 1;
     }
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php
index f9acda547..343d3b53d 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php
@@ -24,6 +24,7 @@ use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
 
 /**
  * Command to validate that the current mapping is valid.
@@ -55,35 +56,43 @@ class ValidateSchemaCommand extends Command
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $ui = new SymfonyStyle($input, $output);
+
         $em = $this->getHelper('em')->getEntityManager();
         $validator = new SchemaValidator($em);
         $exit = 0;
 
+        $ui->section('Mapping');
+
         if ($input->getOption('skip-mapping')) {
-            $output->writeln('<comment>[Mapping]  Skipped mapping check.</comment>');
+            $ui->text('<comment>[SKIPPED] The mapping was not checked.</comment>');
         } elseif ($errors = $validator->validateMapping()) {
             foreach ($errors as $className => $errorMessages) {
-                $output->writeln("<error>[Mapping]  FAIL - The entity-class '" . $className . "' mapping is invalid:</error>");
+                $ui->text(
+                    sprintf(
+                        '<error>[FAIL]</error> The entity-class <comment>%s</comment> mapping is invalid:',
+                        $className
+                    )
+                );
 
-                foreach ($errorMessages as $errorMessage) {
-                    $output->writeln('* ' . $errorMessage);
-                }
-
-                $output->writeln('');
+                $ui->listing($errorMessages);
+                $ui->newLine();
             }
 
             ++$exit;
         } else {
-            $output->writeln('<info>[Mapping]  OK - The mapping files are correct.</info>');
+            $ui->success('The mapping files are correct.');
         }
 
+        $ui->section('Database');
+
         if ($input->getOption('skip-sync')) {
-            $output->writeln('<comment>[Database] SKIPPED - The database was not checked for synchronicity.</comment>');
-        } elseif (!$validator->schemaInSyncWithMetadata()) {
-            $output->writeln('<error>[Database] FAIL - The database schema is not in sync with the current mapping file.</error>');
+            $ui->text('<comment>[SKIPPED] The database was not checked for synchronicity.</comment>');
+        } elseif ( ! $validator->schemaInSyncWithMetadata()) {
+            $ui->error('The database schema is not in sync with the current mapping file.');
             $exit += 2;
         } else {
-            $output->writeln('<info>[Database] OK - The database schema is in sync with the mapping files.</info>');
+            $ui->success('The database schema is in sync with the mapping files.');
         }
 
         return $exit;
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index c6bd89882..be88f60e7 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -19,6 +19,10 @@
          bootstrap="./tests/Doctrine/Tests/TestInit.php"
 >
 
+    <php>
+        <env name="COLUMNS" value="120"/>
+    </php>
+
     <testsuites>
         <testsuite name="Doctrine ORM Test Suite">
             <directory>./tests/Doctrine/Tests/ORM</directory>
diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheCollectionRegionCommandTest.php b/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheCollectionRegionCommandTest.php
index f9290e7be..f8c17b318 100644
--- a/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheCollectionRegionCommandTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheCollectionRegionCommandTest.php
@@ -50,7 +50,7 @@ class ClearCacheCollectionRegionCommandTest extends OrmFunctionalTestCase
             ['decorated' => false]
         );
 
-        $this->assertEquals('Clearing all second-level cache collection regions' . PHP_EOL, $tester->getDisplay());
+        self::assertContains(' // Clearing all second-level cache collection regions', $tester->getDisplay());
     }
 
     public function testClearByOwnerEntityClassName()
@@ -67,7 +67,10 @@ class ClearCacheCollectionRegionCommandTest extends OrmFunctionalTestCase
             ['decorated' => false]
         );
 
-        $this->assertEquals('Clearing second-level cache for collection "Doctrine\Tests\Models\Cache\State#cities"' . PHP_EOL, $tester->getDisplay());
+        self::assertContains(
+            ' // Clearing second-level cache for collection "Doctrine\Tests\Models\Cache\State#cities"',
+            $tester->getDisplay()
+        );
     }
 
     public function testClearCacheEntryName()
@@ -85,7 +88,12 @@ class ClearCacheCollectionRegionCommandTest extends OrmFunctionalTestCase
             ['decorated' => false]
         );
 
-        $this->assertEquals('Clearing second-level cache entry for collection "Doctrine\Tests\Models\Cache\State#cities" owner entity identified by "1"' . PHP_EOL, $tester->getDisplay());
+        self::assertContains(
+            ' // Clearing second-level cache entry for collection "Doctrine\Tests\Models\Cache\State#cities" owner',
+            $tester->getDisplay()
+        );
+
+        self::assertContains(' // entity identified by "1"', $tester->getDisplay());
     }
 
     public function testFlushRegionName()
@@ -103,6 +111,9 @@ class ClearCacheCollectionRegionCommandTest extends OrmFunctionalTestCase
             ['decorated' => false]
         );
 
-        $this->assertEquals('Flushing cache provider configured for "Doctrine\Tests\Models\Cache\State#cities"' . PHP_EOL, $tester->getDisplay());
+        self::assertContains(
+            ' // Flushing cache provider configured for "Doctrine\Tests\Models\Cache\State#cities"',
+            $tester->getDisplay()
+        );
     }
 }
diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheEntityRegionCommandTest.php b/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheEntityRegionCommandTest.php
index f0eed2595..b1d8d386b 100644
--- a/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheEntityRegionCommandTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheEntityRegionCommandTest.php
@@ -50,7 +50,7 @@ class ClearCacheEntityRegionCommandTest extends OrmFunctionalTestCase
             ['decorated' => false]
         );
 
-        $this->assertEquals('Clearing all second-level cache entity regions' . PHP_EOL, $tester->getDisplay());
+        self::assertContains(' // Clearing all second-level cache entity regions', $tester->getDisplay());
     }
 
     public function testClearByEntityClassName()
@@ -66,7 +66,10 @@ class ClearCacheEntityRegionCommandTest extends OrmFunctionalTestCase
             ['decorated' => false]
         );
 
-        $this->assertEquals('Clearing second-level cache for entity "Doctrine\Tests\Models\Cache\Country"' . PHP_EOL, $tester->getDisplay());
+        self::assertContains(
+            ' // Clearing second-level cache for entity "Doctrine\Tests\Models\Cache\Country"',
+            $tester->getDisplay()
+        );
     }
 
     public function testClearCacheEntryName()
@@ -83,7 +86,12 @@ class ClearCacheEntityRegionCommandTest extends OrmFunctionalTestCase
             ['decorated' => false]
         );
 
-        $this->assertEquals('Clearing second-level cache entry for entity "Doctrine\Tests\Models\Cache\Country" identified by "1"' . PHP_EOL, $tester->getDisplay());
+        self::assertContains(
+            ' // Clearing second-level cache entry for entity "Doctrine\Tests\Models\Cache\Country" identified by',
+            $tester->getDisplay()
+        );
+
+        self::assertContains(' // "1"', $tester->getDisplay());
     }
 
     public function testFlushRegionName()
@@ -100,6 +108,9 @@ class ClearCacheEntityRegionCommandTest extends OrmFunctionalTestCase
             ['decorated' => false]
         );
 
-        $this->assertEquals('Flushing cache provider configured for entity named "Doctrine\Tests\Models\Cache\Country"' . PHP_EOL, $tester->getDisplay());
+        self::assertContains(
+            ' // Flushing cache provider configured for entity named "Doctrine\Tests\Models\Cache\Country"',
+            $tester->getDisplay()
+        );
     }
 }
diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheQueryRegionCommandTest.php b/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheQueryRegionCommandTest.php
index f5eb4017f..1d761260c 100644
--- a/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheQueryRegionCommandTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheQueryRegionCommandTest.php
@@ -49,7 +49,7 @@ class ClearCacheQueryRegionCommandTest extends OrmFunctionalTestCase
             ['decorated' => false]
         );
 
-        $this->assertEquals('Clearing all second-level cache query regions' . PHP_EOL, $tester->getDisplay());
+        self::assertContains(' // Clearing all second-level cache query regions', $tester->getDisplay());
     }
 
     public function testClearDefaultRegionName()
@@ -65,7 +65,10 @@ class ClearCacheQueryRegionCommandTest extends OrmFunctionalTestCase
             ['decorated' => false]
         );
 
-        $this->assertEquals('Clearing second-level cache query region named "query_cache_region"' . PHP_EOL, $tester->getDisplay());
+        self::assertContains(
+            ' // Clearing second-level cache query region named "query_cache_region"',
+            $tester->getDisplay()
+        );
     }
 
     public function testClearByRegionName()
@@ -81,7 +84,10 @@ class ClearCacheQueryRegionCommandTest extends OrmFunctionalTestCase
             ['decorated' => false]
         );
 
-        $this->assertEquals('Clearing second-level cache query region named "my_region"' . PHP_EOL, $tester->getDisplay());
+        self::assertContains(
+            ' // Clearing second-level cache query region named "my_region"',
+            $tester->getDisplay()
+        );
     }
 
     public function testFlushRegionName()
@@ -98,6 +104,9 @@ class ClearCacheQueryRegionCommandTest extends OrmFunctionalTestCase
             ['decorated' => false]
         );
 
-        $this->assertEquals('Flushing cache provider configured for second-level cache query region named "my_region"' . PHP_EOL, $tester->getDisplay());
+        self::assertContains(
+            ' // Flushing cache provider configured for second-level cache query region named "my_region"',
+            $tester->getDisplay()
+        );
     }
 }
diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/GenerateRepositoriesCommandTest.php b/tests/Doctrine/Tests/ORM/Tools/Console/Command/GenerateRepositoriesCommandTest.php
index 64c81ddfe..74fbc38b2 100644
--- a/tests/Doctrine/Tests/ORM/Tools/Console/Command/GenerateRepositoriesCommandTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/Console/Command/GenerateRepositoriesCommandTest.php
@@ -136,4 +136,38 @@ class GenerateRepositoriesCommandTest extends OrmFunctionalTestCase
         );
     }
 
+    public function testNoMetadataClassesToProcess() : void
+    {
+        $configuration   = $this->createMock(Configuration::class);
+        $metadataFactory = $this->createMock(ClassMetadataFactory::class);
+        $em              = $this->createMock(EntityManagerInterface::class);
+
+        $configuration->method('getDefaultRepositoryClassName')
+                      ->willReturn('fooRepository');
+
+        $metadataFactory->method('getAllMetadata')
+                        ->willReturn([]);
+
+        $em->method('getMetadataFactory')
+           ->willReturn($metadataFactory);
+
+        $em->method('getConfiguration')
+           ->willReturn($configuration);
+
+        $application = new Application();
+        $application->setHelperSet(new HelperSet(['em' => new EntityManagerHelper($em)]));
+        $application->add(new GenerateRepositoriesCommand());
+
+        $command = $application->find('orm:generate-repositories');
+        $tester  = new CommandTester($command);
+
+        $tester->execute(
+            [
+                'command'   => $command->getName(),
+                'dest-path' => $this->path,
+            ]
+        );
+
+        self::assertContains('[OK] No Metadata Classes to process.', $tester->getDisplay());
+    }
 }
diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/InfoCommandTest.php b/tests/Doctrine/Tests/ORM/Tools/Console/Command/InfoCommandTest.php
index 240378a6a..59d5d9532 100644
--- a/tests/Doctrine/Tests/ORM/Tools/Console/Command/InfoCommandTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/Console/Command/InfoCommandTest.php
@@ -52,4 +52,71 @@ class InfoCommandTest extends OrmFunctionalTestCase
         self::assertContains(AttractionInfo::class, $this->tester->getDisplay());
         self::assertContains(City::class, $this->tester->getDisplay());
     }
+
+    public function testEmptyEntityClassNames() :  void
+    {
+        $mappingDriver = $this->createMock(MappingDriver::class);
+        $configuration = $this->createMock(Configuration::class);
+        $em            = $this->createMock(EntityManagerInterface::class);
+
+        $mappingDriver->method('getAllClassNames')
+                      ->willReturn([]);
+
+        $configuration->method('getMetadataDriverImpl')
+                      ->willReturn($mappingDriver);
+
+        $em->method('getConfiguration')
+           ->willReturn($configuration);
+
+        $application = new Application();
+        $application->setHelperSet(new HelperSet(['em' => new EntityManagerHelper($em)]));
+        $application->add(new InfoCommand());
+
+        $command = $application->find('orm:info');
+        $tester  = new CommandTester($command);
+
+        $tester->execute(['command' => $command->getName()]);
+
+        self::assertContains(
+            ' ! [CAUTION] You do not have any mapped Doctrine ORM entities according to the current configuration',
+            $tester->getDisplay()
+        );
+
+        self::assertContains(
+            ' !           If you have entities or mapping files you should check your mapping configuration for errors.',
+            $tester->getDisplay()
+        );
+    }
+
+    public function testInvalidEntityClassMetadata() : void
+    {
+        $mappingDriver = $this->createMock(MappingDriver::class);
+        $configuration = $this->createMock(Configuration::class);
+        $em            = $this->createMock(EntityManagerInterface::class);
+
+        $mappingDriver->method('getAllClassNames')
+                      ->willReturn(['InvalidEntity']);
+
+        $configuration->method('getMetadataDriverImpl')
+                      ->willReturn($mappingDriver);
+
+        $em->method('getConfiguration')
+           ->willReturn($configuration);
+
+        $em->method('getClassMetadata')
+           ->with('InvalidEntity')
+           ->willThrowException(new MappingException('exception message'));
+
+        $application = new Application();
+        $application->setHelperSet(new HelperSet(['em' => new EntityManagerHelper($em)]));
+        $application->add(new InfoCommand());
+
+        $command = $application->find('orm:info');
+        $tester  = new CommandTester($command);
+
+        $tester->execute(['command' => $command->getName()]);
+
+        self::assertContains('[FAIL] InvalidEntity', $tester->getDisplay());
+        self::assertContains('exception message', $tester->getDisplay());
+    }
 }
diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/RunDqlCommandTest.php b/tests/Doctrine/Tests/ORM/Tools/Console/Command/RunDqlCommandTest.php
index 298ff886e..552c67873 100644
--- a/tests/Doctrine/Tests/ORM/Tools/Console/Command/RunDqlCommandTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/Console/Command/RunDqlCommandTest.php
@@ -86,6 +86,6 @@ class RunDqlCommandTest extends OrmFunctionalTestCase
             )
         );
 
-        self::assertStringMatchesFormat('%Astring%sSELECT %a', $this->tester->getDisplay());
+        self::assertStringMatchesFormat('SELECT %a', trim($this->tester->getDisplay()));
     }
 }
diff --git a/tests/travis/mariadb.travis.xml b/tests/travis/mariadb.travis.xml
index 16024c4c6..d4a3fef40 100644
--- a/tests/travis/mariadb.travis.xml
+++ b/tests/travis/mariadb.travis.xml
@@ -19,6 +19,8 @@
         <var name="tmpdb_username" value="travis" />
         <var name="tmpdb_password" value="" />
         <var name="tmpdb_port" value="3306"/>
+
+        <env name="COLUMNS" value="120"/>
     </php>
 
     <testsuites>
diff --git a/tests/travis/mysql.travis.xml b/tests/travis/mysql.travis.xml
index 16024c4c6..d4a3fef40 100644
--- a/tests/travis/mysql.travis.xml
+++ b/tests/travis/mysql.travis.xml
@@ -19,6 +19,8 @@
         <var name="tmpdb_username" value="travis" />
         <var name="tmpdb_password" value="" />
         <var name="tmpdb_port" value="3306"/>
+
+        <env name="COLUMNS" value="120"/>
     </php>
 
     <testsuites>
diff --git a/tests/travis/pgsql.travis.xml b/tests/travis/pgsql.travis.xml
index 6ad430af3..d42908447 100644
--- a/tests/travis/pgsql.travis.xml
+++ b/tests/travis/pgsql.travis.xml
@@ -22,6 +22,8 @@
         <var name="tmpdb_username" value="postgres" />
         <var name="tmpdb_password" value="" />
         <var name="tmpdb_port" value="5432"/>
+
+        <env name="COLUMNS" value="120"/>
     </php>
 
     <testsuites>
diff --git a/tests/travis/sqlite.travis.xml b/tests/travis/sqlite.travis.xml
index 7894dfd2e..b783a34ff 100644
--- a/tests/travis/sqlite.travis.xml
+++ b/tests/travis/sqlite.travis.xml
@@ -6,6 +6,10 @@
          failOnRisky="true"
          bootstrap="../Doctrine/Tests/TestInit.php"
 >
+    <php>
+        <env name="COLUMNS" value="120"/>
+    </php>
+
    <testsuites>
      <testsuite name="Doctrine ORM Test Suite">
         <directory>./../Doctrine/Tests/ORM</directory>