diff --git a/lib/Doctrine/Migrations/MigrationRepository.php b/lib/Doctrine/Migrations/MigrationRepository.php index c98faa7c4d..31a4292794 100644 --- a/lib/Doctrine/Migrations/MigrationRepository.php +++ b/lib/Doctrine/Migrations/MigrationRepository.php @@ -355,7 +355,7 @@ public function getRelativeVersion(string $version, int $delta) : ?string return null; } - $relativeVersion = ((int) $offset) + $delta; + $relativeVersion = $offset + $delta; if (! isset($versions[$relativeVersion])) { // Unknown version or delta out of bounds. diff --git a/lib/Doctrine/Migrations/Tools/Console/Command/AbstractCommand.php b/lib/Doctrine/Migrations/Tools/Console/Command/AbstractCommand.php index a42ab0fad5..77b599755d 100644 --- a/lib/Doctrine/Migrations/Tools/Console/Command/AbstractCommand.php +++ b/lib/Doctrine/Migrations/Tools/Console/Command/AbstractCommand.php @@ -17,6 +17,7 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ConfirmationQuestion; +use function assert; use function escapeshellarg; use function proc_open; use function str_repeat; @@ -111,8 +112,10 @@ protected function getMigrationConfiguration( ) : Configuration { if ($this->migrationConfiguration === null) { if ($this->hasConfigurationHelper()) { + $helperSet = $this->getHelperSet(); + assert($helperSet !== null); /** @var ConfigurationHelper $configHelper */ - $configHelper = $this->getHelperSet()->get('configuration'); + $configHelper = $helperSet->get('configuration'); } else { $configHelper = new ConfigurationHelper( $this->getConnection($input), @@ -187,8 +190,10 @@ private function hasConfigurationHelper() : bool private function getConnection(InputInterface $input) : Connection { if ($this->connection === null) { + $helperSet = $this->getHelperSet(); + assert($helperSet !== null); $this->connection = (new ConnectionLoader($this->configuration)) - ->getConnection($input, $this->getHelperSet()); + ->getConnection($input, $helperSet); } return $this->connection; diff --git a/lib/Doctrine/Migrations/Tools/Console/Command/DiffCommand.php b/lib/Doctrine/Migrations/Tools/Console/Command/DiffCommand.php index 7f5b4121de..f8bd0d6e82 100644 --- a/lib/Doctrine/Migrations/Tools/Console/Command/DiffCommand.php +++ b/lib/Doctrine/Migrations/Tools/Console/Command/DiffCommand.php @@ -14,8 +14,12 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use const FILTER_VALIDATE_BOOLEAN; +use function assert; use function class_exists; use function filter_var; +use function is_array; +use function is_bool; +use function is_string; use function sprintf; /** @@ -111,11 +115,14 @@ public function execute( OutputInterface $output ) : ?int { $filterExpression = $input->getOption('filter-expression') ?? null; - $formatted = (bool) $input->getOption('formatted'); - $lineLength = (int) $input->getOption('line-length'); - $allowEmptyDiff = (bool) $input->getOption('allow-empty-diff'); - $checkDbPlatform = filter_var($input->getOption('check-database-platform'), FILTER_VALIDATE_BOOLEAN); - $fromEmptySchema = (bool) $input->getOption('from-empty-schema'); + assert(is_string($filterExpression) || $filterExpression === null); + $formatted = (bool) $input->getOption('formatted'); + $lineLength = $input->getOption('line-length'); + assert(! is_array($lineLength) && ! is_bool($lineLength)); + $lineLength = (int) $lineLength; + $allowEmptyDiff = (bool) $input->getOption('allow-empty-diff'); + $checkDbPlatform = filter_var($input->getOption('check-database-platform'), FILTER_VALIDATE_BOOLEAN); + $fromEmptySchema = (bool) $input->getOption('from-empty-schema'); if ($formatted) { if (! class_exists('SqlFormatter')) { @@ -146,6 +153,7 @@ public function execute( } $editorCommand = $input->getOption('editor-cmd'); + assert(is_string($editorCommand) || $editorCommand === null); if ($editorCommand !== null) { $this->procOpen($editorCommand, $path); diff --git a/lib/Doctrine/Migrations/Tools/Console/Command/DumpSchemaCommand.php b/lib/Doctrine/Migrations/Tools/Console/Command/DumpSchemaCommand.php index c1bb788742..33d16e4b77 100644 --- a/lib/Doctrine/Migrations/Tools/Console/Command/DumpSchemaCommand.php +++ b/lib/Doctrine/Migrations/Tools/Console/Command/DumpSchemaCommand.php @@ -9,8 +9,12 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use function assert; use function class_exists; use function count; +use function is_array; +use function is_bool; +use function is_string; use function sprintf; /** @@ -68,7 +72,9 @@ public function execute( OutputInterface $output ) : ?int { $formatted = (bool) $input->getOption('formatted'); - $lineLength = (int) $input->getOption('line-length'); + $lineLength = $input->getOption('line-length'); + assert(! is_array($lineLength) && ! is_bool($lineLength)); + $lineLength = (int) $lineLength; $schemaDumper = $this->dependencyFactory->getSchemaDumper(); $versions = $this->migrationRepository->getVersions(); @@ -94,6 +100,7 @@ public function execute( ); $editorCommand = $input->getOption('editor-cmd'); + assert(is_string($editorCommand) || $editorCommand === null); if ($editorCommand !== null) { $this->procOpen($editorCommand, $path); diff --git a/lib/Doctrine/Migrations/Tools/Console/Command/ExecuteCommand.php b/lib/Doctrine/Migrations/Tools/Console/Command/ExecuteCommand.php index dd7680735f..6084299f57 100644 --- a/lib/Doctrine/Migrations/Tools/Console/Command/ExecuteCommand.php +++ b/lib/Doctrine/Migrations/Tools/Console/Command/ExecuteCommand.php @@ -10,7 +10,9 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use function assert; use function getcwd; +use function is_string; /** * The ExecutCommand class is responsible for executing a single migration version up or down. @@ -92,7 +94,8 @@ protected function configure() : void public function execute(InputInterface $input, OutputInterface $output) : ?int { - $version = $input->getArgument('version'); + $version = $input->getArgument('version'); + assert(is_string($version)); $timeAllQueries = (bool) $input->getOption('query-time'); $dryRun = (bool) $input->getOption('dry-run'); $path = $input->getOption('write-sql'); @@ -104,6 +107,7 @@ public function execute(InputInterface $input, OutputInterface $output) : ?int if ($path !== false) { $path = $path ?? getcwd(); + assert(is_string($path)); $version->writeSqlFile($path, $direction); diff --git a/lib/Doctrine/Migrations/Tools/Console/Command/GenerateCommand.php b/lib/Doctrine/Migrations/Tools/Console/Command/GenerateCommand.php index 18a696c4f6..80130feb8b 100644 --- a/lib/Doctrine/Migrations/Tools/Console/Command/GenerateCommand.php +++ b/lib/Doctrine/Migrations/Tools/Console/Command/GenerateCommand.php @@ -7,6 +7,8 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use function assert; +use function is_string; use function sprintf; /** @@ -51,6 +53,7 @@ public function execute(InputInterface $input, OutputInterface $output) : ?int $path = $migrationGenerator->generateMigration($versionNumber); $editorCommand = $input->getOption('editor-cmd'); + assert(is_string($editorCommand) || $editorCommand === null); if ($editorCommand !== null) { $this->procOpen($editorCommand, $path); diff --git a/lib/Doctrine/Migrations/Tools/Console/Command/MigrateCommand.php b/lib/Doctrine/Migrations/Tools/Console/Command/MigrateCommand.php index 159a7575f3..3c01e41aef 100644 --- a/lib/Doctrine/Migrations/Tools/Console/Command/MigrateCommand.php +++ b/lib/Doctrine/Migrations/Tools/Console/Command/MigrateCommand.php @@ -11,8 +11,10 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use function assert; use function count; use function getcwd; +use function is_string; use function sprintf; use function substr; @@ -115,7 +117,8 @@ public function execute(InputInterface $input, OutputInterface $output) : ?int { $this->outputHeader($output); - $version = (string) $input->getArgument('version'); + $version = $input->getArgument('version'); + assert(is_string($version)); $path = $input->getOption('write-sql'); $allowNoMigration = (bool) $input->getOption('allow-no-migration'); $timeAllQueries = (bool) $input->getOption('query-time'); @@ -142,6 +145,7 @@ public function execute(InputInterface $input, OutputInterface $output) : ?int if ($path !== false) { $path = $path ?? getcwd(); + assert(is_string($path)); $migrator->writeSqlFile($path, $version); return 0; diff --git a/lib/Doctrine/Migrations/Tools/Console/Command/VersionCommand.php b/lib/Doctrine/Migrations/Tools/Console/Command/VersionCommand.php index 2244da39df..b4a5d88e29 100644 --- a/lib/Doctrine/Migrations/Tools/Console/Command/VersionCommand.php +++ b/lib/Doctrine/Migrations/Tools/Console/Command/VersionCommand.php @@ -12,6 +12,8 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use function assert; +use function is_string; use function sprintf; /** @@ -128,6 +130,8 @@ public function execute(InputInterface $input, OutputInterface $output) : ?int private function markVersions(InputInterface $input, OutputInterface $output) : void { $affectedVersion = $input->getArgument('version'); + assert(is_string($affectedVersion) || $affectedVersion === null); + $allOption = $input->getOption('all'); $rangeFromOption = $input->getOption('range-from'); $rangeToOption = $input->getOption('range-to'); diff --git a/lib/Doctrine/Migrations/Tools/Console/ConnectionLoader.php b/lib/Doctrine/Migrations/Tools/Console/ConnectionLoader.php index 92fbadf6db..1c0f2523e2 100644 --- a/lib/Doctrine/Migrations/Tools/Console/ConnectionLoader.php +++ b/lib/Doctrine/Migrations/Tools/Console/ConnectionLoader.php @@ -14,6 +14,8 @@ use Doctrine\Migrations\Tools\Console\Exception\ConnectionNotSpecified; use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Input\InputInterface; +use function assert; +use function is_string; /** * The ConnectionLoader class is responsible for loading the Doctrine\DBAL\Connection instance to use for migrations. @@ -46,8 +48,11 @@ protected function createConnectionConfigurationChainLoader( InputInterface $input, HelperSet $helperSet ) : ConnectionLoaderInterface { + $dbConfiguration = $input->getOption('db-configuration'); + assert(is_string($dbConfiguration) || $dbConfiguration === null); + return new ConnectionConfigurationChainLoader([ - new ArrayConnectionConfigurationLoader($input->getOption('db-configuration')), + new ArrayConnectionConfigurationLoader($dbConfiguration), new ArrayConnectionConfigurationLoader('migrations-db.php'), new ConnectionHelperLoader($helperSet, 'connection'), new ConnectionConfigurationLoader($this->configuration), diff --git a/lib/Doctrine/Migrations/Tools/Console/Helper/ConfigurationHelper.php b/lib/Doctrine/Migrations/Tools/Console/Helper/ConfigurationHelper.php index a4d21ea159..4e3b096c56 100644 --- a/lib/Doctrine/Migrations/Tools/Console/Helper/ConfigurationHelper.php +++ b/lib/Doctrine/Migrations/Tools/Console/Helper/ConfigurationHelper.php @@ -13,7 +13,9 @@ use Doctrine\Migrations\Tools\Console\Exception\FileTypeNotSupported; use Symfony\Component\Console\Helper\Helper; use Symfony\Component\Console\Input\InputInterface; +use function assert; use function file_exists; +use function is_string; use function pathinfo; /** @@ -45,6 +47,8 @@ public function getMigrationConfig(InputInterface $input) : Configuration $configuration = $input->getOption('configuration'); if ($configuration !== null) { + assert(is_string($configuration)); + return $this->loadConfig($configuration); } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 1722859116..6f673e5f68 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -16,6 +16,7 @@ parameters: - '~ProxyManager\\Proxy\\VirtualProxyInterface~' - '~^Parameter #1 \$files of method Doctrine\\Migrations\\Finder\\Finder::loadMigrationClasses\(\) expects array, array given\.\z~' - '~^Class Doctrine\\Migrations\\Tests\\DoesNotExistAtAll not found\.\z~' + - '~^Call to method getVersion\(\) of deprecated class PackageVersions\\Versions\.$~' includes: - vendor/phpstan/phpstan-deprecation-rules/rules.neon diff --git a/tests/Doctrine/Migrations/Tests/Functional/FunctionalTest.php b/tests/Doctrine/Migrations/Tests/Functional/FunctionalTest.php index 98092caaca..14f0266599 100644 --- a/tests/Doctrine/Migrations/Tests/Functional/FunctionalTest.php +++ b/tests/Doctrine/Migrations/Tests/Functional/FunctionalTest.php @@ -521,6 +521,8 @@ public function testMigrateWithConnectionWithAutoCommitOffStillPersistsChanges() { $listener = new AutoCommitListener(); [$conn, $config] = self::fileConnectionAndConfig(); + assert($conn instanceof Connection); + assert($config instanceof Configuration); $config->registerMigration('1', MigrateWithDataModification::class); $migrator = $this->createTestMigrator($config); $conn->getEventManager()->addEventSubscriber($listener); @@ -552,6 +554,8 @@ public function testMigrationExecutedAt() : void /** * @return Connection[]|Configuration[] + * + * @psalm-return array{Connection,Configuration} */ private static function fileConnectionAndConfig() : array { diff --git a/tests/Doctrine/Migrations/Tests/MigrationTestCase.php b/tests/Doctrine/Migrations/Tests/MigrationTestCase.php index 824b8a798d..f015d9b7ea 100644 --- a/tests/Doctrine/Migrations/Tests/MigrationTestCase.php +++ b/tests/Doctrine/Migrations/Tests/MigrationTestCase.php @@ -63,8 +63,10 @@ public function getOutputStreamContent(StreamOutput $streamOutput) : string { $stream = $streamOutput->getStream(); rewind($stream); + $contents = stream_get_contents($stream); + assert($contents !== false); - return stream_get_contents($stream); + return $contents; } /** @return resource */ diff --git a/tests/Doctrine/Migrations/Tests/Provider/ClassMetadataFactory.php b/tests/Doctrine/Migrations/Tests/Provider/ClassMetadataFactory.php index 8b6dd2cc50..9abc7cbcd8 100644 --- a/tests/Doctrine/Migrations/Tests/Provider/ClassMetadataFactory.php +++ b/tests/Doctrine/Migrations/Tests/Provider/ClassMetadataFactory.php @@ -4,8 +4,8 @@ namespace Doctrine\Migrations\Tests\Provider; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadataFactory as BaseMetadataFactoryAlias; +use Doctrine\Persistence\Mapping\ClassMetadata; use function array_reverse; class ClassMetadataFactory extends BaseMetadataFactoryAlias diff --git a/tests/Doctrine/Migrations/Tests/Tools/Console/Command/AbstractCommandTest.php b/tests/Doctrine/Migrations/Tests/Tools/Console/Command/AbstractCommandTest.php index 054c9e94f7..693316cb59 100644 --- a/tests/Doctrine/Migrations/Tests/Tools/Console/Command/AbstractCommandTest.php +++ b/tests/Doctrine/Migrations/Tests/Tools/Console/Command/AbstractCommandTest.php @@ -54,7 +54,9 @@ public function invokeMigrationConfigurationGetter( } if (! $noConnection) { - $command->getHelperSet()->set( + $helperSet = $command->getHelperSet(); + assert($helperSet !== null); + $helperSet->set( new ConnectionHelper($this->getSqliteConnection()), 'connection' ); diff --git a/tests/Doctrine/Migrations/Tests/Tools/Console/Command/CommandTestCase.php b/tests/Doctrine/Migrations/Tests/Tools/Console/Command/CommandTestCase.php index 7fb0e355d9..a49b2290a6 100644 --- a/tests/Doctrine/Migrations/Tests/Tools/Console/Command/CommandTestCase.php +++ b/tests/Doctrine/Migrations/Tests/Tools/Console/Command/CommandTestCase.php @@ -12,6 +12,8 @@ use Symfony\Component\Console\Application; use Symfony\Component\Console\Tester\CommandTester; use function array_replace; +use function assert; +use function is_string; abstract class CommandTestCase extends MigrationTestCase { @@ -47,7 +49,10 @@ protected function createConnection() : Connection protected function createCommandTester() : CommandTester { - return new CommandTester($this->app->find($this->command->getName())); + $name = $this->command->getName(); + assert(is_string($name)); + + return new CommandTester($this->app->find($name)); } /**