From 873f318eeaea7c7027082fa89aed2446902844d6 Mon Sep 17 00:00:00 2001 From: Max Antipin Date: Sun, 5 Apr 2026 14:50:03 +0300 Subject: [PATCH] Update Docker setup, composer configuration, and Makefile Simplify testing workflow by replacing `test.sh` with Makefile targets (`lint`, `test-cs`, `test-all`). Update Dockerfile to support PHP 8.3 and add new dependencies. Adjust composer constraints and `composer.json` autoload paths. Streamline `.gitattributes` and README for improved clarity. --- .docker/Dockerfile | 14 ++-- .docker/compose-test.yaml | 2 +- .docker/compose.yaml | 4 +- .gitattributes | 12 ++- Makefile | 23 +++-- README.md | 171 +++++++++++++++++++------------------- composer.json | 12 +-- test.sh | 10 --- 8 files changed, 125 insertions(+), 123 deletions(-) delete mode 100644 test.sh diff --git a/.docker/Dockerfile b/.docker/Dockerfile index d8a5377..b94e980 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -1,8 +1,8 @@ #syntax=docker/dockerfile:1.16 -ARG PHP_VERSION=8.2 -ARG COMPOSER_VERSION=2.7 -ARG CS_BRANCH=3.13.2 +ARG PHP_VERSION=8.3 +ARG COMPOSER_VERSION=2.9 +ARG CS_BRANCH=3.13.5 FROM composer:${COMPOSER_VERSION} AS composer_image @@ -11,7 +11,7 @@ ARG CS_BRANCH RUN set -eu; \ apk update \ && apk upgrade \ - && apk add --no-cache git linux-headers \ + && apk add --no-cache git linux-headers make \ && apk add --update --no-cache --virtual .build-dependencies $PHPIZE_DEPS \ && pecl install xdebug \ && docker-php-ext-enable xdebug \ @@ -26,7 +26,8 @@ COPY --from=composer_image --link /usr/bin/composer /usr/local/bin/composer WORKDIR /usr/src/cs-test/ RUN set -eu; \ git clone https://github.com/PHPCSStandards/PHP_CodeSniffer.git --branch ${CS_BRANCH} --single-branch . \ - && composer install + && composer install \ + && composer require --dev --no-scripts --no-plugins max-antipin/php-code-sniffs WORKDIR /usr/src/app/ FROM dev_image AS test_image @@ -35,6 +36,7 @@ RUN --mount=type=bind,from=git-files,source=.,target=.git,readonly \ set -eu; \ git clean --force; \ composer validate; \ - composer install + composer install --no-autoloader --no-progress; \ + composer dump-autoload --classmap-authoritative --strict-psr --strict-ambiguous COPY phpunit.9.xml /usr/src/cs-test/phpunit.xml COPY --from=source ./AntipinCS/ /usr/src/cs-test/src/Standards/AntipinCS/ \ No newline at end of file diff --git a/.docker/compose-test.yaml b/.docker/compose-test.yaml index e0b682d..cb2654c 100644 --- a/.docker/compose-test.yaml +++ b/.docker/compose-test.yaml @@ -16,7 +16,7 @@ x-php-service: &php-service services: php-84: <<: *php-service - command: ["./test.sh"] + command: ["make", "lint", "test-cs"] environment: XDEBUG_MODE: coverage volumes: &volumes diff --git a/.docker/compose.yaml b/.docker/compose.yaml index 94a36d4..45e774b 100644 --- a/.docker/compose.yaml +++ b/.docker/compose.yaml @@ -3,7 +3,7 @@ services: php-dev: build: args: - - PHP_VERSION=${PHP_VERSION:-8.2} + - PHP_VERSION=${PHP_VERSION:-8.3} context: ../. dockerfile: ./.docker/Dockerfile target: dev_image @@ -31,7 +31,7 @@ services: target: dev_image configs: *dev_configs container_name: ${COMPOSE_PROJECT_NAME}-dev-coverage - command: ./test.sh + command: make test-cs lint environment: XDEBUG_MODE: coverage image: max-antipin/${COMPOSE_PROJECT_NAME}:dev-coverage diff --git a/.gitattributes b/.gitattributes index 30605fc..03bd40a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,10 +1,8 @@ -.* export-ignore -*.sh export-ignore -Makefile export-ignore -phpcs.xml.dist export-ignore -phpstan.neon.dist export-ignore -phpunit.xml.dist export-ignore -Tests export-ignore +.* export-ignore +*.sh export-ignore +Makefile export-ignore +*.dist export-ignore +Tests export-ignore *.sh text eol=lf .docker/* text eol=lf \ No newline at end of file diff --git a/Makefile b/Makefile index 39e571d..4adf71c 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,26 @@ up: - docker compose -f .docker/compose.yaml up -d; \ + docker compose -f .docker/compose.yaml up -d --build docker compose -f .docker/compose.yaml run --rm --remove-orphans php-dev composer install down: docker compose -f .docker/compose.yaml down -pre-release: - docker compose -f .docker/compose.yaml run --rm --remove-orphans php-dev composer validate --strict; \ - ./vendor/bin/export-ignore +shell: + docker exec -it php-code-sniffs-dev /bin/sh check-dockerfile: - docker run --rm -i ghcr.io/hadolint/hadolint < .docker/Dockerfile \ No newline at end of file + docker run --rm -i ghcr.io/hadolint/hadolint < .docker/Dockerfile + +lint: + php ./vendor/bin/phpcs + php ./vendor/bin/phpstan analyze + php ./vendor/bin/phpcs-check-feature-completeness + +test-cs: + cd ../cs-test/ && XDEBUG_MODE=coverage php ./vendor/bin/phpunit --filter AntipinCS + +check-build: + composer validate --strict + php ./vendor/bin/export-ignore + +test-all: lint test-cs check-build \ No newline at end of file diff --git a/README.md b/README.md index f41fdfb..023f3ab 100644 --- a/README.md +++ b/README.md @@ -1,86 +1,85 @@ -# Sniffs for [PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer) by Max Antipin - -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) -[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=bugs)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) -[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) -[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) -[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) - -[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) -[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) -[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) -[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) -[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) - -## Development & testing - -Start dev container: -```Shell -docker compose -f .docker/compose.yaml up -d -``` - -For the first time run: -```Shell -docker exec php-code-sniffs-dev composer install -``` - -Enter dev container: -```Shell -docker exec -it php-code-sniffs-dev sh -``` - -Run all tests (or view this file to get list of commands for testing): -```Shell -./test.sh -``` - -Run all tests without creating one more service: -```Shell -PHP_VERSION=8.3 docker compose -f .docker/compose.yaml run --rm --build --quiet-build -e XDEBUG_MODE=off php-dev ./test.sh -``` - -Run service with test coverage: -```Shell -docker compose -f .docker/compose.yaml up dev-coverage -``` -The results will be stored in `var/coverage-report/`. - -Below `PHP 8.4` there is a conflict between `PHP_CodeSniffer` and `nikic/php-parser` which causes fatal error: `Token T_PUBLIC_SET has ID of type string, should be int. You may be using a library with broken token emulation`. `nikic/php-parser` package is used by `PHPUnit` while calculation code coverage. - -`PHP_CodeSniffer` file `src/Util/Tokens.php`, lines `183-194`: -```PHP -// Some PHP 8.4 tokens, replicated for lower versions. -if (defined('T_PUBLIC_SET') === false) { - define('T_PUBLIC_SET', 'PHPCS_T_PUBLIC_SET'); -} - -if (defined('T_PROTECTED_SET') === false) { - define('T_PROTECTED_SET', 'PHPCS_T_PROTECTED_SET'); -} - -if (defined('T_PRIVATE_SET') === false) { - define('T_PRIVATE_SET', 'PHPCS_T_PRIVATE_SET'); -} -``` - -`nikic/php-parser` file `lib/PhpParser/compatibility_tokens.php`, lines `34-42`: -```PHP - foreach ($compatTokens as $token) { - if (\defined($token)) { - $tokenId = \constant($token); - if (!\is_int($tokenId)) { - throw new \Error(sprintf( - 'Token %s has ID of type %s, should be int. ' . - 'You may be using a library with broken token emulation', - $token, \gettype($tokenId) - )); - } - // ... - } - } -``` - -Run test containers with all PHP versions and code coverage: -```Shell -docker compose -f .docker/compose-test.yaml up --quiet-build -``` +# Sniffs for [PHP_CodeSniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer) by Max Antipin + +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) +[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=bugs)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) +[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) +[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) +[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) + +[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) +[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) +[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) +[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) +[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=max-antipin_php-code-sniffs&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=max-antipin_php-code-sniffs) + +```Shell +composer require --dev max-antipin/php-code-sniffs +``` + +## Development & testing + +Start a dev container and install dependencies: +```Shell +make up +``` + +Enter the dev container: +```Shell +make shell +``` + +Run all tests: +```Shell +make test-all +``` + +Run all tests without creating one more service: +```Shell +PHP_VERSION=8.3 docker compose -f .docker/compose.yaml run --rm --build --quiet-build -e XDEBUG_MODE=off php-dev make test-all +``` + +Run service with test coverage: +```Shell +docker compose -f .docker/compose.yaml up dev-coverage +``` +The results will be stored in `var/coverage-report/`. + +Below `PHP 8.4` there is a conflict between `PHP_CodeSniffer` and `nikic/php-parser` which causes fatal error: `Token T_PUBLIC_SET has ID of type string, should be int. You may be using a library with broken token emulation`. `nikic/php-parser` package is used by `PHPUnit` while calculation code coverage. + +`PHP_CodeSniffer` file `src/Util/Tokens.php`, lines `183-194`: +```PHP +// Some PHP 8.4 tokens, replicated for lower versions. +if (defined('T_PUBLIC_SET') === false) { + define('T_PUBLIC_SET', 'PHPCS_T_PUBLIC_SET'); +} + +if (defined('T_PROTECTED_SET') === false) { + define('T_PROTECTED_SET', 'PHPCS_T_PROTECTED_SET'); +} + +if (defined('T_PRIVATE_SET') === false) { + define('T_PRIVATE_SET', 'PHPCS_T_PRIVATE_SET'); +} +``` + +`nikic/php-parser` file `lib/PhpParser/compatibility_tokens.php`, lines `34-42`: +```PHP + foreach ($compatTokens as $token) { + if (\defined($token)) { + $tokenId = \constant($token); + if (!\is_int($tokenId)) { + throw new \Error(sprintf( + 'Token %s has ID of type %s, should be int. ' . + 'You may be using a library with broken token emulation', + $token, \gettype($tokenId) + )); + } + // ... + } + } +``` + +Run test containers with all PHP versions and code coverage: +```Shell +docker compose -f .docker/compose-test.yaml up --quiet-build +``` diff --git a/composer.json b/composer.json index a2a3dfb..2d76104 100644 --- a/composer.json +++ b/composer.json @@ -19,13 +19,13 @@ ], "license": "Unlicense", "require": { - "php": ">=8.2", - "squizlabs/php_codesniffer": "^3", - "dealerdirect/phpcodesniffer-composer-installer": "^1" + "php": ">=8.3", + "squizlabs/php_codesniffer": "^3.13", + "dealerdirect/phpcodesniffer-composer-installer": "^1.2" }, "require-dev": { - "phpstan/phpstan": "^2", - "phpcsstandards/phpcsdevtools": "^1.0", + "phpstan/phpstan": "^2.1", + "phpcsstandards/phpcsdevtools": "^1.2", "max-antipin/packagist-export-ignore": "^1" }, "autoload": { @@ -34,7 +34,7 @@ "MaxAntipin\\PHPCS\\Lib\\": "Lib/" }, "exclude-from-classmap": [ - "/Tests/" + "/AntipinCS/Tests/" ] }, "autoload-dev": { diff --git a/test.sh b/test.sh deleted file mode 100644 index 6c4cdf3..0000000 --- a/test.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -set -eu - -cd ../cs-test/ -php ./vendor/bin/phpunit --filter AntipinCS - -cd ../app/ -php ./vendor/bin/phpcs -php ./vendor/bin/phpstan analyze -php ./vendor/bin/phpcs-check-feature-completeness \ No newline at end of file