diff --git a/.coveralls.yml b/.coveralls.yml index 1621caa9..30b618e3 100644 --- a/.coveralls.yml +++ b/.coveralls.yml @@ -1,3 +1,2 @@ coverage_clover: build/logs/clover.xml json_path: build/logs/coveralls-upload.json -service_name: travis-ci diff --git a/.gitattributes b/.gitattributes index b8f7709c..814f5484 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,10 +8,11 @@ /.coveralls.yml export-ignore /.gitattributes export-ignore /.gitignore export-ignore -/.travis.yml export-ignore +/.github/ export-ignore /phpcs.xml.dist export-ignore /phpunit.xml.dist export-ignore /phpunit-bootstrap.php export-ignore +/Modernize/Tests/ export-ignore /NormalizedArrays/Tests/ export-ignore /Universal/Tests/ export-ignore diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..56043bed --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,76 @@ +--- +name: "\U0001F41B Bug report for sniffs" +about: I got unexpected behavior and think it is a bug. + +--- + + + +## Bug Description + + + +## Given the following reproduction Scenario + + +The issue happens when running this command: + +```bash +phpcs -ps file.php --standard=... +``` + +... over a file containing this code: +```php +// Place your code sample here. +``` + + +... with this custom ruleset: +```xml + + + ... + +``` + + +### I'd expect the following behaviour + + + +### Instead this happened + + + +## Environment + + +| Environment | Answer +| ------------------------ | ------- +| PHP version | x.y.z +| PHP_CodeSniffer version | x.y.z +| PHPCSExtra version | x.y.z +| PHPCSUtils version | x.y.z +| Install type | e.g. Composer global, Composer project local, git clone, other (please expand) + + +## Additional Context (optional) + + + +## Tested Against `develop` branch? +- [ ] I have verified the issue still exists in the `develop` branch of PHPCSExtra. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..25a15a41 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: "\U0001F680 Feature request" +about: I have a suggestion (and may want to implement it). +--- + +## Is your feature request related to a problem? + + +## Describe the solution you'd like + + +## Additional context (optional) + + +- [ ] I intend to create a pull request to implement this feature. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..d7bb986a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,27 @@ +# Dependabot configuration. +# +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 # Set to 0 to (temporarily) disable. + versioning-strategy: widen + commit-message: + prefix: "Composer:" + labels: + - "Type: chores/QA" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + commit-message: + prefix: "GH Actions:" + labels: + - "Type: chores/QA" diff --git a/.github/workflows/basics.yml b/.github/workflows/basics.yml new file mode 100644 index 00000000..9029b26a --- /dev/null +++ b/.github/workflows/basics.yml @@ -0,0 +1,98 @@ +name: CS + +on: + # Run on all pushes and on all pull requests. + # Prevent the build from running when there are only irrelevant changes. + push: + paths-ignore: + - '**.md' + pull_request: + # Allow manually triggering the workflow. + workflow_dispatch: + +# Cancels all previous workflow runs for the same branch that have not yet completed. +concurrency: + # The concurrency group contains the workflow name and the branch name. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + checkcs: + name: 'Basic CS and QA checks' + runs-on: ubuntu-latest + + env: + XMLLINT_INDENT: ' ' + # - COMPOSER_ROOT_VERSION is needed to get round the recursive dependency when using CI. + COMPOSER_ROOT_VERSION: '1.99.99' + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 'latest' + coverage: none + tools: cs2pr + + - name: 'Composer: adjust dependencies' + run: | + # The sniff stage doesn't run the unit tests, so no need for PHPUnit. + composer remove --no-update --dev phpunit/phpunit --no-scripts --no-interaction + # Using PHPCS `master` as an early detection system for bugs upstream. + composer require --no-update squizlabs/php_codesniffer:"dev-master" --no-interaction + + # Install dependencies and handle caching in one go. + # @link https://github.com/marketplace/actions/install-composer-dependencies + - name: Install Composer dependencies + uses: "ramsey/composer-install@v2" + with: + # Bust the cache at least once a month - output format: YYYY-MM-DD. + custom-cache-suffix: $(date -u -d "-0 month -$(($(date +%d)-1)) days" "+%F") + + - name: Install xmllint + run: | + sudo apt-get update + sudo apt-get install --no-install-recommends -y libxml2-utils + + # Show XML violations inline in the file diff. + # @link https://github.com/marketplace/actions/xmllint-problem-matcher + - uses: korelstar/xmllint-problem-matcher@v1 + + # Validate the Ruleset XML file. + # @link http://xmlsoft.org/xmllint.html + - name: Validate rulesets against schema + run: xmllint --noout --schema vendor/squizlabs/php_codesniffer/phpcs.xsd ./*/ruleset.xml + + # Check the code-style consistency of the XML ruleset files. + - name: Check XML code style + run: | + diff -B ./Modernize/ruleset.xml <(xmllint --format "./Modernize/ruleset.xml") + diff -B ./NormalizedArrays/ruleset.xml <(xmllint --format "./NormalizedArrays/ruleset.xml") + diff -B ./Universal/ruleset.xml <(xmllint --format "./Universal/ruleset.xml") + + # Validate the Documentation XML files. + - name: Validate documentation against schema + run: xmllint --noout --schema vendor/phpcsstandards/phpcsdevtools/DocsXsd/phpcsdocs.xsd ./*/Docs/*/*Standard.xml + + # Check the code-style consistency of the PHP files. + - name: Check PHP code style + id: phpcs + run: vendor/bin/phpcs --report-full --report-checkstyle=./phpcs-report.xml + + - name: Show PHPCS results in PR + if: ${{ always() && steps.phpcs.outcome == 'failure' }} + run: cs2pr ./phpcs-report.xml + + # Check that the sniffs available are feature complete. + # For now, just check that all sniffs have unit tests. + # At a later stage the documentation check can be activated. + - name: Check sniff feature completeness + run: composer check-complete + + # Validate the composer.json file. + # @link https://getcomposer.org/doc/03-cli.md#validate + - name: Validate Composer installation + run: composer validate --no-check-all --strict diff --git a/.github/workflows/quicktest.yml b/.github/workflows/quicktest.yml new file mode 100644 index 00000000..90c699e0 --- /dev/null +++ b/.github/workflows/quicktest.yml @@ -0,0 +1,88 @@ +name: Quicktest + +on: + # Run on pushes, including merges, to all branches except for `stable` and `develop`. + push: + branches-ignore: + - stable + - develop + paths-ignore: + - '**.md' + # Allow manually triggering the workflow. + workflow_dispatch: + +# Cancels all previous workflow runs for the same branch that have not yet completed. +concurrency: + # The concurrency group contains the workflow name and the branch name. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + #### QUICK TEST STAGE #### + # This is a much quicker test which only runs the unit tests and linting against the low/high + # supported PHP/PHPCS combinations. + # These are basically the same builds as in the Test->Coverage workflow, but then without doing + # the code-coverage. + quicktest: + runs-on: ubuntu-latest + + strategy: + matrix: + php: ['5.4', 'latest'] + phpcs_version: ['3.7.1', 'dev-master'] + + name: "QTest${{ matrix.phpcs_version == 'dev-master' && ' + Lint' || '' }}: PHP ${{ matrix.php }} - PHPCS ${{ matrix.phpcs_version }}" + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + # On stable PHPCS versions, allow for PHP deprecation notices. + # Unit tests don't need to fail on those for stable releases where those issues won't get fixed anymore. + - name: Setup ini config + id: set_ini + run: | + if [ "${{ matrix.phpcs_version }}" != "dev-master" ]; then + echo 'PHP_INI=error_reporting=E_ALL & ~E_DEPRECATED, display_errors=On' >> $GITHUB_OUTPUT + else + echo 'PHP_INI=error_reporting=-1, display_errors=On' >> $GITHUB_OUTPUT + fi + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + ini-values: ${{ steps.set_ini.outputs.PHP_INI }} + coverage: none + + - name: 'Composer: set PHPCS version for tests' + run: composer require --no-update --no-scripts squizlabs/php_codesniffer:"${{ matrix.phpcs_version }}" --no-interaction + + # Install dependencies and handle caching in one go. + # @link https://github.com/marketplace/actions/install-composer-dependencies + - name: Install Composer dependencies - normal + if: matrix.php != 'latest' + uses: "ramsey/composer-install@v2" + with: + # Bust the cache at least once a month - output format: YYYY-MM-DD. + custom-cache-suffix: $(date -u -d "-0 month -$(($(date +%d)-1)) days" "+%F") + + # For the PHP "latest", we need to install with ignore platform reqs as not all PHPUnit 7.x dependencies allow it. + - name: Install Composer dependencies - with ignore platform + if: matrix.php == 'latest' + uses: "ramsey/composer-install@v2" + with: + composer-options: --ignore-platform-reqs + custom-cache-suffix: $(date -u -d "-0 month -$(($(date +%d)-1)) days" "+%F") + + - name: Lint against parse errors + if: matrix.phpcs_version == 'dev-master' + run: composer lint + + - name: Run the unit tests - PHP 5.4 - 8.0 + if: matrix.php != 'latest' + run: composer test + + - name: Run the unit tests - PHP > 8.1 + if: matrix.php == 'latest' + run: composer test -- --no-configuration --bootstrap=phpunit-bootstrap.php --dont-report-useless-tests diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..bc82d4aa --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,188 @@ +name: Test + +on: + # Run on pushes to `stable` and `develop` and on all pull requests. + push: + branches: + - stable + - develop + paths-ignore: + - '**.md' + pull_request: + # Allow manually triggering the workflow. + workflow_dispatch: + +# Cancels all previous workflow runs for the same branch that have not yet completed. +concurrency: + # The concurrency group contains the workflow name and the branch name. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + #### TEST STAGE #### + test: + if: ${{ github.ref != 'refs/heads/develop' }} + runs-on: ubuntu-latest + + strategy: + matrix: + # The GHA matrix works different from Travis. + # You can define jobs here and then augment them with extra variables in `include`, + # as well as add extra jobs in `include`. + # @link https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix + # + # The matrix is set up so as not to duplicate the builds which are run for code coverage. + php: ['5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '8.0', '8.1', '8.2'] + phpcs_version: ['3.7.1', 'dev-master'] + + name: "Test${{ matrix.phpcs_version == 'dev-master' && ' + Lint' || '' }}: PHP ${{ matrix.php }} - PHPCS ${{ matrix.phpcs_version }}" + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + # On stable PHPCS versions, allow for PHP deprecation notices. + # Unit tests don't need to fail on those for stable releases where those issues won't get fixed anymore. + - name: Setup ini config + id: set_ini + run: | + if [[ "${{ matrix.phpcs_version }}" != "dev-master" ]]; then + echo 'PHP_INI=error_reporting=E_ALL & ~E_DEPRECATED, display_errors=On' >> $GITHUB_OUTPUT + else + echo 'PHP_INI=error_reporting=-1, display_errors=On' >> $GITHUB_OUTPUT + fi + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + ini-values: ${{ steps.set_ini.outputs.PHP_INI }} + coverage: none + + - name: 'Composer: set PHPCS version for tests' + run: composer require --no-update squizlabs/php_codesniffer:"${{ matrix.phpcs_version }}" --no-interaction + + # Install dependencies and handle caching in one go. + # @link https://github.com/marketplace/actions/install-composer-dependencies + - name: Install Composer dependencies - normal + if: ${{ startsWith( matrix.php, '8' ) == false }} + uses: "ramsey/composer-install@v2" + with: + # Bust the cache at least once a month - output format: YYYY-MM-DD. + custom-cache-suffix: $(date -u -d "-0 month -$(($(date +%d)-1)) days" "+%F") + + # For the PHP 8/"nightly", we need to install with ignore platform reqs as we're still using PHPUnit 7. + - name: Install Composer dependencies - with ignore platform + if: ${{ startsWith( matrix.php, '8' ) }} + uses: "ramsey/composer-install@v2" + with: + composer-options: --ignore-platform-reqs + custom-cache-suffix: $(date -u -d "-0 month -$(($(date +%d)-1)) days" "+%F") + + - name: Lint against parse errors + if: matrix.phpcs_version == 'dev-master' + run: composer lint + + - name: Run the unit tests - PHP 5.4 - 8.0 + if: ${{ matrix.php < '8.1' }} + run: composer test + + - name: Run the unit tests - PHP > 8.1 + if: ${{ matrix.php >= '8.1' }} + run: composer test -- --no-configuration --bootstrap=phpunit-bootstrap.php --dont-report-useless-tests + + #### CODE COVERAGE STAGE #### + # N.B.: Coverage is only checked on the lowest and highest stable PHP versions + # and a low/high of each major for PHPCS. + # These builds are left out off the "test" stage so as not to duplicate test runs. + coverage: + # No use running the coverage builds if there are failing test builds. + needs: test + # The default condition is success(), but this is false when one of the previous jobs is skipped + if: always() && (needs.test.result == 'success' || needs.test.result == 'skipped') + + runs-on: ubuntu-latest + + strategy: + matrix: + # 7.4 should be updated to 8.2 when higher PHPUnit versions can be supported. + php: ['5.4', '7.4'] + phpcs_version: ['3.7.1', 'dev-master'] + + name: "Coverage${{ matrix.phpcs_version == 'dev-master' && ' + Lint' || '' }}: PHP ${{ matrix.php }} - PHPCS ${{ matrix.phpcs_version }}" + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + # On stable PHPCS versions, allow for PHP deprecation notices. + # Unit tests don't need to fail on those for stable releases where those issues won't get fixed anymore. + - name: Setup ini config + id: set_ini + run: | + if [ "${{ matrix.phpcs_version }}" != "dev-master" ]; then + echo 'PHP_INI=error_reporting=E_ALL & ~E_DEPRECATED, display_errors=On' >> $GITHUB_OUTPUT + else + echo 'PHP_INI=error_reporting=-1, display_errors=On' >> $GITHUB_OUTPUT + fi + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + ini-values: ${{ steps.set_ini.outputs.PHP_INI }} + coverage: xdebug + tools: cs2pr + + - name: 'Composer: adjust dependencies' + run: | + # Set a specific PHPCS version. + composer require --no-update squizlabs/php_codesniffer:"${{ matrix.phpcs_version }}" --no-scripts --no-interaction + + # Install dependencies and handle caching in one go. + # @link https://github.com/marketplace/actions/install-composer-dependencies + - name: Install Composer dependencies + uses: "ramsey/composer-install@v2" + with: + # Bust the cache at least once a month - output format: YYYY-MM-DD. + custom-cache-suffix: $(date -u -d "-0 month -$(($(date +%d)-1)) days" "+%F") + + - name: Lint against parse errors + if: matrix.phpcs_version == 'dev-master' + run: composer lint -- --checkstyle | cs2pr + + - name: Run the unit tests with code coverage + run: composer coverage + + # Uploading the results with PHP Coveralls v1 won't work from GH Actions, so switch the PHP version. + - name: Switch to PHP 7.4 + if: ${{ success() && matrix.php != '7.4' }} + uses: shivammathur/setup-php@v2 + with: + php-version: 7.4 + coverage: none + + - name: Install Coveralls + if: ${{ success() }} + run: composer require php-coveralls/php-coveralls:"^2.5.3" --no-interaction + + - name: Upload coverage results to Coveralls + if: ${{ success() }} + env: + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COVERALLS_PARALLEL: true + COVERALLS_FLAG_NAME: php-${{ matrix.php }}-phpcs-${{ matrix.phpcs_version }} + run: vendor/bin/php-coveralls -v -x build/logs/clover.xml + + coveralls-finish: + needs: coverage + if: always() && needs.coverage.result == 'success' + + runs-on: ubuntu-latest + + steps: + - name: Coveralls Finished + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + parallel-finished: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e20d7c2b..00000000 --- a/.travis.yml +++ /dev/null @@ -1,198 +0,0 @@ -dist: trusty - -language: php - -## Cache composer and apt downloads. -cache: - apt: true - directories: - # Cache directory for older Composer versions. - - $HOME/.composer/cache/files - # Cache directory for more recent Composer versions. - - $HOME/.cache/composer/files - -php: - - 5.5 - - 5.6 - - 7.0 - - 7.1 - - 7.2 - -env: - jobs: - # PHPCS `master`. - - PHPCS_VERSION="dev-master" LINT=1 - # Lowest supported PHPCS version. - - PHPCS_VERSION="3.3.1" - -# Define the stages used. -# For non-PRs, only the sniff and quicktest stages are run. -# For pull requests and merges, the full script is run (skipping quicktest). -# Note: for pull requests, "develop" is the base branch name. -# See: https://docs.travis-ci.com/user/conditions-v1 -stages: - - name: sniff - - name: validate - - name: quicktest - if: type = push AND branch NOT IN (stable, develop) - - name: test - if: branch IN (stable, develop) - - name: coverage - if: branch IN (stable, develop) - -jobs: - fast_finish: true - - include: - #### SNIFF STAGE #### - - stage: sniff - php: 7.4 - install: skip - before_script: skip - script: - # Check the code style of the code base. - - composer travis-checkcs - - - stage: validate - php: 7.4 - env: PHPCS_VERSION="dev-master" - addons: - apt: - packages: - - libxml2-utils - script: - # Validate the composer.json file. - # @link https://getcomposer.org/doc/03-cli.md#validate - - composer validate --no-check-all --strict - - # Validate the xml files. - # @link http://xmlsoft.org/xmllint.html - - xmllint --noout --schema ./vendor/squizlabs/php_codesniffer/phpcs.xsd ./NormalizedArrays/ruleset.xml - - xmllint --noout --schema ./vendor/squizlabs/php_codesniffer/phpcs.xsd ./Universal/ruleset.xml - - # Check the code-style consistency of the xml files. - - diff -B ./NormalizedArrays/ruleset.xml <(xmllint --format "./NormalizedArrays/ruleset.xml") - - diff -B ./Universal/ruleset.xml <(xmllint --format "./Universal/ruleset.xml") - - # Check that the sniffs available are feature complete. - - composer check-complete - - #### QUICK TEST STAGE #### - # This is a much quicker test which only runs the unit tests and linting against the low/high - # supported PHP/PHPCS combinations. - # These are basically the same builds as in the Coverage stage, but then without doing - # the code-coverage. - - stage: quicktest - php: 7.4 - env: PHPCS_VERSION="dev-master" LINT=1 - - php: 7.3 - env: PHPCS_VERSION="3.3.1" - - - php: 5.4 - env: PHPCS_VERSION="dev-master" LINT=1 - - php: 5.4 - env: PHPCS_VERSION="3.3.1" - - #### TEST STAGE #### - # Additional builds to prevent issues with PHPCS versions incompatible with certain PHP versions. - - stage: test - # PHPCS is only compatible with PHP 7.4 as of version 3.5.0. - php: 7.4 - env: PHPCS_VERSION="3.5.0" - - php: 7.3 - env: PHPCS_VERSION="dev-master" LINT=1 - - - php: 7.4 - env: PHPCS_VERSION="4.0.x-dev@dev" - - - php: "nightly" - env: PHPCS_VERSION="dev-master" LINT=1 - - #### CODE COVERAGE STAGE #### - # N.B.: Coverage is only checked on the lowest and highest stable PHP versions for all PHPCS versions. - # These builds are left out off the "test" stage so as not to duplicate test runs. - # The script used is the default script below, the same as for the `test` stage. - - stage: coverage - php: 7.4 - env: PHPCS_VERSION="dev-master" LINT=1 COVERALLS_VERSION="^2.0" - - php: 7.3 - env: PHPCS_VERSION="3.3.1" COVERALLS_VERSION="^2.0" - - - php: 5.4 - env: PHPCS_VERSION="dev-master" LINT=1 COVERALLS_VERSION="^1.0" - - php: 5.4 - env: PHPCS_VERSION="3.3.1" COVERALLS_VERSION="^1.0" - - allow_failures: - # Allow failures for unstable builds. - - php: "nightly" - - env: PHPCS_VERSION="4.0.x-dev@dev" - - -before_install: - # Speed up build time by disabling Xdebug when its not needed. - - | - if [[ "${TRAVIS_BUILD_STAGE_NAME^}" != "Coverage" ]]; then - phpenv config-rm xdebug.ini || echo 'No xdebug config.' - fi - - - export XMLLINT_INDENT=" " - - # On stable PHPCS versions, allow for PHP deprecation notices. - # Unit tests don't need to fail on those for stable releases where those issues won't get fixed anymore. - - | - if [[ "${TRAVIS_BUILD_STAGE_NAME^}" != "Sniff" && $PHPCS_BRANCH != "dev-master" ]]; then - echo 'error_reporting = E_ALL & ~E_DEPRECATED' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - fi - - -install: - # Set up test environment using Composer. - - composer require --no-update --no-scripts squizlabs/php_codesniffer:${PHPCS_VERSION} - - | - if [[ "${TRAVIS_BUILD_STAGE_NAME^}" == "Coverage" ]]; then - composer require --no-update --no-suggest --no-scripts php-coveralls/php-coveralls:${COVERALLS_VERSION} - fi - - - | - if [[ "${PHPCS_VERSION:0:3}" == "4.0" ]]; then - # Remove devtools as it will not (yet) install on PHPCS 4.x. - composer remove --dev phpcsstandards/phpcsdevtools --no-update - # --prefer-source ensures that the PHPCS native unit test framework will be available in PHPCS 4.x. - composer install --prefer-source --no-suggest - elif [[ $TRAVIS_PHP_VERSION == "nightly" ]]; then - # Ignore PHPUnit platform requirements for installing on nightly. - composer install --prefer-dist --no-suggest --ignore-platform-reqs - else - # --prefer-dist will allow for optimal use of the travis caching ability. - composer install --prefer-dist --no-suggest - fi - # The Composer PHPCS plugin takes care of setting the installed_paths for PHPCS. - - -before_script: - - if [[ "${TRAVIS_BUILD_STAGE_NAME^}" == "Coverage" ]]; then mkdir -p build/logs; fi - - phpenv rehash - - -script: - # Lint PHP files against parse errors. - - if [[ "$LINT" == "1" ]]; then composer lint; fi - - # Run the unit tests. - - | - if [[ "${TRAVIS_BUILD_STAGE_NAME^}" != "Coverage" ]]; then - composer test - elif [[ "${TRAVIS_BUILD_STAGE_NAME^}" == "Coverage" ]]; then - composer coverage - fi - -after_success: - - | - if [[ "${TRAVIS_BUILD_STAGE_NAME^}" == "Coverage" && $COVERALLS_VERSION == "^1.0" ]]; then - php vendor/bin/coveralls -v -x build/logs/clover.xml - fi - - | - if [[ "${TRAVIS_BUILD_STAGE_NAME^}" == "Coverage" && $COVERALLS_VERSION == "^2.0" ]]; then - php vendor/bin/php-coveralls -v -x build/logs/clover.xml - fi diff --git a/CHANGELOG.md b/CHANGELOG.md index db5f02ee..8e97109d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Change Log for the PHPCSExtra standard for PHP Codesniffer +# Change Log for the PHPCSExtra standard for PHP CodeSniffer All notable changes to this project will be documented in this file. @@ -14,24 +14,191 @@ This projects adheres to [Keep a CHANGELOG](http://keepachangelog.com/) and uses _Nothing yet._ + +## [1.0.0-RC1] - 2022-12-07 + +:warning: Important: this package now requires [PHPCSUtils 1.0.0-alpha4]. Please make sure you use `--with-[all-]dependencies` when running `composer update`. :exclamation: + +### Added + +#### Modernize + +* This is a new standard with one sniff to start with. +* :wrench: :books: New `Modernize.FunctionCalls.Dirname` sniff to detect and auto-fix two typical code modernizations which can be made related to the [`dirname()`][php-manual-dirname] function. [#172] + +#### Universal + +* :wrench: :bar_chart: :books: New `Universal.Classes.DisallowAnonClassParentheses` sniff to disallow the use of parentheses when declaring an anonymous class without passing parameters. [#76], [#162] +* :wrench: :bar_chart: :books: New `Universal.Classes.RequireAnonClassParentheses` sniff to require the use of parentheses when declaring an anonymous class, whether parameters are passed or not. [#76], [#166] +* :wrench: :bar_chart: :books: New `Universal.Classes.DisallowFinalClass` sniff to disallow classes being declared `final`. [#108], [#114], [#148], [#163] +* :wrench: :bar_chart: :books: New `Universal.Classes.RequireFinalClass` sniff to require all non-`abstract` classes to be declared `final`. [#109], [#148], [#164] + Warning: the auto-fixer for this sniff _may_ have unintended side-effects for applications and should be used with care! This is considered a _risky_ fixer. +* :wrench: :bar_chart: :books: New `Universal.Classes.ModifierKeywordOrder` sniff to standardize the modifier keyword order for class declarations. [#142] + The sniff offers an `order` property to specify the preferred order. +* :wrench: :books: New `Universal.CodeAnalysis.ConstructorDestructorReturn` sniff to verify that class constructor/destructor methods 1) do not have a return type declaration and 2) do not return a value. [#137], [#140], [#146] Inspired by [@derickr]. +* :wrench: :books: New `Universal.CodeAnalysis.ForeachUniqueAssignment` sniff to detect `foreach` control structures which use the same variable for both the key as well as the value assignment as this will lead to unexpected - and most likely unintended - behaviour. [#110], [#175] + The fixer will maintain the existing behaviour of the code. Mind: this may not be the _intended_ behaviour. +* :wrench: :books: New `Universal.CodeAnalysis.StaticInFinalClass` sniff to detect using `static` instead of `self` in OO constructs which are `final`. [#116], [#180] + The sniff has modular error codes to allow for making exceptions based on the type of use for `static`. +* :wrench: :bar_chart: :books: New `Universal.Constants.LowercaseClassResolutionKeyword` sniff to enforce that the `class` keyword when used for class name resolution, i.e. `::class`, is in lowercase. [#72] +* :wrench: :bar_chart: :books: New `Universal.Constants.ModifierKeywordOrder` sniff to standardize the modifier keyword order for OO constant declarations. [#143] + The sniff offers an `order` property to specify the preferred order. +* :wrench: :books: New `Universal.ControlStructures.DisallowLonelyIf` sniff to disallow `if` statements as the only statement in an `else` block. [#85], [#168], [#169] + Inspired by the [ESLint "no lonely if"] rule. + Note: This sniff will not fix the indentation of the "inner" code. It is strongly recommended to run this sniff together with the `Generic.WhiteSpace.ScopeIndent` sniff to get the correct indentation. +* :bar_chart: :books: New `Universal.Files.SeparateFunctionsFromOO` sniff to enforce that a file should either declare (global/namespaced) functions or declare OO structures, but not both. [#95], [#170], [#171] + Nested function declarations, i.e. functions declared within a function/method will be disregarded for the purposes of this sniff. + The same goes for anonymous classes, closures and arrow functions. +* :books: New `Universal.NamingConventions.NoReservedKeywordParameterNames` sniff to verify that function parameters do not use reserved keywords as names, as this can quickly become confusing when people use them in function calls using named parameters. [#80], [#81], [#106], [#107], [#173] + The sniff has modular error codes to allow for making exceptions for specific keywords. +* :wrench: :bar_chart: :books: New `Universal.Operators.TypeSeparatorSpacing` sniff to enforce no spaces around union type and intersection type separators. [#117] +* :wrench: :books: New `Universal.PHP.OneStatementInShortEchoTag` sniff to disallow short open echo tags `= 8.0][php-rfc-negative_array_index]. [#177], [#178] + If a [`php_version` configuration option][php_version-config] has been passed to PHPCS, it will be respected by the sniff and only report duplicate keys for the configured PHP version. +* `Universal.ControlStructures.DisallowAlternativeSyntax`: the sniff will now also record a metric when single-line (no body) control structures are encountered. [#158] +* `Universal.ControlStructures.DisallowAlternativeSyntax`: the error message thrown by the sniff is now more descriptive. [#159] +* `Universal.ControlStructures.DisallowAlternativeSyntax`: metrics will no longer be recorded for `elseif` and `else` keywords, but only on the `if` keyword as the type of syntax used has to be the same for the whole "chain". [#161] +* `Universal.Lists.DisallowLongListSyntax`: the sniff will no longer record (incomplete) metrics about long vs short list usage. [#155] +* `Universal.Lists.DisallowShortListSyntax`: the sniff will now record (complete) metrics about long vs short list usage. [#155] +* `Universal.OOStructures.AlphabeticExtendsImplements`: documented support for `enum ... implements`. [#150] +* `Universal.UseStatements.DisallowUseClass`: updated error message and metric name to take PHP 8.1 `enum`s into account. [#149] +* `Universal.UseStatements.NoLeadingBackslash`: the sniff will now also flag and auto-fix leading backslashes in group use statements. [#167] + +#### Other +* Updated the sniffs for compatibility with PHPCSUtils 1.0.0-alpha4. [#134] +* Updated the sniffs to correctly handle PHP 8.0/8.1/8.2 features whenever relevant. +* Readme: Updated installation instructions for compatibility with Composer 2.2+. [#101] +* Composer: The minimum `PHP_CodeSniffer` requirement has been updated to `^3.7.1` (was ^3.3.1). [#115], [#130] +* Composer: The package will now identify itself as a static analysis tool. Thanks [@GaryJones]! [#126] +* All non-`abstract` classes in this package are now `final`. [#121] +* All XML documentation now has a schema annotation. [#128] +* Various housekeeping. + +### Fixed + +The upgrade to PHPCSUtils 1.0.0-alpha4 took care of a number of bugs, which potentially could have affected sniffs in this package. + +#### NormalizedArrays +* `NormalizedArrays.Arrays.ArrayBraceSpacing`: the sniff now allows for trailing comments after the array opener in multi-line arrays. [#118] +* `NormalizedArrays.Arrays.ArrayBraceSpacing`: trailing comments at the end of an array, but before the closer, in multi-line arrays will no longer confuse the sniff. [#135] +* `NormalizedArrays.Arrays.CommaAfterLast`: the fixer will now recognize PHP 7.3+ flexible heredoc/nowdocs and in that case, will add the comma on the same line as the heredoc/nowdoc closer. [#144] + +#### Universal +* `Universal.Arrays.DisallowShortArraySyntax`: nested short arrays in short lists will now be detected and fixed correctly. [#153] +* `Universal.ControlStructures.DisallowAlternativeSyntax`: the sniff will no longer bow out indiscriminately when the `allowWithInlineHTML` property is set to `true`. [#90], [#161] +* `Universal.ControlStructures.DisallowAlternativeSyntax`: when alternative control structure syntax is allowed in combination with inline HTML (`allowWithInlineHTML` property set to `true`), inline HTML in functions declared within the control structure body will no longer be taken into account for determining whether or not the control structure contains inline HTML. [#160] +* `Universal.Lists.DisallowShortListSyntax`: the sniff will work around a tokenizer bug in PHPCS 3.7.1, which previously could lead to false negatives. [#151]. +* `Universal.Lists.DisallowShortListSyntax`: nested short lists in short arrays will now be detected and fixed correctly. [#152] +* `Universal.Operators.DisallowStandalonePostIncrementDecrement`: the sniff will now correctly recognize stand-alone statements which end on a PHP close tag. [#176] + +[#72]: https://github.com/PHPCSStandards/PHPCSExtra/pull/72 +[#76]: https://github.com/PHPCSStandards/PHPCSExtra/pull/76 +[#80]: https://github.com/PHPCSStandards/PHPCSExtra/pull/80 +[#81]: https://github.com/PHPCSStandards/PHPCSExtra/pull/81 +[#85]: https://github.com/PHPCSStandards/PHPCSExtra/pull/85 +[#89]: https://github.com/PHPCSStandards/PHPCSExtra/pull/89 +[#90]: https://github.com/PHPCSStandards/PHPCSExtra/pull/90 +[#95]: https://github.com/PHPCSStandards/PHPCSExtra/pull/95 +[#101]: https://github.com/PHPCSStandards/PHPCSExtra/pull/101 +[#106]: https://github.com/PHPCSStandards/PHPCSExtra/pull/106 +[#107]: https://github.com/PHPCSStandards/PHPCSExtra/pull/107 +[#108]: https://github.com/PHPCSStandards/PHPCSExtra/pull/108 +[#109]: https://github.com/PHPCSStandards/PHPCSExtra/pull/109 +[#110]: https://github.com/PHPCSStandards/PHPCSExtra/pull/110 +[#114]: https://github.com/PHPCSStandards/PHPCSExtra/pull/114 +[#115]: https://github.com/PHPCSStandards/PHPCSExtra/pull/115 +[#116]: https://github.com/PHPCSStandards/PHPCSExtra/pull/116 +[#117]: https://github.com/PHPCSStandards/PHPCSExtra/pull/117 +[#118]: https://github.com/PHPCSStandards/PHPCSExtra/pull/118 +[#119]: https://github.com/PHPCSStandards/PHPCSExtra/pull/119 +[#120]: https://github.com/PHPCSStandards/PHPCSExtra/pull/120 +[#121]: https://github.com/PHPCSStandards/PHPCSExtra/pull/121 +[#122]: https://github.com/PHPCSStandards/PHPCSExtra/pull/122 +[#123]: https://github.com/PHPCSStandards/PHPCSExtra/pull/123 +[#124]: https://github.com/PHPCSStandards/PHPCSExtra/pull/124 +[#126]: https://github.com/PHPCSStandards/PHPCSExtra/pull/126 +[#128]: https://github.com/PHPCSStandards/PHPCSExtra/pull/128 +[#130]: https://github.com/PHPCSStandards/PHPCSExtra/pull/130 +[#134]: https://github.com/PHPCSStandards/PHPCSExtra/pull/134 +[#137]: https://github.com/PHPCSStandards/PHPCSExtra/pull/137 +[#140]: https://github.com/PHPCSStandards/PHPCSExtra/pull/140 +[#142]: https://github.com/PHPCSStandards/PHPCSExtra/pull/142 +[#143]: https://github.com/PHPCSStandards/PHPCSExtra/pull/143 +[#144]: https://github.com/PHPCSStandards/PHPCSExtra/pull/144 +[#146]: https://github.com/PHPCSStandards/PHPCSExtra/pull/146 +[#147]: https://github.com/PHPCSStandards/PHPCSExtra/pull/147 +[#148]: https://github.com/PHPCSStandards/PHPCSExtra/pull/148 +[#149]: https://github.com/PHPCSStandards/PHPCSExtra/pull/149 +[#150]: https://github.com/PHPCSStandards/PHPCSExtra/pull/150 +[#151]: https://github.com/PHPCSStandards/PHPCSExtra/pull/151 +[#152]: https://github.com/PHPCSStandards/PHPCSExtra/pull/152 +[#153]: https://github.com/PHPCSStandards/PHPCSExtra/pull/153 +[#154]: https://github.com/PHPCSStandards/PHPCSExtra/pull/154 +[#155]: https://github.com/PHPCSStandards/PHPCSExtra/pull/155 +[#158]: https://github.com/PHPCSStandards/PHPCSExtra/pull/158 +[#159]: https://github.com/PHPCSStandards/PHPCSExtra/pull/159 +[#160]: https://github.com/PHPCSStandards/PHPCSExtra/pull/160 +[#161]: https://github.com/PHPCSStandards/PHPCSExtra/pull/161 +[#162]: https://github.com/PHPCSStandards/PHPCSExtra/pull/162 +[#163]: https://github.com/PHPCSStandards/PHPCSExtra/pull/163 +[#164]: https://github.com/PHPCSStandards/PHPCSExtra/pull/164 +[#165]: https://github.com/PHPCSStandards/PHPCSExtra/pull/165 +[#166]: https://github.com/PHPCSStandards/PHPCSExtra/pull/166 +[#167]: https://github.com/PHPCSStandards/PHPCSExtra/pull/167 +[#168]: https://github.com/PHPCSStandards/PHPCSExtra/pull/168 +[#169]: https://github.com/PHPCSStandards/PHPCSExtra/pull/169 +[#170]: https://github.com/PHPCSStandards/PHPCSExtra/pull/170 +[#171]: https://github.com/PHPCSStandards/PHPCSExtra/pull/171 +[#172]: https://github.com/PHPCSStandards/PHPCSExtra/pull/172 +[#173]: https://github.com/PHPCSStandards/PHPCSExtra/pull/173 +[#175]: https://github.com/PHPCSStandards/PHPCSExtra/pull/175 +[#176]: https://github.com/PHPCSStandards/PHPCSExtra/pull/176 +[#177]: https://github.com/PHPCSStandards/PHPCSExtra/pull/177 +[#178]: https://github.com/PHPCSStandards/PHPCSExtra/pull/178 +[#180]: https://github.com/PHPCSStandards/PHPCSExtra/pull/180 + +[php-manual-dirname]: https://www.php.net/function.dirname +[php-rfc-negative_array_index]: https://wiki.php.net/rfc/negative_array_index +[php_version-config]: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Configuration-Options#setting-the-php-version +[ESLint "no lonely if"]: https://eslint.org/docs/rules/no-lonely-if +[PHPCSUtils 1.0.0-alpha4]: https://github.com/PHPCSStandards/PHPCSUtils/releases/tag/1.0.0-alpha4 + + ## [1.0.0-alpha3] - 2020-06-29 ### Added #### Universal -* :wrench: :books: New `Universal.Arrays.DisallowShortArraySyntax` sniff to disallow short array syntax. [#40](https://github.com/PHPCSStandards/PHPCSExtra/pull/40) +* :wrench: :books: New `Universal.Arrays.DisallowShortArraySyntax` sniff to disallow short array syntax. [#40] In contrast to the PHPCS native `Generic.Arrays.DisallowShortArraySyntax` sniff, this sniff will ignore short list syntax and not cause parse errors when the fixer is used. -* :wrench: :bar_chart: :books: New `Universal.Constants.UppercaseMagicConstants` sniff to enforce that PHP native magic constants are in uppercase. [#64](https://github.com/PHPCSStandards/PHPCSExtra/pull/64) -* :bar_chart: :books: New `Universal.Namespaces.DisallowDeclarationWithoutName` sniff to disallow namespace declarations without a namespace name. [#50](https://github.com/PHPCSStandards/PHPCSExtra/pull/50) -* :bar_chart: :books: New `Universal.Operators.DisallowLogicalAndOr` sniff to enforce the use of the boolean `&&` and `||` operators instead of the logical `and`/`or` operators. [#52](https://github.com/PHPCSStandards/PHPCSExtra/pull/52) - Note: as the [operator precedence](https://www.php.net/manual/en/language.operators.precedence.php) of the logical operators is significantly lower than the operator precedence of boolean operators, this sniff does not contain an auto-fixer. -* :bar_chart: :books: New `Universal.Operators.DisallowShortTernary` sniff to disallow the use of short ternaries `?:`. [#42](https://github.com/PHPCSStandards/PHPCSExtra/pull/42) +* :wrench: :bar_chart: :books: New `Universal.Constants.UppercaseMagicConstants` sniff to enforce that PHP native magic constants are in uppercase. [#64] +* :bar_chart: :books: New `Universal.Namespaces.DisallowDeclarationWithoutName` sniff to disallow namespace declarations without a namespace name. [#50] +* :bar_chart: :books: New `Universal.Operators.DisallowLogicalAndOr` sniff to enforce the use of the boolean `&&` and `||` operators instead of the logical `and`/`or` operators. [#52] + Note: as the [operator precedence] of the logical operators is significantly lower than the operator precedence of boolean operators, this sniff does not contain an auto-fixer. +* :bar_chart: :books: New `Universal.Operators.DisallowShortTernary` sniff to disallow the use of short ternaries `?:`. [#42] While short ternaries are useful when used correctly, the principle of them is often misunderstood and they are more often than not used incorrectly, leading to hard to debug issues and/or PHP warnings/notices. -* :wrench: :bar_chart: :books: New `Universal.Operators.DisallowStandalonePostIncrementDecrement` sniff disallow the use of post-in/decrements in stand-alone statements and discourage the use of multiple increment/decrement operators in a stand-alone statement. [#65](https://github.com/PHPCSStandards/PHPCSExtra/pull/65) -* :wrench: :bar_chart: :books: New `Universal.Operators.StrictComparisons` sniff to enforce the use of strict comparisons. [#48](https://github.com/PHPCSStandards/PHPCSExtra/pull/48) +* :wrench: :bar_chart: :books: New `Universal.Operators.DisallowStandalonePostIncrementDecrement` sniff disallow the use of post-in/decrements in stand-alone statements and discourage the use of multiple increment/decrement operators in a stand-alone statement. [#65] +* :wrench: :bar_chart: :books: New `Universal.Operators.StrictComparisons` sniff to enforce the use of strict comparisons. [#48] Warning: the auto-fixer for this sniff _may_ cause bugs in applications and should be used with care! This is considered a _risky_ fixer. -* :wrench: :bar_chart: :books: New `Universal.OOStructures.AlphabeticExtendsImplements` sniff to verify that the names used in a class "implements" statement or an interface "extends" statement are listed in alphabetic order. [#55](https://github.com/PHPCSStandards/PHPCSExtra/pull/55) +* :wrench: :bar_chart: :books: New `Universal.OOStructures.AlphabeticExtendsImplements` sniff to verify that the names used in a class "implements" statement or an interface "extends" statement are listed in alphabetic order. [#55] * This sniff contains a public `orderby` property to determine the sort order to use for the statement. If all names used are unqualified, the sort order won't make a difference. However, if one or more of the names are partially or fully qualified, the chosen sort order will determine how the sorting between unqualified, partially and fully qualified names is handled. @@ -47,38 +214,53 @@ _Nothing yet._ * When fixing, the existing spacing between the names in an `implements`/`extends` statement will not be maintained. The fixer will separate each name with a comma and one space. If alternative formatting is desired, a sniff which will check and fix the formatting should be added to the ruleset. -* :wrench: :bar_chart: :books: New `Universal.UseStatements.LowercaseFunctionConst` sniff to enforce that `function` and `const` keywords when used in an import `use` statement are always lowercase. [#58](https://github.com/PHPCSStandards/PHPCSExtra/pull/58) -* :wrench: :bar_chart: :books: New `Universal.UseStatements.NoLeadingBackslash` sniff to verify that a name being imported in an import `use` statement does not start with a leading backslash. [#46](https://github.com/PHPCSStandards/PHPCSExtra/pull/46) +* :wrench: :bar_chart: :books: New `Universal.UseStatements.LowercaseFunctionConst` sniff to enforce that `function` and `const` keywords when used in an import `use` statement are always lowercase. [#58] +* :wrench: :bar_chart: :books: New `Universal.UseStatements.NoLeadingBackslash` sniff to verify that a name being imported in an import `use` statement does not start with a leading backslash. [#46] Names in import `use` statements should always be fully qualified, so a leading backslash is not needed and it is strongly recommended not to use one. This sniff handles all types of import use statements supported by PHP, in contrast to other sniffs for the same in, for instance, the PSR12 or the Slevomat standard, which are incomplete. -* :wrench: :books: New `Universal.WhiteSpace.DisallowInlineTabs` sniff to enforce using spaces for mid-line alignment. [#43](https://github.com/PHPCSStandards/PHPCSExtra/pull/43) +* :wrench: :books: New `Universal.WhiteSpace.DisallowInlineTabs` sniff to enforce using spaces for mid-line alignment. [#43] ### Changed #### Other * The `master` branch has been renamed to `stable`. -* Composer: The version requirements for the [DealerDirect Composer PHPCS plugin] have been widened to allow for version 0.7.0 which supports Composer 2.0.0. [#62](https://github.com/PHPCSStandards/PHPCSExtra/pull/62) +* Composer: The version requirements for the [Composer PHPCS plugin] have been widened to allow for version 0.7.0 which supports Composer 2.0.0. [#62] * Various housekeeping. +[#40]: https://github.com/PHPCSStandards/PHPCSExtra/pull/40 +[#42]: https://github.com/PHPCSStandards/PHPCSExtra/pull/42 +[#43]: https://github.com/PHPCSStandards/PHPCSExtra/pull/43 +[#46]: https://github.com/PHPCSStandards/PHPCSExtra/pull/46 +[#48]: https://github.com/PHPCSStandards/PHPCSExtra/pull/48 +[#50]: https://github.com/PHPCSStandards/PHPCSExtra/pull/50 +[#52]: https://github.com/PHPCSStandards/PHPCSExtra/pull/52 +[#55]: https://github.com/PHPCSStandards/PHPCSExtra/pull/55 +[#58]: https://github.com/PHPCSStandards/PHPCSExtra/pull/58 +[#62]: https://github.com/PHPCSStandards/PHPCSExtra/pull/62 +[#64]: https://github.com/PHPCSStandards/PHPCSExtra/pull/64 +[#65]: https://github.com/PHPCSStandards/PHPCSExtra/pull/65 + +[operator precedence]: https://www.php.net/manual/en/language.operators.precedence.php + ## [1.0.0-alpha2] - 2020-02-18 ### Added #### Universal -* :wrench: :bar_chart: :books: New `Universal.ControlStructures.DisallowAlternativeSyntax` sniff to disallow using the alternative syntax for control structures. [#23](https://github.com/PHPCSStandards/PHPCSExtra/pull/23) +* :wrench: :bar_chart: :books: New `Universal.ControlStructures.DisallowAlternativeSyntax` sniff to disallow using the alternative syntax for control structures. [#23] - This sniff contains a `allowWithInlineHTML` property to allow alternative syntax when inline HTML is used within the control structure. In all other cases, the use of the alternative syntax will still be disallowed. - The sniff has modular error codes to allow for making exceptions based on specific control structures and/or specific control structures in combination with inline HTML. -* :bar_chart: `Universal.UseStatements.DisallowUseClass/Function/Const`: new, additional metrics about the import source will be shown in the `info` report. [#25](https://github.com/PHPCSStandards/PHPCSExtra/pull/25) +* :bar_chart: `Universal.UseStatements.DisallowUseClass/Function/Const`: new, additional metrics about the import source will be shown in the `info` report. [#25] #### Other -* Readme: installation instructions and sniff list. [#26](https://github.com/PHPCSStandards/PHPCSExtra/pull/26) +* Readme: installation instructions and sniff list. [#26] ### Changed #### Universal -* `Universal.Arrays.DuplicateArrayKey`: wording of the error message. [#18](https://github.com/PHPCSStandards/PHPCSExtra/pull/18) -* `Universal.UseStatements.DisallowUseClass/Function/Const`: the error codes have been made more modular. [#25](https://github.com/PHPCSStandards/PHPCSExtra/pull/25) +* `Universal.Arrays.DuplicateArrayKey`: wording of the error message. [#18] +* `Universal.UseStatements.DisallowUseClass/Function/Const`: the error codes have been made more modular. [#25] Each of these sniffs now has four additional error codes: