ConsoleRunner.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. declare(strict_types=1);
  3. namespace Doctrine\Migrations\Tools\Console;
  4. use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
  5. use Doctrine\Migrations\Configuration\Connection\ExistingConnection;
  6. use Doctrine\Migrations\Configuration\EntityManager\ExistingEntityManager;
  7. use Doctrine\Migrations\Configuration\Migration\ConfigurationFileWithFallback;
  8. use Doctrine\Migrations\DependencyFactory;
  9. use Doctrine\Migrations\Tools\Console\Command\CurrentCommand;
  10. use Doctrine\Migrations\Tools\Console\Command\DiffCommand;
  11. use Doctrine\Migrations\Tools\Console\Command\DoctrineCommand;
  12. use Doctrine\Migrations\Tools\Console\Command\DumpSchemaCommand;
  13. use Doctrine\Migrations\Tools\Console\Command\ExecuteCommand;
  14. use Doctrine\Migrations\Tools\Console\Command\GenerateCommand;
  15. use Doctrine\Migrations\Tools\Console\Command\LatestCommand;
  16. use Doctrine\Migrations\Tools\Console\Command\ListCommand;
  17. use Doctrine\Migrations\Tools\Console\Command\MigrateCommand;
  18. use Doctrine\Migrations\Tools\Console\Command\RollupCommand;
  19. use Doctrine\Migrations\Tools\Console\Command\StatusCommand;
  20. use Doctrine\Migrations\Tools\Console\Command\SyncMetadataCommand;
  21. use Doctrine\Migrations\Tools\Console\Command\UpToDateCommand;
  22. use Doctrine\Migrations\Tools\Console\Command\VersionCommand;
  23. use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
  24. use PackageVersions\Versions;
  25. use RuntimeException;
  26. use Symfony\Component\Console\Application;
  27. use Symfony\Component\Console\Helper\HelperSet;
  28. use function file_exists;
  29. use function getcwd;
  30. use function is_readable;
  31. use function sprintf;
  32. use const DIRECTORY_SEPARATOR;
  33. /**
  34. * The ConsoleRunner class is used to create the Symfony Console application for the Doctrine Migrations console.
  35. *
  36. * @internal
  37. *
  38. * @see bin/doctrine-migrations.php
  39. */
  40. class ConsoleRunner
  41. {
  42. public static function findDependencyFactory(): ?DependencyFactory
  43. {
  44. // Support for using the Doctrine ORM convention of providing a `cli-config.php` file.
  45. $configurationDirectories = [
  46. getcwd(),
  47. getcwd() . DIRECTORY_SEPARATOR . 'config',
  48. ];
  49. $configurationFile = null;
  50. foreach ($configurationDirectories as $configurationDirectory) {
  51. $configurationFilePath = $configurationDirectory . DIRECTORY_SEPARATOR . 'cli-config.php';
  52. if (! file_exists($configurationFilePath)) {
  53. continue;
  54. }
  55. $configurationFile = $configurationFilePath;
  56. break;
  57. }
  58. $dependencyFactory = null;
  59. if ($configurationFile !== null) {
  60. if (! is_readable($configurationFile)) {
  61. throw new RuntimeException(sprintf(
  62. 'Configuration file "%s" cannot be read.',
  63. $configurationFile
  64. ));
  65. }
  66. $dependencyFactory = require $configurationFile;
  67. $dependencyFactory = self::checkLegacyConfiguration($dependencyFactory, $configurationFile);
  68. }
  69. if ($dependencyFactory !== null && ! ($dependencyFactory instanceof DependencyFactory)) {
  70. throw new RuntimeException(sprintf(
  71. 'Configuration file "%s" must return an instance of "%s"',
  72. $configurationFile,
  73. DependencyFactory::class
  74. ));
  75. }
  76. return $dependencyFactory;
  77. }
  78. /** @param DoctrineCommand[] $commands */
  79. public static function run(array $commands = [], ?DependencyFactory $dependencyFactory = null): void
  80. {
  81. $cli = static::createApplication($commands, $dependencyFactory);
  82. $cli->run();
  83. }
  84. /** @param DoctrineCommand[] $commands */
  85. public static function createApplication(array $commands = [], ?DependencyFactory $dependencyFactory = null): Application
  86. {
  87. $cli = new Application('Doctrine Migrations', Versions::getVersion('doctrine/migrations'));
  88. $cli->setCatchExceptions(true);
  89. self::addCommands($cli, $dependencyFactory);
  90. $cli->addCommands($commands);
  91. return $cli;
  92. }
  93. public static function addCommands(Application $cli, ?DependencyFactory $dependencyFactory = null): void
  94. {
  95. $cli->addCommands([
  96. new CurrentCommand($dependencyFactory),
  97. new DumpSchemaCommand($dependencyFactory),
  98. new ExecuteCommand($dependencyFactory),
  99. new GenerateCommand($dependencyFactory),
  100. new LatestCommand($dependencyFactory),
  101. new MigrateCommand($dependencyFactory),
  102. new RollupCommand($dependencyFactory),
  103. new StatusCommand($dependencyFactory),
  104. new VersionCommand($dependencyFactory),
  105. new UpToDateCommand($dependencyFactory),
  106. new SyncMetadataCommand($dependencyFactory),
  107. new ListCommand($dependencyFactory),
  108. ]);
  109. if ($dependencyFactory === null || ! $dependencyFactory->hasSchemaProvider()) {
  110. return;
  111. }
  112. $cli->add(new DiffCommand($dependencyFactory));
  113. }
  114. /**
  115. * @param mixed|HelperSet $dependencyFactory
  116. *
  117. * @return mixed|DependencyFactory
  118. */
  119. private static function checkLegacyConfiguration($dependencyFactory, string $configurationFile)
  120. {
  121. if (! ($dependencyFactory instanceof HelperSet)) {
  122. return $dependencyFactory;
  123. }
  124. $configurations = new ConfigurationFileWithFallback();
  125. if ($dependencyFactory->has('em') && $dependencyFactory->get('em') instanceof EntityManagerHelper) {
  126. return DependencyFactory::fromEntityManager(
  127. $configurations,
  128. new ExistingEntityManager($dependencyFactory->get('em')->getEntityManager())
  129. );
  130. }
  131. if ($dependencyFactory->has('db') && $dependencyFactory->get('db') instanceof ConnectionHelper) {
  132. return DependencyFactory::fromConnection(
  133. $configurations,
  134. new ExistingConnection($dependencyFactory->get('db')->getConnection())
  135. );
  136. }
  137. throw new RuntimeException(sprintf(
  138. 'Configuration HelperSet returned by "%s" does not have a valid "em" or the "db" helper.',
  139. $configurationFile
  140. ));
  141. }
  142. }