Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

YoastCS: add dependency on PHPCSUtils and start using it #322

Merged
merged 4 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/basics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ jobs:
run: >
composer require --no-update --no-scripts --no-interaction
squizlabs/php_codesniffer:"dev-master"
phpcsstandards/phpcsutils:"dev-develop"
phpcsstandards/phpcsextra:"dev-develop"

# Install dependencies and handle caching in one go.
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/quicktest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ jobs:
run: >
composer require --no-update --no-scripts --no-interaction --ignore-platform-req=php+
squizlabs/php_codesniffer:"dev-master"
phpcsstandards/phpcsutils:"dev-develop"

# Install dependencies and handle caching in one go.
# @link https://github.com/marketplace/actions/install-composer-dependencies
Expand All @@ -86,6 +87,7 @@ jobs:
run: >
composer update --prefer-lowest --no-scripts --no-interaction --ignore-platform-req=php+
squizlabs/php_codesniffer
phpcsstandards/phpcsutils
wp-coding-standards/wpcs

- name: Verify installed standards
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ concurrency:
# Once support for WPCS 3.0.0 has been added, the matrix should switch (back) using `dev-develop`.
env:
PHPCS_HIGHEST: 'dev-master'
UTILS_HIGHEST: 'dev-develop'
WPCS_HIGHEST: '2.3.0'

jobs:
Expand Down Expand Up @@ -96,6 +97,7 @@ jobs:
run: >
composer require --no-update --no-scripts --no-interaction --ignore-platform-req=php+
squizlabs/php_codesniffer:"${{ env.PHPCS_HIGHEST }}"
phpcsstandards/phpcsutils:"${{ env.UTILS_HIGHEST }}"

# Install dependencies and handle caching in one go.
# @link https://github.com/marketplace/actions/install-composer-dependencies
Expand All @@ -119,6 +121,7 @@ jobs:
run: >
composer update --prefer-lowest --no-scripts --no-interaction --ignore-platform-req=php+
squizlabs/php_codesniffer
phpcsstandards/phpcsutils
wp-coding-standards/wpcs

- name: Verify installed versions
Expand Down Expand Up @@ -191,6 +194,7 @@ jobs:
run: >
composer require --no-update --no-scripts --no-interaction
squizlabs/php_codesniffer:"${{ env.PHPCS_HIGHEST }}"
phpcsstandards/phpcsutils:"${{ env.UTILS_HIGHEST }}"

# Install dependencies and handle caching in one go.
# @link https://github.com/marketplace/actions/install-composer-dependencies
Expand All @@ -205,6 +209,7 @@ jobs:
run: >
composer update --prefer-lowest --no-scripts --no-interaction
squizlabs/php_codesniffer
phpcsstandards/phpcsutils
wp-coding-standards/wpcs

- name: Verify installed versions
Expand Down
3 changes: 2 additions & 1 deletion Yoast/Sniffs/Commenting/CoversTagSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHPCSUtils\Utils\GetTokensAsString;

/**
* Verifies that a @covers tag annotation follows a format supported by PHPUnit.
Expand Down Expand Up @@ -327,7 +328,7 @@ protected function fixAnnotationToSplit( File $phpcsFile, $stackPtr, $errorCode,
$phpcsFile->fixer->replaceToken( $i, '' );
}

$stub = $phpcsFile->getTokensAsString( $i, ( $stackPtr - $i ), true );
$stub = GetTokensAsString::origContent( $phpcsFile, $i, ( $stackPtr - 1 ) );
$replacement = '';
foreach ( $annotations as $annotation ) {
$replacement .= $stub . $annotation;
Expand Down
8 changes: 5 additions & 3 deletions Yoast/Sniffs/Commenting/TestsHaveCoversTagSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
use PHPCSUtils\Utils\FunctionDeclarations;
use PHPCSUtils\Utils\ObjectDeclarations;

/**
* Verifies that all test functions have at least one @covers tag.
Expand Down Expand Up @@ -59,7 +61,7 @@ public function process( File $phpcsFile, $stackPtr ) {
*/
protected function process_class( File $phpcsFile, $stackPtr ) {
$tokens = $phpcsFile->getTokens();
$name = $phpcsFile->getDeclarationName( $stackPtr );
$name = ObjectDeclarations::getName( $phpcsFile, $stackPtr );

if ( \substr( $name, -4 ) !== 'Test'
&& \substr( $name, -8 ) !== 'TestCase'
Expand Down Expand Up @@ -180,13 +182,13 @@ protected function process_function( File $phpcsFile, $stackPtr ) {
}
}

$name = $phpcsFile->getDeclarationName( $stackPtr );
$name = FunctionDeclarations::getName( $phpcsFile, $stackPtr );
if ( \stripos( $name, 'test' ) !== 0 && $foundTest === false ) {
// Not a test method.
return;
}

$method_props = $phpcsFile->getMethodProperties( $stackPtr );
$method_props = FunctionDeclarations::getProperties( $phpcsFile, $stackPtr );
if ( $method_props['is_abstract'] === true ) {
// Abstract test method, not implemented.
return;
Expand Down
3 changes: 2 additions & 1 deletion Yoast/Sniffs/Files/FileNameSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Common;
use PHPCSUtils\Utils\ObjectDeclarations;

/**
* Ensures files comply with the Yoast file name rules.
Expand Down Expand Up @@ -121,7 +122,7 @@ public function process( File $phpcsFile, $stackPtr ) {
if ( $oo_structure !== false ) {

$tokens = $phpcsFile->getTokens();
$name = $phpcsFile->getDeclarationName( $oo_structure );
$name = ObjectDeclarations::getName( $phpcsFile, $oo_structure );

$prefixes = $this->clean_custom_array_property( $this->oo_prefixes );
if ( ! empty( $prefixes ) ) {
Expand Down
5 changes: 3 additions & 2 deletions Yoast/Sniffs/Files/TestDoublesSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHPCSUtils\Utils\ObjectDeclarations;

/**
* Check that all mock/doubles classes are in their own file and in a `doubles` directory.
Expand Down Expand Up @@ -123,7 +124,7 @@ public function process( File $phpcsFile, $stackPtr ) {
}
}

$object_name = $phpcsFile->getDeclarationName( $stackPtr );
$object_name = ObjectDeclarations::getName( $phpcsFile, $stackPtr );
if ( empty( $object_name ) ) {
return;
}
Expand Down Expand Up @@ -206,7 +207,7 @@ public function process( File $phpcsFile, $stackPtr ) {
$tokens[ $stackPtr ]['content'],
$object_name,
$tokens[ $more_objects_in_file ]['content'],
$phpcsFile->getDeclarationName( $more_objects_in_file ),
ObjectDeclarations::getName( $phpcsFile, $more_objects_in_file ),
];

$phpcsFile->addError(
Expand Down
8 changes: 5 additions & 3 deletions Yoast/Sniffs/NamingConventions/ObjectNameDepthSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace YoastCS\Yoast\Sniffs\NamingConventions;

use PHPCSUtils\Utils\Namespaces;
use PHPCSUtils\Utils\ObjectDeclarations;
use WordPressCS\WordPress\Sniff as WPCS_Sniff;

/**
Expand Down Expand Up @@ -73,11 +75,11 @@ public function register() {
public function process_token( $stackPtr ) {

// Check whether we are in a namespace or not.
if ( $this->determine_namespace( $stackPtr ) === '' ) {
if ( Namespaces::determineNamespace( $this->phpcsFile, $stackPtr ) === '' ) {
return;
}

$object_name = $this->phpcsFile->getDeclarationName( $stackPtr );
$object_name = ObjectDeclarations::getName( $this->phpcsFile, $stackPtr );
if ( empty( $object_name ) ) {
return;
}
Expand All @@ -101,7 +103,7 @@ public function process_token( $stackPtr ) {
--$part_count;
}
else {
$extends = $this->phpcsFile->findExtendedClassName( $stackPtr );
$extends = ObjectDeclarations::findExtendedClassName( $this->phpcsFile, $stackPtr );
if ( \is_string( $extends ) ) {
--$part_count;
}
Expand Down
5 changes: 3 additions & 2 deletions Yoast/Sniffs/NamingConventions/ValidHookNameSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace YoastCS\Yoast\Sniffs\NamingConventions;

use PHP_CodeSniffer\Util\Tokens;
use PHPCSUtils\Utils\TextStrings;
use WordPressCS\WordPress\Sniffs\NamingConventions\ValidHookNameSniff as WPCS_ValidHookNameSniff;
use YoastCS\Yoast\Utils\CustomPrefixesTrait;

Expand Down Expand Up @@ -118,7 +119,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p

if ( isset( Tokens::$stringTokens[ $this->tokens[ $first_non_empty ]['code'] ] ) ) {
$this->prefix_quote_style = $this->tokens[ $first_non_empty ]['content'][0];
$content = \trim( $this->strip_quotes( $this->tokens[ $first_non_empty ]['content'] ) );
$content = \trim( TextStrings::stripQuotes( $this->tokens[ $first_non_empty ]['content'] ) );

foreach ( $this->validated_prefixes as $prefix ) {
if ( \strpos( $prefix, '\\' ) === false
Expand Down Expand Up @@ -296,7 +297,7 @@ public function verify_yoast_hook_name( $stackPtr, $parameters ) {
* Check the hook name depth.
*/
$hook_ptr = $first_non_empty; // If no other tokens were found, the first non empty will be the hook name.
$hook_name = $this->strip_quotes( $this->tokens[ $hook_ptr ]['content'] );
$hook_name = TextStrings::stripQuotes( $this->tokens[ $hook_ptr ]['content'] );
$hook_name = \substr( $hook_name, \strlen( $this->found_prefix ) );

$parts = \explode( '_', $hook_name );
Expand Down
15 changes: 9 additions & 6 deletions Yoast/Sniffs/Tools/BrainMonkeyRaceConditionSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
namespace YoastCS\Yoast\Sniffs\Tools;

use PHP_CodeSniffer\Util\Tokens;
use PHPCSUtils\Utils\FunctionDeclarations;
use PHPCSUtils\Utils\PassedParameters;
use PHPCSUtils\Utils\TextStrings;
use WordPressCS\WordPress\Sniff;

/**
Expand Down Expand Up @@ -82,21 +85,21 @@ public function process_token( $stackPtr ) {
}

// Check that this is an expect() for one of the hook functions.
$params = $this->get_function_call_parameters( $stackPtr );
if ( empty( $params ) ) {
$param = PassedParameters::getParameter( $this->phpcsFile, $stackPtr, 1, 'function_name' );
if ( empty( $param ) ) {
return;
}

$expected = Tokens::$emptyTokens;
$expected[] = \T_CONSTANT_ENCAPSED_STRING;

$hasUnexpected = $this->phpcsFile->findNext( $expected, $params[1]['start'], ( $params[1]['end'] + 1 ), true );
$hasUnexpected = $this->phpcsFile->findNext( $expected, $param['start'], ( $param['end'] + 1 ), true );
if ( $hasUnexpected !== false ) {
return;
}

$text = $this->phpcsFile->findNext( Tokens::$emptyTokens, $params[1]['start'], ( $params[1]['end'] + 1 ), true );
$textContent = $this->strip_quotes( $this->tokens[ $text ]['content'] );
$text = $this->phpcsFile->findNext( Tokens::$emptyTokens, $param['start'], ( $param['end'] + 1 ), true );
$textContent = TextStrings::stripQuotes( $this->tokens[ $text ]['content'] );
if ( $textContent !== 'apply_filters' && $textContent !== 'do_action' ) {
return;
}
Expand Down Expand Up @@ -133,7 +136,7 @@ public function process_token( $stackPtr ) {
// Okay, we have found the race condition. Throw error.
$message = 'The %s() test method contains both a call to Monkey\Functions\expect( %s ), as well as a call to %s(). This causes a race condition which will cause the tests to fail. Only use one of these in a test.';
$data = [
$this->phpcsFile->getDeclarationName( $functionToken ),
FunctionDeclarations::getName( $this->phpcsFile, $functionToken ),
$this->tokens[ $text ]['content'],
( $targetContent === 'expectdone' ) ? 'Monkey\Actions\expectDone' : 'Monkey\Filters\expectApplied',
];
Expand Down
3 changes: 2 additions & 1 deletion Yoast/Sniffs/WhiteSpace/FunctionSpacingSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\FunctionSpacingSniff as Squiz_FunctionSpacingSniff;
use PHP_CodeSniffer\Util\Tokens;
use PHPCSUtils\Utils\Conditions;

/**
* Verifies the space between methods.
Expand Down Expand Up @@ -54,7 +55,7 @@ final class FunctionSpacingSniff extends Squiz_FunctionSpacingSniff {
*/
public function process( File $phpcsFile, $stackPtr ) {
// Check that the function is nested in an OO structure (class, trait, interface).
if ( $phpcsFile->hasCondition( $stackPtr, Tokens::$ooScopeTokens ) === false ) {
if ( Conditions::hasCondition( $phpcsFile, $stackPtr, Tokens::$ooScopeTokens ) === false ) {
return;
}

Expand Down
13 changes: 8 additions & 5 deletions Yoast/Sniffs/Yoast/AlternativeFunctionsSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace YoastCS\Yoast\Sniffs\Yoast;

use PHPCSUtils\Utils\MessageHelper;
use PHPCSUtils\Utils\Namespaces;
use PHPCSUtils\Utils\PassedParameters;
use WordPressCS\WordPress\AbstractFunctionRestrictionsSniff;

/**
Expand Down Expand Up @@ -49,7 +52,7 @@ public function process_matched_token( $stackPtr, $group_name, $matched_content
$fixable = true;
$message = $this->groups[ $group_name ]['message'];
$is_error = ( $this->groups[ $group_name ]['type'] === 'error' );
$error_code = $this->string_to_errorcode( $group_name . '_' . $matched_content );
$error_code = MessageHelper::stringToErrorcode( $group_name . '_' . $matched_content );
$data = [
$matched_content,
$replacement,
Expand All @@ -65,7 +68,7 @@ public function process_matched_token( $stackPtr, $group_name, $matched_content
* The function `WPSEO_Utils:format_json_encode()` is only a valid alternative
* when only the first parameter is passed.
*/
if ( $this->get_function_call_parameter_count( $stackPtr ) !== 1 ) {
if ( PassedParameters::getParameterCount( $this->phpcsFile, $stackPtr ) !== 1 ) {
$fixable = false;
$error_code .= 'WithAdditionalParams';
}
Expand All @@ -74,13 +77,13 @@ public function process_matched_token( $stackPtr, $group_name, $matched_content
}

if ( $fixable === false ) {
$this->addMessage( $message, $stackPtr, $is_error, $error_code, $data );
MessageHelper::addMessage( $this->phpcsFile, $message, $stackPtr, $is_error, $error_code, $data );
return;
}

$fix = $this->addFixableMessage( $message, $stackPtr, $is_error, $error_code, $data );
$fix = MessageHelper::addFixableMessage( $this->phpcsFile, $message, $stackPtr, $is_error, $error_code, $data );
if ( $fix === true ) {
$namespaced = $this->determine_namespace( $stackPtr );
$namespaced = Namespaces::determineNamespace( $this->phpcsFile, $stackPtr );

if ( empty( $namespaced ) || empty( $replacement ) ) {
$this->phpcsFile->fixer->replaceToken( $stackPtr, $replacement );
Expand Down
10 changes: 10 additions & 0 deletions Yoast/ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@
add configuration for a sniff.
#############################################################################
-->

<!--
Trigger error if PHPCSUtils cannot be found.
PHPCSUtils does not contain any sniffs, so this rule isn't strictly necessary, but
by having this here anyway, if PHPCSUtils is missing, the user will get a
descriptive error message during the loading of the ruleset instead of
a fatal "class not found" error once the sniffs start running.
-->
<rule ref="PHPCSUtils"/>

<rule ref="WordPress">
<!-- Set the minimum supported WP version for all sniff which use it in one go.
Ref: https://github.com/WordPress/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#minimum-wp-version-to-check-for-usage-of-deprecated-functions-classes-and-function-parameters
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
"require": {
"php": ">=5.4",
"ext-tokenizer": "*",
"dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0",
"php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/phpcompatibility-wp": "^2.1.4",
"phpcsstandards/phpcsextra": "^1.1.2",
"phpcsstandards/phpcsutils": "^1.0.8",
"squizlabs/php_codesniffer": "^3.7.2",
"wp-coding-standards/wpcs": "^2.3.0"
},
Expand Down
3 changes: 2 additions & 1 deletion phpunit-bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@

If you use Composer, please run `composer install`.
Otherwise, make sure you set a `PHPCS_DIR` environment variable in your phpunit.xml file
pointing to the PHPCS directory.
pointing to the PHPCS directory and that PHPCSUtils is included in the `installed_paths`
for that PHPCS install.
';

die( 1 );
Expand Down