From e03f48101f43ce610646050e980f507886632e72 Mon Sep 17 00:00:00 2001 From: Nicholas Ruunu Date: Thu, 20 Jun 2024 02:20:28 +0200 Subject: [PATCH 1/2] Add github actions workflow --- .gitattributes | 8 +++--- .github/workflows/php.yml | 43 +++++++++++++++++++++++++++++ .gitignore | 1 + .php-cs-fixer.php | 17 ++++++++++++ LICENSE | 2 +- composer.json | 9 +++--- docker-compose.yaml | 25 +++++++++++++++++ phpspec.yml.dist => phpspec.yml | 0 phpstan.neon | 4 +++ rector.php | 14 ++++------ spec/CompositeSpecificationSpec.php | 13 ++++----- spec/NotSpec.php | 6 ++-- src/AndX.php | 5 +--- src/CompositeSpecification.php | 2 +- src/Not.php | 5 +--- src/OrX.php | 7 ++--- 16 files changed, 118 insertions(+), 43 deletions(-) create mode 100644 .github/workflows/php.yml create mode 100644 .php-cs-fixer.php create mode 100644 docker-compose.yaml rename phpspec.yml.dist => phpspec.yml (100%) create mode 100644 phpstan.neon diff --git a/.gitattributes b/.gitattributes index 3cf489b..fcbac5b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,8 @@ /spec export-ignore -.coveralls.yml export-ignore .editorconfig export-ignore .gitattributes export-ignore .gitignore export-ignore -.travis.yml export-ignore -.php_cs export-ignore -phpspec.yml.dist export-ignore +.php-cs-fixer.php export-ignore +phpspec.yml export-ignore +rector.php export-ignore +phpstan.neon export-ignore diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml new file mode 100644 index 0000000..cef2c14 --- /dev/null +++ b/.github/workflows/php.yml @@ -0,0 +1,43 @@ +name: PHP Composer + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Validate composer.json and composer.lock + run: docker compose run composer validate --strict + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.json') }}-${{ github.ref_name }} + restore-keys: | + ${{ runner.os }}-php-${{ hashFiles('**/composer.json') }} + ${{ runner.os }}-php- + + - name: Install packages + run: docker compose run composer install + + - name: Run test suite + run: docker compose run phpspec + + - name: Run static analyzer + run: docker compose run phpstan + + - name: Run code style checker + run: docker compose run php-cs-fixer --dry-run diff --git a/.gitignore b/.gitignore index 0fabc0e..4d3e5f6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ build/ vendor/ composer.lock +.php-cs-fixer.cache diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..2070fa1 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,17 @@ +exclude(['vendor', 'build']) + ->in(__DIR__); + +return (new PhpCsFixer\Config()) + ->setRiskyAllowed(true) + ->setRules([ + '@Symfony' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'ordered_class_elements' => true, + 'strict_comparison' => true, + 'strict_param' => true, + ]) + ->setFinder($finder); diff --git a/LICENSE b/LICENSE index 3c98b61..75abca4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ The MIT License (MIT) Copyright (c) 2015 Rik Bruil +Copyright (c) 2024 Nicholas Ruunu Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -19,4 +20,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/composer.json b/composer.json index 9935328..70f7403 100644 --- a/composer.json +++ b/composer.json @@ -8,10 +8,6 @@ { "name": "Nicholas Ruunu", "email": "nicholas@ruu.nu" - }, - { - "name": "Rik Bruil", - "email": "rik.bruil@gmail.com" } ], "minimum-stability": "stable", @@ -26,7 +22,9 @@ }, "require-dev": { "phpspec/phpspec": "^7.5", - "rector/rector": "^1.1" + "rector/rector": "^1.1", + "phpstan/phpstan": "^1.11", + "friendsofphp/php-cs-fixer": "^3.59" }, "extra": { "branch-alias": { @@ -35,6 +33,7 @@ }, "scripts": { "test": "vendor/bin/phpspec run", + "static-analyzer": "vendor/bin/phpstan", "fix-style": "vendor/bin/php-cs-fixer fix" } } diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..4ee7f6f --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,25 @@ +services: + php: &php + image: php:8.2-cli-alpine + volumes: + - .:/app + working_dir: /app + + phpspec: + <<: *php + entrypoint: vendor/bin/phpspec + command: run + + phpstan: + <<: *php + entrypoint: vendor/bin/phpstan + + php-cs-fixer: + <<: *php + entrypoint: vendor/bin/php-cs-fixer fix + + composer: + image: composer:latest + volumes: + - .:/app + working_dir: /app diff --git a/phpspec.yml.dist b/phpspec.yml similarity index 100% rename from phpspec.yml.dist rename to phpspec.yml diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..776ccd8 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,4 @@ +parameters: + level: max + paths: + - src diff --git a/rector.php b/rector.php index 3f0d7e7..97ad8d1 100644 --- a/rector.php +++ b/rector.php @@ -1,16 +1,14 @@ withPaths([ - __DIR__ . '/src', - __DIR__ . '/spec', - ])->withPhpSets(php83: true)->withAttributesSets( - symfony: true, - doctrine: true, - ) + __DIR__.'/src', + __DIR__.'/spec', +])->withPhpSets(php83: true)->withAttributesSets( + symfony: true, + doctrine: true, +) // here we can define, what prepared sets of rules will be applied ->withPreparedSets( deadCode: true, diff --git a/spec/CompositeSpecificationSpec.php b/spec/CompositeSpecificationSpec.php index af67be9..81d5501 100644 --- a/spec/CompositeSpecificationSpec.php +++ b/spec/CompositeSpecificationSpec.php @@ -18,7 +18,7 @@ public function let(): void public function it_is_initializable(): void { - $this->shouldHaveType(\Purist\Specification\CompositeSpecification::class); + $this->shouldHaveType(CompositeSpecification::class); } public function it_should_return_and_specification(SpecificationInterface $specification): void @@ -26,7 +26,7 @@ public function it_should_return_and_specification(SpecificationInterface $speci $specification->isSatisfiedBy('foo')->willReturn(true); $and = $this->andX($specification); - $and->shouldHaveType(\Purist\Specification\AndX::class); + $and->shouldHaveType(AndX::class); $and->isSatisfiedBy('foo')->shouldReturn(true); } @@ -35,7 +35,7 @@ public function it_should_return_or_specification(SpecificationInterface $specif $specification->isSatisfiedBy('foo')->willReturn(false); $or = $this->orX($specification); - $or->shouldHaveType(\Purist\Specification\OrX::class); + $or->shouldHaveType(OrX::class); $or->isSatisfiedBy('foo')->shouldReturn(true); } @@ -44,19 +44,16 @@ public function it_should_return_not_specification(SpecificationInterface $speci $specification->isSatisfiedBy('foo')->willReturn(true); $not = $this->not($specification); - $not->shouldHaveType(\Purist\Specification\Not::class); + $not->shouldHaveType(Not::class); $not->isSatisfiedBy('foo')->shouldReturn(false); } } readonly class DummySpec extends CompositeSpecification { - /** - * {@inheritDoc} - */ #[\Override] public function isSatisfiedBy($value): bool { - return $value === 'foo'; + return 'foo' === $value; } } diff --git a/spec/NotSpec.php b/spec/NotSpec.php index 4cc34d3..3885305 100644 --- a/spec/NotSpec.php +++ b/spec/NotSpec.php @@ -13,9 +13,9 @@ public function it_should_have_correct_types(SpecificationInterface $specificati { $this->beConstructedWith($specification); - $this->shouldHaveType(\Purist\Specification\Not::class); - $this->shouldHaveType(\Purist\Specification\SpecificationInterface::class); - $this->shouldHaveType(\Purist\Specification\CompositeSpecification::class); + $this->shouldHaveType(Not::class); + $this->shouldHaveType(SpecificationInterface::class); + $this->shouldHaveType(CompositeSpecification::class); } public function it_should_pass_if_child_fails(SpecificationInterface $specification): void diff --git a/src/AndX.php b/src/AndX.php index ebd09fa..5059385 100644 --- a/src/AndX.php +++ b/src/AndX.php @@ -2,15 +2,12 @@ namespace Purist\Specification; -readonly final class AndX extends CompositeSpecification +final readonly class AndX extends CompositeSpecification { public function __construct(private SpecificationInterface $x, private SpecificationInterface $y) { } - /** - * {@inheritDoc} - */ #[\Override] public function isSatisfiedBy(mixed $value): bool { diff --git a/src/CompositeSpecification.php b/src/CompositeSpecification.php index d8b3292..2a6acbf 100644 --- a/src/CompositeSpecification.php +++ b/src/CompositeSpecification.php @@ -2,7 +2,7 @@ namespace Purist\Specification; -readonly abstract class CompositeSpecification implements CompositeSpecificationInterface +abstract readonly class CompositeSpecification implements CompositeSpecificationInterface { #[\Override] public function andX(SpecificationInterface $specification): AndX diff --git a/src/Not.php b/src/Not.php index dd2a672..11d01be 100644 --- a/src/Not.php +++ b/src/Not.php @@ -2,15 +2,12 @@ namespace Purist\Specification; -readonly final class Not extends CompositeSpecification +final readonly class Not extends CompositeSpecification { public function __construct(private SpecificationInterface $wrapped) { } - /** - * {@inheritDoc} - */ #[\Override] public function isSatisfiedBy(mixed $value): bool { diff --git a/src/OrX.php b/src/OrX.php index b289b3c..6714f1e 100644 --- a/src/OrX.php +++ b/src/OrX.php @@ -2,17 +2,14 @@ namespace Purist\Specification; -readonly final class OrX extends CompositeSpecification +final readonly class OrX extends CompositeSpecification { public function __construct(private SpecificationInterface $x, private SpecificationInterface $y) { } - /** - * {@inheritDoc} - */ #[\Override] - public function isSatisfiedBy(mixed $value) : bool + public function isSatisfiedBy(mixed $value): bool { return $this->x->isSatisfiedBy($value) || $this->y->isSatisfiedBy($value); } From 26258e332401d6ebebf4a78b381037b1287018ff Mon Sep 17 00:00:00 2001 From: Nicholas Ruunu Date: Thu, 20 Jun 2024 03:02:43 +0200 Subject: [PATCH 2/2] Remove icons --- .php_cs | 20 -------------------- README.md | 5 ----- 2 files changed, 25 deletions(-) delete mode 100644 .php_cs diff --git a/.php_cs b/.php_cs deleted file mode 100644 index ee91561..0000000 --- a/.php_cs +++ /dev/null @@ -1,20 +0,0 @@ -files() - ->name('*.php') - ->in(__DIR__ . '/src') - ->in(__DIR__ . '/spec'); - -return Symfony\CS\Config\Config::create() - ->level(Symfony\CS\FixerInterface::SYMFONY_LEVEL) - ->fixers(array( - 'header_comment', - 'align_equals', - 'concat_with_spaces', - 'ordered_use', - 'phpdoc_order', - 'strict', - 'strict_param', - )) - ->finder($finder); diff --git a/README.md b/README.md index 53a4421..c1b9397 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,4 @@ # Specification -[![Build Status](https://travis-ci.org/rikbruil/specification.svg)](https://travis-ci.org/rikbruil/specification) -[![Coverage Status](https://coveralls.io/repos/rikbruil/specification/badge.svg?branch=master)](https://coveralls.io/r/rikbruil/specification?branch=master) -[![Latest Stable Version](https://poser.pugx.org/rikbruil/specification/v/stable.svg)](https://packagist.org/packages/rikbruil/specification) -[![License](https://poser.pugx.org/rikbruil/specification/license.svg)](https://packagist.org/packages/rikbruil/specification) -[![SensioLabsInsight](https://insight.sensiolabs.com/projects/1b2454be-832e-4086-9f64-759f1ff5a089/mini.png)](https://insight.sensiolabs.com/projects/1b2454be-832e-4086-9f64-759f1ff5a089) PHP implementation of the [Specification pattern][specification_pattern]