From 2e6f0ab3b9af629d2b5a16b551db927dbf9aa594 Mon Sep 17 00:00:00 2001 From: Clemens Krack Date: Tue, 30 Jun 2020 14:21:46 +0200 Subject: [PATCH 1/6] refactor: add rector & phpstan and improve code --- .github/workflows/qa.yml | 6 +++ README.md | 16 +++--- composer.json | 6 +++ phpstan.neon.dist | 29 ++++++++++ rector.yaml | 21 ++++++++ .../OptimusParamConverterSpec.php | 2 +- spec/Twig/OptimusExtensionSpec.php | 2 +- src/CkrackOptimusBundle.php | 2 +- .../CkrackOptimusExtension.php | 2 +- src/DependencyInjection/Configuration.php | 27 +++++----- src/ParamConverter/OptimusParamConverter.php | 54 +++++++++++-------- src/Twig/OptimusExtension.php | 4 +- 12 files changed, 119 insertions(+), 52 deletions(-) create mode 100644 phpstan.neon.dist create mode 100644 rector.yaml diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index 53243f1..7605167 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -27,3 +27,9 @@ jobs: uses: php-actions/phpspec@master with: config: phpspec.yml.dist + + - name: Lint code + run: vendor/bin/php-cs-fixer fix -v --dry-run && vendor/bin/rector process --dry-run + + - name: Static analysis + run: vendor/bin/phpstan analyse --ansi --memory-limit=0 diff --git a/README.md b/README.md index 3c55154..09e4224 100644 --- a/README.md +++ b/README.md @@ -39,18 +39,14 @@ The configuration (`config/packages/ckrack_optimus.yaml`) looks as follows: ```yaml ckrack_optimus: + # Set options, as documented at https://github.com/jenssegers/optimus#usage + prime: "%env(int:OPTIMUS_PRIME)%" + inverse: "%env(int:OPTIMUS_INVERSE)%" + random: "%env(int:OPTIMUS_RANDOM)%" - # Large prime number lower than 2147483647 - prime: %env(int:OPTIMUS_PRIME)% - - # The inverse prime so that (PRIME * INVERSE) & MAXID == 1 - inverse: %env(int:OPTIMUS_INVERSE)% - - # A large random integer lower than 2147483647 - random: %env(int:OPTIMUS_RANDOM)% - - # if set to true, param converter will continue with the next available + # if set to true, param converter will continue with the next available param converters passthrough: true + ``` To generate the env variables, we can use optimus' `spark` command. diff --git a/composer.json b/composer.json index cb99716..ee1e140 100644 --- a/composer.json +++ b/composer.json @@ -30,8 +30,14 @@ }, "require-dev": { "bossa/phpspec2-expect": "^3.0", + "ergebnis/phpstan-rules": "^0.15.0", + "friendsofphp/php-cs-fixer": "^2.16.3", "phpspec/phpspec": "^6.1", + "phpstan/phpstan-strict-rules": "^0.12.2", + "phpstan/phpstan": "^0.12.31", + "rector/rector": "^0.7.37", "roave/security-advisories": "dev-master", + "thecodingmachine/phpstan-strict-rules": "^0.12.0", "twig/twig": "^2.7" }, "suggest": { diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..4fbc38d --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,29 @@ +includes: + - vendor/phpstan/phpstan-strict-rules/rules.neon + - vendor/ergebnis/phpstan-rules/rules.neon + - vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon + +parameters: + level: max + paths: + - src + + checkMissingIterableValueType: false + checkGenericClassInNonGenericObjectType: false + reportUnmatchedIgnoredErrors: true + ergebnis: + classesAllowedToBeExtended: + - Symfony\Component\HttpKernel\Bundle\Bundle + - Symfony\Component\HttpKernel\DependencyInjection\Extension + - Twig\Extension\AbstractExtension + - PhpSpec\ObjectBehavior + ignoreErrors: + # We actually configure a container here + - + message: '#.*has a parameter \$container with a type declaration of .*ContainerBuilder.*#m' + path: src/DependencyInjection/CkrackOptimusExtension.php + + # The DependencyInjection returns are very complex to deal with + - + message: '#Cannot call method.* on .*NodeParentInterface\|null.*#' + path: src/DependencyInjection/Configuration.php diff --git a/rector.yaml b/rector.yaml new file mode 100644 index 0000000..e67b4a4 --- /dev/null +++ b/rector.yaml @@ -0,0 +1,21 @@ +# rector.yaml +parameters: + paths: + - src + - spec + sets: + - 'action-injection-to-constructor-injection' + - 'array-str-functions-to-static-call' + - 'celebrity' + - 'doctrine' + - 'phpstan' + - 'phpunit-code-quality' + - 'solid' + - 'early-return' + - 'doctrine-code-quality' + - 'code-quality' + - 'php71' + - 'php72' + - 'php73' + exclude_rectors: + - Rector\SOLID\Rector\Class_\RepeatedLiteralToClassConstantRector diff --git a/spec/ParamConverter/OptimusParamConverterSpec.php b/spec/ParamConverter/OptimusParamConverterSpec.php index f1880d0..30b1ccb 100644 --- a/spec/ParamConverter/OptimusParamConverterSpec.php +++ b/spec/ParamConverter/OptimusParamConverterSpec.php @@ -10,7 +10,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Component\HttpFoundation\Request; -class OptimusParamConverterSpec extends ObjectBehavior +final class OptimusParamConverterSpec extends ObjectBehavior { public function let() { diff --git a/spec/Twig/OptimusExtensionSpec.php b/spec/Twig/OptimusExtensionSpec.php index 789fbba..971d7e7 100644 --- a/spec/Twig/OptimusExtensionSpec.php +++ b/spec/Twig/OptimusExtensionSpec.php @@ -10,7 +10,7 @@ use Twig\Environment; use Twig\Loader\ArrayLoader; -class OptimusExtensionSpec extends ObjectBehavior +final class OptimusExtensionSpec extends ObjectBehavior { public function it_is_initializable(Optimus $optimus) { diff --git a/src/CkrackOptimusBundle.php b/src/CkrackOptimusBundle.php index 920827d..1e5fea4 100644 --- a/src/CkrackOptimusBundle.php +++ b/src/CkrackOptimusBundle.php @@ -6,6 +6,6 @@ use Symfony\Component\HttpKernel\Bundle\Bundle; -class CkrackOptimusBundle extends Bundle +final class CkrackOptimusBundle extends Bundle { } diff --git a/src/DependencyInjection/CkrackOptimusExtension.php b/src/DependencyInjection/CkrackOptimusExtension.php index e29748e..d748a55 100644 --- a/src/DependencyInjection/CkrackOptimusExtension.php +++ b/src/DependencyInjection/CkrackOptimusExtension.php @@ -9,7 +9,7 @@ use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; -class CkrackOptimusExtension extends Extension +final class CkrackOptimusExtension extends Extension { public function load(array $configs, ContainerBuilder $container): void { diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index c69bd02..3e02353 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -4,11 +4,12 @@ namespace Ckrack\OptimusBundle\DependencyInjection; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\NodeParentInterface; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; -class Configuration implements ConfigurationInterface +final class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder(): NodeParentInterface { @@ -17,19 +18,19 @@ public function getConfigTreeBuilder(): NodeParentInterface $rootNode = $treeBuilder->getRootNode(); $rootNode - ->children() - ->integerNode('prime') - /* - * use the lowest possible prime, because optimus must instantiate with valid numbers. - * they will be replaced by configuration provided by the recipe. - */ - ->defaultValue(3) - ->info('Large prime number lower than 2147483647') - ->end() + ->children() + ->integerNode('prime') + /* + * Use the lowest possible prime, because optimus must instantiate with valid numbers. + * They will be replaced by configuration provided by the recipe. + */ + ->defaultValue(3) + ->info('Large prime number lower than 2147483647') + ->end() ->integerNode('inverse') - ->defaultValue(715827883) - ->info('The inverse prime so that (PRIME * INVERSE) & MAXID == 1') - ->end() + ->defaultValue(715827883) + ->info('The inverse prime so that (PRIME * INVERSE) & MAXID == 1') + ->end() ->integerNode('random') ->defaultValue(1592469642) ->info('A large random integer lower than 2147483647') diff --git a/src/ParamConverter/OptimusParamConverter.php b/src/ParamConverter/OptimusParamConverter.php index 11b6832..52b037c 100644 --- a/src/ParamConverter/OptimusParamConverter.php +++ b/src/ParamConverter/OptimusParamConverter.php @@ -9,7 +9,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface; use Symfony\Component\HttpFoundation\Request; -class OptimusParamConverter implements ParamConverterInterface +final class OptimusParamConverter implements ParamConverterInterface { /** * @var Optimus @@ -19,7 +19,12 @@ class OptimusParamConverter implements ParamConverterInterface /** * @var bool */ - private $passthrough; + private $passthrough = false; + + /** + * @var string + */ + private const DEFAULT_IDENTIFIER = 'optimus'; public function __construct(Optimus $optimus, bool $passthrough) { @@ -43,49 +48,52 @@ public function supports(ParamConverter $configuration): bool private function setOptimus(Request $request, ParamConverter $configuration): void { - $name = $configuration->getName(); + if (!$this->hasIdentifier($request, array_replace([self::DEFAULT_IDENTIFIER => null], $configuration->getOptions()))) { + return; + } $identifier = $this->getIdentifier( $request, - array_replace(['optimus' => null], $configuration->getOptions()), - (string) $configuration->getName() + array_replace([self::DEFAULT_IDENTIFIER => null], $configuration->getOptions()) ); - if (!$identifier) { - return; + $name = $configuration->getName(); + if ($name == null && $identifier == self::DEFAULT_IDENTIFIER) { + $name = self::DEFAULT_IDENTIFIER; } - if ($name == null && $identifier == 'optimus') { - $name = 'optimus'; - } + $optimus = $this->optimus->decode((int) $request->attributes->get($identifier)); + $request->attributes->set($name, $optimus); + } - try { - $optimus = $this->optimus->decode((int) $request->attributes->get($identifier)); - $request->attributes->set($name, $optimus); - } catch (\Throwable $th) { - return; + private function getIdentifier(Request $request, array $options): string + { + if ($options[self::DEFAULT_IDENTIFIER] && \is_string($options[self::DEFAULT_IDENTIFIER])) { + return $options[self::DEFAULT_IDENTIFIER]; } + + return self::DEFAULT_IDENTIFIER; } - private function getIdentifier(Request $request, $options, string $name): ?string + private function hasIdentifier(Request $request, array $options): bool { - if ($options['optimus'] && !\is_array($options['optimus'])) { - return $options['optimus']; + if ($options[self::DEFAULT_IDENTIFIER]) { + return true; } - if ($request->attributes->has('optimus')) { - return 'optimus'; + if ($request->attributes->has(self::DEFAULT_IDENTIFIER)) { + return true; } - return null; + return false; } private function removeOptimusOption(ParamConverter $configuration): void { $options = $configuration->getOptions(); - if (isset($options['optimus'])) { - unset($options['optimus']); + if (\array_key_exists(self::DEFAULT_IDENTIFIER, $options)) { + unset($options[self::DEFAULT_IDENTIFIER]); $configuration->setOptions($options); } } diff --git a/src/Twig/OptimusExtension.php b/src/Twig/OptimusExtension.php index 24c964f..580133b 100644 --- a/src/Twig/OptimusExtension.php +++ b/src/Twig/OptimusExtension.php @@ -8,7 +8,7 @@ use Twig\Extension\AbstractExtension; use Twig\TwigFilter; -class OptimusExtension extends AbstractExtension +final class OptimusExtension extends AbstractExtension { /** * @var Optimus @@ -27,7 +27,7 @@ public function getFilters(): array ]; } - public function optimusEncode($number): int + public function optimusEncode(int $number): int { return $this->optimus->encode($number); } From a1c366c051846a4a8cd77c7cf62e0a7b30d69111 Mon Sep 17 00:00:00 2001 From: Clemens Krack Date: Tue, 30 Jun 2020 14:41:35 +0200 Subject: [PATCH 2/6] refactor(paramconverter): simplify return --- src/ParamConverter/OptimusParamConverter.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/ParamConverter/OptimusParamConverter.php b/src/ParamConverter/OptimusParamConverter.php index 52b037c..92e9a8e 100644 --- a/src/ParamConverter/OptimusParamConverter.php +++ b/src/ParamConverter/OptimusParamConverter.php @@ -68,7 +68,7 @@ private function setOptimus(Request $request, ParamConverter $configuration): vo private function getIdentifier(Request $request, array $options): string { - if ($options[self::DEFAULT_IDENTIFIER] && \is_string($options[self::DEFAULT_IDENTIFIER])) { + if (\array_key_exists(self::DEFAULT_IDENTIFIER, $options) && \is_string($options[self::DEFAULT_IDENTIFIER])) { return $options[self::DEFAULT_IDENTIFIER]; } @@ -77,15 +77,11 @@ private function getIdentifier(Request $request, array $options): string private function hasIdentifier(Request $request, array $options): bool { - if ($options[self::DEFAULT_IDENTIFIER]) { + if (\array_key_exists(self::DEFAULT_IDENTIFIER, $options) && \is_string($options[self::DEFAULT_IDENTIFIER])) { return true; } - if ($request->attributes->has(self::DEFAULT_IDENTIFIER)) { - return true; - } - - return false; + return $request->attributes->has(self::DEFAULT_IDENTIFIER); } private function removeOptimusOption(ParamConverter $configuration): void From 488b6ce3f11a93ba64e4c736379c9e05862bf752 Mon Sep 17 00:00:00 2001 From: Clemens Krack Date: Tue, 30 Jun 2020 14:45:05 +0200 Subject: [PATCH 3/6] ci: add more php versions to matrix --- .github/workflows/qa.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index 7605167..41e2af3 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - php: [ 7.4 ] + php: [ 7.1, 7.2, 7.3, 7.4 ] os: [ ubuntu-latest ] steps: - name: Checkout From 346ec3c2eedf2cc4fb57925ff61d215a1a7309e0 Mon Sep 17 00:00:00 2001 From: Clemens Krack Date: Tue, 30 Jun 2020 15:04:01 +0200 Subject: [PATCH 4/6] fix: add alternative phpspec version for PHP 7.1 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ee1e140..3ca1559 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "bossa/phpspec2-expect": "^3.0", "ergebnis/phpstan-rules": "^0.15.0", "friendsofphp/php-cs-fixer": "^2.16.3", - "phpspec/phpspec": "^6.1", + "phpspec/phpspec": "^5.1 || ^6.1", "phpstan/phpstan-strict-rules": "^0.12.2", "phpstan/phpstan": "^0.12.31", "rector/rector": "^0.7.37", From 9692829511d018a1e9fede728ccaab0308ba187a Mon Sep 17 00:00:00 2001 From: Clemens Krack Date: Tue, 30 Jun 2020 15:24:13 +0200 Subject: [PATCH 5/6] ci: drop support for PHP 7.1 --- .github/workflows/qa.yml | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index 41e2af3..44ae86a 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - php: [ 7.1, 7.2, 7.3, 7.4 ] + php: [ 7.2, 7.3, 7.4 ] os: [ ubuntu-latest ] steps: - name: Checkout diff --git a/composer.json b/composer.json index 3ca1559..5f2fb8b 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ } }, "require": { - "php": ">=7.1", + "php": ">=7.2", "jenssegers/optimus": "^1.1", "sensio/framework-extra-bundle": "~3.0", "symfony/http-kernel": "^4.0 || ^5.0" From 1a72ac6289915f84952bfe78f6778a4784508dd5 Mon Sep 17 00:00:00 2001 From: Clemens Krack Date: Tue, 30 Jun 2020 15:47:14 +0200 Subject: [PATCH 6/6] fix(phpspec): support more versions --- composer.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5f2fb8b..29872b0 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "bossa/phpspec2-expect": "^3.0", "ergebnis/phpstan-rules": "^0.15.0", "friendsofphp/php-cs-fixer": "^2.16.3", - "phpspec/phpspec": "^5.1 || ^6.1", + "phpspec/phpspec": "^4.3 || ^5.1 || ^6.1", "phpstan/phpstan-strict-rules": "^0.12.2", "phpstan/phpstan": "^0.12.31", "rector/rector": "^0.7.37", @@ -48,5 +48,16 @@ "*": "dist" }, "sort-packages": true + }, + "scripts": { + "lint:rector": "vendor/bin/rector process --dry-run", + "lint:php-cs-fixer": "vendor/bin/php-cs-fixer fix -v --dry-run", + "lint:phpstan": "vendor/bin/phpstan analyse --ansi --memory-limit=0", + "lint": [ + "composer lint:rector", + "composer lint:php-cs-fixer", + "composer lint:phpstan" + ], + "test": "vendor/bin/phpspec run --ansi" } }