diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 7ba88b1..1a6e733 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -6,36 +6,7 @@ on: workflow_dispatch: jobs: - coding-standards: - name: Coding Standards - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 8.0 - tools: cs2pr - coverage: none - - - name: Get composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install dependencies - run: composer install --no-interaction --no-progress --prefer-dist - - - name: Validate composer.json - run: composer validate --strict - - - name: Run PHP_CodeSniffer - run: ./vendor/bin/phpcs -q --no-colors --report=checkstyle src tests | cs2pr + cs: + uses: ray-di/.github/.github/workflows/coding-standards.yml@v1 + with: + php_version: 8.3 diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 20e8b14..818de5e 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -4,58 +4,10 @@ on: push: pull_request: workflow_dispatch: - schedule: - - cron: '42 15 * * *' jobs: - phpunit: - name: PHPUnit - runs-on: ubuntu-latest - strategy: - matrix: - operating-system: - - ubuntu-latest - php-version: - - '7.3' - - '7.4' - - '8.0' - dependencies: - - lowest - - highest - steps: - - name: Checkout - uses: actions/checkout@v1 - - - name: Setup PHP ${{ matrix.php-version }} - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - coverage: pcov - ini-values: zend.assertions=1 - - - name: Get composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install lowest dependencies - if: ${{ matrix.dependencies == 'lowest' }} - run: composer update --prefer-lowest --no-interaction --no-progress --no-suggest - - - name: Install highest dependencies - if: ${{ matrix.dependencies == 'highest' }} - run: composer update --no-interaction --no-progress --no-suggest - - - name: Run test suite - run: ./vendor/bin/phpunit --coverage-clover=coverage.xml - - - name: Upload coverage report - uses: codecov/codecov-action@v1 - with: - file: ./coverage.xml + ci: + uses: ray-di/.github/.github/workflows/continuous-integration.yml@v1 + with: + old_stable: '["8.1", "8.2"]' + current_stable: 8.3 diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 74bba0b..1e5f6bf 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -6,134 +6,7 @@ on: workflow_dispatch: jobs: - static-analysis-phpstan: - name: Static Analysis with PHPStan - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 8.0 - tools: cs2pr - coverage: none - - - name: Get composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install dependencies - run: composer install --no-interaction --no-progress --prefer-dist - - - name: Run PHPStan - run: ./vendor/bin/phpstan analyse -c phpstan.neon --no-progress --no-interaction --error-format=checkstyle | cs2pr - - static-analysis-psalm: - name: Static Analysis with Psalm - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 8.0 - tools: cs2pr - coverage: none - - - name: Get composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Install dependencies - run: composer install --no-interaction --no-progress --prefer-dist - - - name: Run Psalm - run: ./vendor/bin/psalm --show-info=false --output-format=checkstyle --shepherd | cs2pr - - static-analysis-phpmd: - name: Static Analysis with PHPMD - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - - - name: Get composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install dependencies - run: composer install --no-interaction --no-progress --prefer-dist - - - name: Run PHP Mess Detector - run: ./vendor/bin/phpmd src text --exclude src/Annotation ./phpmd.xml - - static-analysis-php-metrics: - name: Static Analysis with PhpMetrics - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 8.0 - coverage: none - - - name: Get composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Install dependencies - run: composer install --no-interaction --no-progress --prefer-dist - - - name: Run PhpMetrics - run: ./vendor/bin/phpmetrics --exclude=Exception src - - static-analysis-composer-require-checker: - name: Static Analysis with ComposerRequireChecker - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - coverage: none - - - name: Get composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Install dependencies - run: | - composer install --no-interaction --no-progress --prefer-dist - composer require --dev maglnet/composer-require-checker ^2.0 - - - name: Run composer-require-checker - run: ./vendor/bin/composer-require-checker check --config-file=./php-require-checker.config.json ./composer.json + sa: + uses: ray-di/.github/.github/workflows/static-analysis.yml@v1 + with: + php_version: 8.3 diff --git a/.scrutinizer.yml b/.scrutinizer.yml index c2e2aeb..9c4042c 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -1,18 +1,12 @@ +build: + nodes: + analysis: + tests: + override: + - php-scrutinizer-run + environment: + php: + version: 8.2 + filter: paths: ["src/*"] -tools: - external_code_coverage: true - php_code_coverage: true - php_sim: true - php_mess_detector: true - php_pdepend: true - php_analyzer: true - php_cpd: true - php_mess_detector: - enabled: true - config: - ruleset: ./phpmd.xml - php_code_sniffer: - enabled: true - config: - ruleset: ./phpcs.xml diff --git a/build.xml b/build.xml deleted file mode 100644 index 24a53ea..0000000 --- a/build.xml +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/composer.json b/composer.json index a2db358..7ab47c0 100644 --- a/composer.json +++ b/composer.json @@ -26,15 +26,14 @@ ] }, "require": { - "php": "^7.3 || ^8.0", + "php": "^8.1", "bear/resource": "^1.15.1", "bear/sunday": "^1.5", "ray/di": "^2.11", "ray/aop": "^2.10.4" }, "require-dev": { - "phpunit/phpunit": "^9.5", - "doctrine/annotations": "^1.7", + "phpunit/phpunit": "^9.6.19", "bamarni/composer-bin-plugin": "^1.4" }, "scripts" :{ @@ -51,5 +50,10 @@ "metrics": ["./vendor/bin/phpmetrics --report-html=build/metrics --exclude=Exception --junit=build/junit.xml src"], "phpmd": ["./vendor/bin/phpmd --exclude src/Annotation src text ./phpmd.xml"], "build": ["@cs", "@sa", "@pcov", "@metrics"] + }, + "config": { + "allow-plugins": { + "bamarni/composer-bin-plugin": true + } } } diff --git a/phpstan.neon b/phpstan.neon index 70c087d..871b347 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,5 +3,5 @@ parameters: paths: - src - tests - excludes_analyse: + excludePaths: - 'tests/Fake' diff --git a/src/Annotation/Stream.php b/src/Annotation/Stream.php index 596d7fc..5f76f03 100644 --- a/src/Annotation/Stream.php +++ b/src/Annotation/Stream.php @@ -9,11 +9,6 @@ use function is_string; use function var_dump; -/** - * @Annotation - * @Target("METHOD") - * @Qualifier - */ #[Attribute(Attribute::TARGET_METHOD), Qualifier] final class Stream { diff --git a/src/StreamProvider.php b/src/StreamProvider.php index 01de826..d58376f 100644 --- a/src/StreamProvider.php +++ b/src/StreamProvider.php @@ -10,6 +10,7 @@ use function fopen; use function is_resource; +/** @implements ProviderInterface */ class StreamProvider implements ProviderInterface { /** diff --git a/src/StreamRenderer.php b/src/StreamRenderer.php index ccafcef..ef9c6cf 100644 --- a/src/StreamRenderer.php +++ b/src/StreamRenderer.php @@ -7,31 +7,28 @@ use BEAR\Resource\RenderInterface; use BEAR\Resource\ResourceObject; +use function assert; use function get_resource_type; use function is_array; +use function is_iterable; use function is_resource; -use function mt_rand; +use function mt_getrandmax; +use function random_int; use function uniqid; final class StreamRenderer implements RenderInterface { - /** @var RenderInterface */ - private $renderer; - /** * Pushed stream * * @var resource[] */ - private $streams = []; - - /** @var StreamerInterface */ - private $streamer; + private array $streams = []; - public function __construct(RenderInterface $renderer, StreamerInterface $streamer) - { - $this->renderer = $renderer; - $this->streamer = $streamer; + public function __construct( + private readonly RenderInterface $renderer, + private readonly StreamerInterface $streamer + ) { } /** @@ -60,12 +57,10 @@ public function getView(ResourceObject $ro): string return $this->pushScalarBody($ro); } - /** - * @param resource $item - */ + /** @param resource $item */ private function pushStream($item): string { - $id = uniqid(__FUNCTION__ . mt_rand(), true) . '_'; + $id = uniqid(__FUNCTION__ . random_int(0, mt_getrandmax()), true) . '_'; $this->streams[$id] = $item; // push return $id; @@ -82,6 +77,7 @@ private function pushScalarBody(ResourceObject $ro): string private function pushArrayBody(ResourceObject $ro): void { + assert(is_iterable($ro->body)); foreach ($ro->body as &$item) { if (is_resource($item) && get_resource_type($item) === 'stream') { $item = $this->pushStream($item); diff --git a/src/StreamResponder.php b/src/StreamResponder.php index 232942c..7ba8d37 100644 --- a/src/StreamResponder.php +++ b/src/StreamResponder.php @@ -12,14 +12,12 @@ use function http_response_code; use function rewind; +use const PHP_SAPI; + class StreamResponder implements TransferInterface { - /** @var StreamerInterface */ - private $streamer; - - public function __construct(StreamerInterface $streamer) + public function __construct(private readonly StreamerInterface $streamer) { - $this->streamer = $streamer; } /** @@ -29,7 +27,7 @@ public function __invoke(ResourceObject $resourceObject, array $server): void { unset($server); // render - if (! $resourceObject->view) { + if ($resourceObject->view === null) { $resourceObject->toString(); } @@ -39,7 +37,9 @@ public function __invoke(ResourceObject $resourceObject, array $server): void } // code - http_response_code($resourceObject->code); + if (PHP_SAPI !== 'cli') { + http_response_code($resourceObject->code); + } // stream body $stream = $this->streamer->getStream((string) $resourceObject->view); diff --git a/src/StreamTransferInject.php b/src/StreamTransferInject.php index 8537be0..6e547e0 100644 --- a/src/StreamTransferInject.php +++ b/src/StreamTransferInject.php @@ -14,23 +14,16 @@ trait StreamTransferInject /** @var TransferInterface */ private $responder; - /** - * @return static - * - * @Inject - * @Stream - */ - #[Inject, Stream] + /** @return static */ + #[Inject] + #[Stream] public function setRenderer(RenderInterface $render) { return parent::setRenderer($render); } - /** - * @Inject - * @Stream - */ - #[Inject, Stream] + #[Inject] + #[Stream] public function setTransfer(TransferInterface $responder): void { $this->responder = $responder; @@ -42,6 +35,7 @@ public function setTransfer(TransferInterface $responder): void public function transfer(TransferInterface $responder, array $server): void { unset($responder); + parent::transfer($this->responder, $server); } } diff --git a/src/Streamer.php b/src/Streamer.php index 59a09d5..a3520cf 100644 --- a/src/Streamer.php +++ b/src/Streamer.php @@ -20,26 +20,16 @@ final class Streamer implements StreamerInterface { - /** @var resource */ - private $stream; - /** @var array */ - private $streams = []; + private array $streams = []; - /** - * @param resource $stream - * - * @Stream - */ + /** @param resource $stream */ #[Stream] - public function __construct($stream) + public function __construct(private $stream) { - $this->stream = $stream; } - /** - * @param resource[] $streams - */ + /** @param resource[] $streams */ public function addStreams(array $streams): void { $this->streams += $streams; diff --git a/src/StreamerInterface.php b/src/StreamerInterface.php index b837ed0..e8f0cb1 100644 --- a/src/StreamerInterface.php +++ b/src/StreamerInterface.php @@ -6,9 +6,7 @@ interface StreamerInterface { - /** - * @param resource[] $streams - */ + /** @param resource[] $streams */ public function addStreams(array $streams): void; /** diff --git a/tests/IntegrateTest.php b/tests/IntegrateTest.php index e87f7cc..fb20bc7 100644 --- a/tests/IntegrateTest.php +++ b/tests/IntegrateTest.php @@ -24,15 +24,9 @@ class IntegrateTest extends TestCase { /** @var array> */ public static $headers = []; - - /** @var ResourceInterface */ - private $resource; - - /** @var RenderInterface */ - private $renderer; - - /** @var Streamer */ - private $streamer; + private ResourceInterface $resource; + private RenderInterface $renderer; + private StreamerInterface $streamer; protected function setUp(): void { @@ -42,9 +36,7 @@ protected function setUp(): void $this->streamer = $injector->getInstance(StreamerInterface::class); } - /** - * @return array> - */ + /** @return array> */ public function caseProvider(): array { return [ @@ -79,9 +71,7 @@ public function caseProvider(): array ]; } - /** - * @dataProvider caseProvider - */ + /** @dataProvider caseProvider */ public function testRender(string $uri, string $expected): void { $ro = $this->resource->newInstance($uri); diff --git a/vendor-bin/tools/composer.json b/vendor-bin/tools/composer.json index d7fbc7a..c0f3030 100644 --- a/vendor-bin/tools/composer.json +++ b/vendor-bin/tools/composer.json @@ -1,11 +1,16 @@ { "require": { - "doctrine/coding-standard": "^8.2", + "doctrine/coding-standard": "^11", "phpmd/phpmd": "^2.9", "phpmetrics/phpmetrics": "^2.7", "phpstan/phpstan": "^0.12", "psalm/plugin-phpunit": "^0.13", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^4.2" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } } }