From 34475d84d7ebbc9b6ccfbe627dace13162d762b7 Mon Sep 17 00:00:00 2001 From: shvlv Date: Fri, 26 Jan 2024 23:17:25 +0200 Subject: [PATCH 1/7] feat: introduce InpsydeTemplate standard; add TrailingSemicolonSniff --- .../Formatting/TrailingSemicolonSniff.php | 109 ++++++++++++++++++ InpsydeTemplates/ruleset.xml | 6 + 2 files changed, 115 insertions(+) create mode 100644 InpsydeTemplates/Sniffs/Formatting/TrailingSemicolonSniff.php create mode 100644 InpsydeTemplates/ruleset.xml diff --git a/InpsydeTemplates/Sniffs/Formatting/TrailingSemicolonSniff.php b/InpsydeTemplates/Sniffs/Formatting/TrailingSemicolonSniff.php new file mode 100644 index 0000000..0496c74 --- /dev/null +++ b/InpsydeTemplates/Sniffs/Formatting/TrailingSemicolonSniff.php @@ -0,0 +1,109 @@ + + */ + public function register(): array + { + return [ + T_SEMICOLON, + ]; + } + + /** + * @param File $phpcsFile + * @param int $stackPtr + * + * phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration + */ + public function process(File $phpcsFile, $stackPtr): void + { + // phpcs:enable Inpsyde.CodeQuality.ArgumentTypeDeclaration + + /** @var array $tokens */ + $tokens = $phpcsFile->getTokens(); + $currentLine = $tokens[$stackPtr]['line']; + + $nextNonEmptyPosition = $phpcsFile->findNext( + Tokens::$emptyTokens, + ($stackPtr + 1), + null, + true + ); + + if (!is_int($nextNonEmptyPosition) || !isset($tokens[$nextNonEmptyPosition])) { + return; + } + + $nextNonEmptyToken = $tokens[$nextNonEmptyPosition]; + + if ($nextNonEmptyToken['line'] !== $currentLine) { + return; + } + + if ($nextNonEmptyToken['code'] !== T_CLOSE_TAG) { + return; + } + + $message = sprintf('Trailing semicolon found at line %d.', $currentLine); + + if ($phpcsFile->addFixableWarning($message, $stackPtr, 'Found')) { + $this->fix($stackPtr, $phpcsFile); + } + } + + /** + * @param int $position + * @param File $file + */ + private function fix(int $position, File $file): void + { + $fixer = $file->fixer; + $fixer->beginChangeset(); + + $fixer->replaceToken($position, ''); + + $fixer->endChangeset(); + } +} diff --git a/InpsydeTemplates/ruleset.xml b/InpsydeTemplates/ruleset.xml new file mode 100644 index 0000000..8b23714 --- /dev/null +++ b/InpsydeTemplates/ruleset.xml @@ -0,0 +1,6 @@ + + + + Coding standards for PHP templates. + + From 441f7ceca8d0df4ea6bfab9798630cd2031c3fe5 Mon Sep 17 00:00:00 2001 From: shvlv Date: Fri, 26 Jan 2024 23:20:23 +0200 Subject: [PATCH 2/7] test: add support for multiple ruleset; add trailing semicolon fixture --- tests/bootstrap.php | 2 +- tests/cases/FixturesTest.php | 24 ++++++++++++----- tests/fixtures/Psr4Fixture.php | 2 +- tests/fixtures/argument-type-declaration.php | 2 +- tests/fixtures/disable-call-user-func.php | 2 +- tests/fixtures/disallow-magic-serialize.php | 2 +- tests/fixtures/disallow-short-open-tag.php | 2 +- .../fixtures/element-name-minimal-length.php | 2 +- tests/fixtures/encoding-comment.php | 4 +-- tests/fixtures/forbidden-public-property.php | 2 +- tests/fixtures/function-body-start.php | 2 +- .../function-length-no-blank-lines.php | 4 +-- .../fixtures/function-length-no-comments.php | 4 +-- tests/fixtures/function-length.php | 4 +-- tests/fixtures/hook-closure-return.php | 2 +- tests/fixtures/hook-priority.php | 2 +- tests/fixtures/line-length.php | 3 +-- tests/fixtures/nesting-level.php | 2 +- tests/fixtures/no-accessors.php | 2 +- tests/fixtures/no-else.php | 4 +-- .../no-root-namespace-functions-multi.php | 2 +- .../no-root-namespace-functions-single.php | 2 +- tests/fixtures/no-top-level-define.php | 4 +-- tests/fixtures/property-per-class-limit.php | 4 +-- tests/fixtures/return-type-declaration.php | 2 +- tests/fixtures/static-closure.php | 2 +- tests/fixtures/trailing-semicolon.php | 27 +++++++++++++++++++ tests/fixtures/var-names-camel-case.php | 4 +-- tests/fixtures/var-names-no-local.php | 4 +-- tests/fixtures/var-names-no-props.php | 4 +-- tests/fixtures/var-names-snake-case.php | 4 +-- 31 files changed, 85 insertions(+), 47 deletions(-) create mode 100644 tests/fixtures/trailing-semicolon.php diff --git a/tests/bootstrap.php b/tests/bootstrap.php index d1ec1a4..ea8ee05 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -35,7 +35,7 @@ die('Please install via Composer before running tests.'); } -putenv("SNIFFS_PATH={$libDir}/Inpsyde/Sniffs"); +putenv("LIB_PATH={$libDir}"); putenv('SNIFFS_NAMESPACE=Inpsyde\\Sniffs'); putenv("FIXTURES_PATH={$testsDir}/fixtures"); diff --git a/tests/cases/FixturesTest.php b/tests/cases/FixturesTest.php index d8d7631..1dfab1b 100644 --- a/tests/cases/FixturesTest.php +++ b/tests/cases/FixturesTest.php @@ -209,24 +209,36 @@ private function createPhpcsForFixture( array $properties ): File { - $sniffFile = str_replace('.', '/', "{$sniffName}Sniff"); - $sniffPath = getenv('SNIFFS_PATH') . "/{$sniffFile}.php"; + $sniffFile = $this->buildSniffFile($sniffName); + $sniffPath = getenv('LIB_PATH') . "/{$sniffFile}.php"; if (!file_exists($sniffPath) || !is_readable($sniffPath)) { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped throw new Exception("Non-existent of unreadable sniff file '{$sniffPath}' found."); } + $standard = strtok($sniffName, '.'); $config = new Config(); - $config->standards = [dirname(getenv('SNIFFS_PATH'))]; - $config->sniffs = ["Inpsyde.{$sniffName}"]; + $config->standards = [getenv('LIB_PATH') . "/{$standard}"]; + $config->sniffs = [$sniffName]; $ruleset = new Ruleset($config); - $baseSniffNamespace = getenv('SNIFFS_NAMESPACE'); $sniffFqn = str_replace('/', '\\', $sniffFile); foreach ($properties as $name => $value) { - $ruleset->setSniffProperty("{$baseSniffNamespace}\\{$sniffFqn}", $name, $value); + $ruleset->setSniffProperty( + $sniffFqn, + $name, + ['scope' => 'sniff', 'value' => $value], + ); } return new LocalFile($fixtureFile, $ruleset, $config); } + + private function buildSniffFile(string $sniffName): string + { + $parts = explode('.', $sniffName); + array_splice($parts, 1, 0, 'Sniffs'); + + return implode('/', $parts) . 'Sniff'; + } } diff --git a/tests/fixtures/Psr4Fixture.php b/tests/fixtures/Psr4Fixture.php index acaec22..f3b1f60 100644 --- a/tests/fixtures/Psr4Fixture.php +++ b/tests/fixtures/Psr4Fixture.php @@ -1,5 +1,5 @@
diff --git a/tests/fixtures/element-name-minimal-length.php b/tests/fixtures/element-name-minimal-length.php index 350ddc4..cc36ab0 100644 --- a/tests/fixtures/element-name-minimal-length.php +++ b/tests/fixtures/element-name-minimal-length.php @@ -1,5 +1,5 @@ \ No newline at end of file +?> diff --git a/tests/fixtures/forbidden-public-property.php b/tests/fixtures/forbidden-public-property.php index 8c0a65d..8d6de37 100644 --- a/tests/fixtures/forbidden-public-property.php +++ b/tests/fixtures/forbidden-public-property.php @@ -1,5 +1,5 @@ @@ -117,4 +117,3 @@ function longComment() {
- diff --git a/tests/fixtures/nesting-level.php b/tests/fixtures/nesting-level.php index d5dc871..669f30c 100644 --- a/tests/fixtures/nesting-level.php +++ b/tests/fixtures/nesting-level.php @@ -1,5 +1,5 @@ + + + + + + + + + + + +
+ + +
+ + Date: Fri, 26 Jan 2024 23:30:57 +0200 Subject: [PATCH 3/7] docs: add TrailingSemicolon sniff documentation --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 7cc6a65..e914e55 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,24 @@ For **notes and configuration** see [`/inpsyde-custom-sniffs.md`](/inpsyde-custo ------------- +## Templates Rules + +InpsydeTemplates ruleset contains custom rules targeted to the PHP templates and views. +To enable the ruleset only for templates the following configuration could be used: + +```xml + + */templates/* + */views/* + +``` + +The following templates-specific rules are available: + +| Sniff name | Description | Has Config | Auto-Fixable | +|:--------------------|:------------------------------------------------|:----------:|:------------:| +| `TrailingSemicolon` | Remove trailing semicolon before close PHP tag. | | ✓ | + # Removing or Disabling Rules ## Rules Tree From 26c9ac5e814cf64f0992a1721d0a381aa2d501cf Mon Sep 17 00:00:00 2001 From: shvlv Date: Fri, 9 Feb 2024 09:47:03 +0200 Subject: [PATCH 4/7] feat: InpsydeTemplates inherits Inpsyde ruleset --- InpsydeTemplates/ruleset.xml | 4 ++++ README.md | 28 ++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/InpsydeTemplates/ruleset.xml b/InpsydeTemplates/ruleset.xml index 8b23714..098918e 100644 --- a/InpsydeTemplates/ruleset.xml +++ b/InpsydeTemplates/ruleset.xml @@ -3,4 +3,8 @@ Coding standards for PHP templates. + + + + diff --git a/README.md b/README.md index e914e55..dd7ec6c 100644 --- a/README.md +++ b/README.md @@ -184,15 +184,31 @@ For **notes and configuration** see [`/inpsyde-custom-sniffs.md`](/inpsyde-custo ## Templates Rules -InpsydeTemplates ruleset contains custom rules targeted to the PHP templates and views. -To enable the ruleset only for templates the following configuration could be used: +InpsydeTemplates ruleset extends Inpsyde ruleset apart from several rules that doesn't make sense in +the templating context. Several template-specific sniffs are added. + +The recommended way of using InpsydeTemplates ruleset: ```xml - - */templates/* - */views/* - + + ./src/ + ./tests + ./templates + ./block-views + + + */templates/* + */views/* + + + + */templates/* + */views/* + + ``` +The following Inpsyde rules are disabled: +* NoElse The following templates-specific rules are available: From 6b9960e1aa34cbfba1472edefb0c4cf78c9f96a8 Mon Sep 17 00:00:00 2001 From: shvlv Date: Fri, 9 Feb 2024 15:09:57 +0200 Subject: [PATCH 5/7] docs: improve "Template Rules" section --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index dd7ec6c..c20146b 100644 --- a/README.md +++ b/README.md @@ -182,12 +182,12 @@ For **notes and configuration** see [`/inpsyde-custom-sniffs.md`](/inpsyde-custo ------------- -## Templates Rules +## Template Rules -InpsydeTemplates ruleset extends Inpsyde ruleset apart from several rules that doesn't make sense in -the templating context. Several template-specific sniffs are added. +The `InpsydeTemplates` ruleset extends the standard `Inpsyde` ruleset with some template-specific +sniffs while disabling some rules that are not useful in templating context. -The recommended way of using InpsydeTemplates ruleset: +The recommended way to use the `InpsydeTemplates` ruleset is as follows: ```xml @@ -208,13 +208,13 @@ The recommended way of using InpsydeTemplates ruleset: ``` The following Inpsyde rules are disabled: -* NoElse +* `NoElse` The following templates-specific rules are available: -| Sniff name | Description | Has Config | Auto-Fixable | -|:--------------------|:------------------------------------------------|:----------:|:------------:| -| `TrailingSemicolon` | Remove trailing semicolon before close PHP tag. | | ✓ | +| Sniff name | Description | Has Config | Auto-Fixable | +|:--------------------|:--------------------------------------------------|:----------:|:------------:| +| `TrailingSemicolon` | Remove trailing semicolon before closing PHP tag. | | ✓ | # Removing or Disabling Rules From 827d5cd17b8c625a520f85de785779b0d1e8906f Mon Sep 17 00:00:00 2001 From: shvlv Date: Mon, 19 Feb 2024 22:02:41 +0200 Subject: [PATCH 6/7] style: format code; improve documentation --- InpsydeTemplates/Sniffs/Formatting/TrailingSemicolonSniff.php | 2 +- README.md | 4 ++-- tests/fixtures/encoding-comment.php | 1 - tests/fixtures/trailing-semicolon.php | 1 - 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/InpsydeTemplates/Sniffs/Formatting/TrailingSemicolonSniff.php b/InpsydeTemplates/Sniffs/Formatting/TrailingSemicolonSniff.php index 0496c74..caa7a96 100644 --- a/InpsydeTemplates/Sniffs/Formatting/TrailingSemicolonSniff.php +++ b/InpsydeTemplates/Sniffs/Formatting/TrailingSemicolonSniff.php @@ -86,7 +86,7 @@ public function process(File $phpcsFile, $stackPtr): void return; } - $message = sprintf('Trailing semicolon found at line %d.', $currentLine); + $message = sprintf('Trailing semicolon found in line %d.', $currentLine); if ($phpcsFile->addFixableWarning($message, $stackPtr, 'Found')) { $this->fix($stackPtr, $phpcsFile); diff --git a/README.md b/README.md index c20146b..9938325 100644 --- a/README.md +++ b/README.md @@ -194,7 +194,7 @@ The recommended way to use the `InpsydeTemplates` ruleset is as follows: ./src/ ./tests ./templates - ./block-views + ./views */templates/* @@ -207,7 +207,7 @@ The recommended way to use the `InpsydeTemplates` ruleset is as follows: ``` -The following Inpsyde rules are disabled: +The following `Inpsyde` rules are disabled: * `NoElse` The following templates-specific rules are available: diff --git a/tests/fixtures/encoding-comment.php b/tests/fixtures/encoding-comment.php index 6ccf639..f400d92 100644 --- a/tests/fixtures/encoding-comment.php +++ b/tests/fixtures/encoding-comment.php @@ -15,4 +15,3 @@ diff --git a/tests/fixtures/trailing-semicolon.php b/tests/fixtures/trailing-semicolon.php index ce95cda..89a6a9b 100644 --- a/tests/fixtures/trailing-semicolon.php +++ b/tests/fixtures/trailing-semicolon.php @@ -7,7 +7,6 @@ Date: Sun, 25 Feb 2024 18:16:51 +0100 Subject: [PATCH 7/7] Fix Psalm for PHP 7.4 --- Inpsyde/Helpers/FunctionDocBlock.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Inpsyde/Helpers/FunctionDocBlock.php b/Inpsyde/Helpers/FunctionDocBlock.php index 605a7ff..72a2e5f 100644 --- a/Inpsyde/Helpers/FunctionDocBlock.php +++ b/Inpsyde/Helpers/FunctionDocBlock.php @@ -170,11 +170,10 @@ public static function normalizeTypesString(string $typesString): array if (strpos($splitType, '&') !== false) { $splitType = rtrim(ltrim($splitType, '('), ')'); } elseif (strpos($splitType, '?') === 0) { - $splitType = substr($splitType, 1); - $hasNull = $hasNull || (($splitType !== '') && ($splitType !== false)); + $splitType = (string) substr($splitType, 1); + $hasNull = $hasNull || ($splitType !== ''); } - /** @psalm-suppress DocblockTypeContradiction */ - if (($splitType === false) || ($splitType === '')) { + if ($splitType === '') { continue; } if (strtolower($splitType) === 'null') {