Skip to content

Commit 61a9be9

Browse files
authored
Merge pull request #257 from PHPCSStandards/develop
Release PHPCSExtra 1.1.0
2 parents 029af41 + ae2326d commit 61a9be9

File tree

82 files changed

+6306
-19
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+6306
-19
lines changed

.github/workflows/test.yml

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -168,36 +168,58 @@ jobs:
168168
- name: Run the unit tests with code coverage
169169
run: composer coverage
170170

171-
# Uploading the results with PHP Coveralls v1 won't work from GH Actions, so switch the PHP version.
172-
- name: Switch to PHP 7.4
173-
if: ${{ success() && matrix.php != '7.4' }}
171+
# PHP Coveralls v2 (which supports GH Actions) has a PHP 5.5 minimum, so switch the PHP version.
172+
- name: Switch to PHP latest
173+
if: ${{ success() && matrix.php == '5.4' }}
174174
uses: shivammathur/setup-php@v2
175175
with:
176-
php-version: 7.4
176+
php-version: 'latest'
177177
coverage: none
178178

179-
# Global install is used to prevent a conflict with the local composer.lock in PHP 8.0+.
179+
# Global install is used to prevent a conflict with the local composer.lock.
180180
- name: Install Coveralls
181181
if: ${{ success() }}
182-
run: composer global require php-coveralls/php-coveralls:"^2.5.3" --no-interaction
182+
run: composer global require php-coveralls/php-coveralls:"^2.6.0" --no-interaction
183183

184-
- name: Upload coverage results to Coveralls
185-
if: ${{ success() }}
184+
- name: Upload coverage results to Coveralls (normal)
185+
if: ${{ success() && github.actor != 'dependabot[bot]' }}
186186
env:
187187
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
188188
COVERALLS_PARALLEL: true
189189
COVERALLS_FLAG_NAME: php-${{ matrix.php }}-phpcs-${{ matrix.phpcs_version }}
190190
run: php-coveralls -v -x build/logs/clover.xml
191191

192+
# Dependabot does not have access to secrets, other than the GH token.
193+
# Ref: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/automating-dependabot-with-github-actions
194+
# Ref: https://github.com/lemurheavy/coveralls-public/issues/1721
195+
- name: Upload coverage results to Coveralls (Dependabot)
196+
if: ${{ success() && github.actor == 'dependabot[bot]' }}
197+
env:
198+
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
199+
COVERALLS_PARALLEL: true
200+
COVERALLS_FLAG_NAME: php-${{ matrix.php }}-phpcs-${{ matrix.phpcs_version }}
201+
run: php-coveralls -v -x build/logs/clover.xml
202+
192203
coveralls-finish:
193204
needs: coverage
194205
if: always() && needs.coverage.result == 'success'
195206

196207
runs-on: ubuntu-latest
197208

198209
steps:
199-
- name: Coveralls Finished
210+
- name: Coveralls Finished (normal)
211+
if: ${{ github.actor != 'dependabot[bot]' }}
200212
uses: coverallsapp/github-action@v2
201213
with:
202214
github-token: ${{ secrets.COVERALLS_TOKEN }}
203215
parallel-finished: true
216+
217+
# Dependabot does not have access to secrets, other than the GH token.
218+
# Ref: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/automating-dependabot-with-github-actions
219+
# Ref: https://github.com/lemurheavy/coveralls-public/issues/1721
220+
- name: Coveralls Finished (Dependabot)
221+
if: ${{ github.actor == 'dependabot[bot]' }}
222+
uses: coverallsapp/github-action@v2
223+
with:
224+
github-token: ${{ secrets.GITHUB_TOKEN }}
225+
parallel-finished: true

CHANGELOG.md

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,60 @@ This projects adheres to [Keep a CHANGELOG](http://keepachangelog.com/) and uses
1414

1515
_Nothing yet._
1616

17+
## [1.1.0] - 2023-07-19
18+
19+
### Added
20+
21+
#### Universal
22+
23+
* :wrench: :books: New `Universal.CodeAnalysis.NoEchoSprintf` sniff to detect use of the inefficient `echo [v]sprintf(...);` combi and recommends using `[v]printf()` instead. [#242]
24+
* :bar_chart: :books: New `Universal.FunctionDeclarations.NoLongClosures` sniff to detect "long" closures and recommend using a named function instead. [#240]
25+
The sniff offers the following properties to influence its behaviour: `recommendedLines` (defaults to `5`), `maxLines` (defaults to `8`), `ignoreCommentLines` (defaults to `true`) and `ignoreEmptyLines` (defaults to `true`).
26+
* :wrench: :bar_chart: :books: New `Universal.FunctionDeclarations.RequireFinalMethodsInTraits` sniff to enforce non-private, non-abstract methods in traits to be declared as `final`. [#243], [#245]
27+
There is a separate `NonFinalMagicMethodFound` error code for magic methods to allow those to be excluded from the check.
28+
* :wrench: :bar_chart: :books: New `Universal.UseStatements.DisallowMixedGroupUse` sniff to disallow group use statements which import a combination of namespace/OO construct, functions and/or constants in one statement. [#241], [#246]
29+
Note: the fixer will use a semi-standardized format for group use statements. If there are more specific requirements for the formatting of group use statements, the ruleset configurator should ensure that additional sniffs are included in the ruleset to enforce the required format.
30+
* :wrench: :bar_chart: :books: New `Universal.UseStatements.KeywordSpacing` sniff to enforce the use of a single space after the `use`, `function`, `const` keywords and both before and after the `as` keyword in import `use` statements. [#247]
31+
The sniff has modular error codes to allow for disabling individual checks.
32+
* :wrench: :books: New `Universal.UseStatements.NoUselessAliases` sniff to detect useless aliases (aliasing something to its original name) in import use statements. [#244]
33+
Note: as OO and function names in PHP are case-insensitive, aliasing to the same name, using a different case is also considered useless.
34+
* :wrench: :bar_chart: :books: New `Universal.WhiteSpace.CommaSpacing` sniff to enforce that there is no space before a comma and exactly one space, or a new line, after a comma. [#254]
35+
Additionally, the sniff also enforces that the comma should follow the code and not be placed after a trailing comment.
36+
The sniff has modular error codes to allow for disabling individual checks and checks in certain contexts.
37+
The sniff will respect a potentially set [`php_version` configuration option][php_version-config] when deciding how to handle the spacing after a heredoc/nowdoc closer.
38+
39+
### Changed
40+
41+
#### Universal
42+
43+
* Minor performance improvements for the `Universal.Arrays.DuplicateArrayKey` and the `Universal.CodeAnalysis.ConstructorDestructorReturn` sniffs. [#251], [#252]
44+
45+
#### Other
46+
47+
* Composer: The minimum `PHPCSUtils` requirement has been updated to `^1.0.8` (was `^1.0.6`). [#249], [#254]
48+
* Various housekeeping.
49+
50+
[#240]: https://github.com/PHPCSStandards/PHPCSExtra/pull/240
51+
[#241]: https://github.com/PHPCSStandards/PHPCSExtra/pull/241
52+
[#242]: https://github.com/PHPCSStandards/PHPCSExtra/pull/242
53+
[#243]: https://github.com/PHPCSStandards/PHPCSExtra/pull/243
54+
[#244]: https://github.com/PHPCSStandards/PHPCSExtra/pull/244
55+
[#245]: https://github.com/PHPCSStandards/PHPCSExtra/pull/245
56+
[#246]: https://github.com/PHPCSStandards/PHPCSExtra/pull/246
57+
[#247]: https://github.com/PHPCSStandards/PHPCSExtra/pull/247
58+
[#249]: https://github.com/PHPCSStandards/PHPCSExtra/pull/249
59+
[#251]: https://github.com/PHPCSStandards/PHPCSExtra/pull/251
60+
[#252]: https://github.com/PHPCSStandards/PHPCSExtra/pull/252
61+
[#254]: https://github.com/PHPCSStandards/PHPCSExtra/pull/254
62+
63+
1764
## [1.0.4] - 2023-06-18
1865

1966
### Changed
2067

2168
#### Other
2269

23-
* Composer: The minimum `PHPCSUtils` requirement has been updated to `^1.0.6` (was ^1.0.0). [#237]
70+
* Composer: The minimum `PHPCSUtils` requirement has been updated to `^1.0.6` (was `^1.0.0`). [#237]
2471
* Various housekeeping.
2572

2673
### Fixed
@@ -183,7 +230,7 @@ For the full list of features, please see the changelogs of the alpha/rc release
183230
* Updated the sniffs for compatibility with PHPCSUtils 1.0.0-alpha4. [#134]
184231
* Updated the sniffs to correctly handle PHP 8.0/8.1/8.2 features whenever relevant.
185232
* Readme: Updated installation instructions for compatibility with Composer 2.2+. [#101]
186-
* Composer: The minimum `PHP_CodeSniffer` requirement has been updated to `^3.7.1` (was ^3.3.1). [#115], [#130]
233+
* Composer: The minimum `PHP_CodeSniffer` requirement has been updated to `^3.7.1` (was `^3.3.1`). [#115], [#130]
187234
* Composer: The package will now identify itself as a static analysis tool. Thanks [@GaryJones]! [#126]
188235
* All non-`abstract` classes in this package are now `final`. [#121]
189236
* All XML documentation now has a schema annotation. [#128]
@@ -441,6 +488,7 @@ This initial alpha release contains the following sniffs:
441488
[php_version-config]: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Configuration-Options#setting-the-php-version
442489

443490
[Unreleased]: https://github.com/PHPCSStandards/PHPCSExtra/compare/stable...HEAD
491+
[1.1.0]: https://github.com/PHPCSStandards/PHPCSExtra/compare/1.0.4...1.1.0
444492
[1.0.4]: https://github.com/PHPCSStandards/PHPCSExtra/compare/1.0.3...1.0.4
445493
[1.0.3]: https://github.com/PHPCSStandards/PHPCSExtra/compare/1.0.2...1.0.3
446494
[1.0.2]: https://github.com/PHPCSStandards/PHPCSExtra/compare/1.0.1...1.0.2

README.md

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Minimum Requirements
4646

4747
* PHP 5.4 or higher.
4848
* [PHP_CodeSniffer][phpcs-gh] version **3.7.1** or higher.
49-
* [PHPCSUtils][phpcsutils-gh] version **1.0.0** or higher.
49+
* [PHPCSUtils][phpcsutils-gh] version **1.0.8** or higher.
5050

5151

5252
Installation
@@ -61,15 +61,15 @@ Installing via Composer is highly recommended.
6161
Run the following from the root of your project:
6262
```bash
6363
composer config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
64-
composer require --dev phpcsstandards/phpcsextra:"^1.0"
64+
composer require --dev phpcsstandards/phpcsextra:"^1.1.0"
6565
```
6666

6767
### Composer Global Installation
6868

6969
Alternatively, you may want to install this standard globally:
7070
```bash
7171
composer global config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
72-
composer global require --dev phpcsstandards/phpcsextra:"^1.0"
72+
composer global require --dev phpcsstandards/phpcsextra:"^1.1.0"
7373
```
7474

7575
### Updating to a newer version
@@ -220,6 +220,10 @@ Require a consistent modifier keyword order for class declarations.
220220
If a [`php_version` configuration option][php_version-config] has been passed to PHPCS using either `--config-set` or `--runtime-set`, it will be respected by the sniff.
221221
In effect, this means that the sniff will only report on PHP4-style constructors if the configured PHP version is less than 8.0.
222222

223+
#### `Universal.CodeAnalysis.NoEchoSprintf` :wrench: :books:
224+
225+
Detects use of the inefficient `echo [v]sprintf(...);` combi. Use `[v]printf()` instead.
226+
223227
#### `Universal.CodeAnalysis.ForeachUniqueAssignment` :wrench: :books:
224228

225229
Detects `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.
@@ -278,6 +282,26 @@ Enforce for a file to either declare (global/namespaced) functions or declare OO
278282
* Also note: This sniff has no opinion on multiple OO structures being declared in one file.
279283
If you want to sniff for that, use the PHPCS native `Generic.Files.OneObjectStructurePerFile` sniff.
280284

285+
#### `Universal.FunctionDeclarations.NoLongClosures` :bar_chart: :books:
286+
287+
Detects "long" closures and recommends using a named function instead.
288+
289+
The sniff is configurable by setting any of the following properties in a custom ruleset:
290+
* `recommendedLines` (int): determines when a warning will be thrown.
291+
Defaults to `5`, meaning a warning with the errorcode `ExceedsRecommended` will be thrown if the closure is more than 5 lines long.
292+
* `maxLines` (int): determines when an error will be thrown.
293+
Defaults to `8`, meaning that an error with the errorcode `ExceedsMaximum` will be thrown if the closure is more than 8 lines long.
294+
* `ignoreCommentLines` (bool): whether or not comment-only lines should be ignored for the lines count.
295+
Defaults to `true`.
296+
* `ignoreEmptyLines` (bool): whether or not blank lines should be ignored for the lines count.
297+
Defaults to `true`.
298+
299+
#### `Universal.FunctionDeclarations.RequireFinalMethodsInTraits` :wrench: :bar_chart: :books:
300+
301+
Enforce non-private, non-abstract methods in traits to be declared as `final`.
302+
303+
The available error codes are: `NonFinalMethodFound` and `NonFinalMagicMethodFound`.
304+
281305
#### `Universal.Lists.DisallowLongListSyntax` :wrench: :books:
282306

283307
Disallow the use of long `list`s.
@@ -368,6 +392,13 @@ The available error codes are: `UnionTypeSpacesBefore`, `UnionTypeSpacesAfter`,
368392

369393
Disallow short open echo tags `<?=` containing more than one PHP statement.
370394

395+
#### `Universal.UseStatements.DisallowMixedGroupUse` :wrench: :bar_chart: :books:
396+
397+
Disallow group use statements which import a combination of namespace/OO construct, functions and/or constants in one statement.
398+
399+
Note: the fixer will use a semi-standardized format for group use statements.
400+
If there are more specific requirements for the formatting of group use statements, the ruleset configurator should ensure that additional sniffs are included in the ruleset to enforce the required format.
401+
371402
#### `Universal.UseStatements.DisallowUseClass` :bar_chart: :books:
372403

373404
Forbid using import `use` statements for classes/traits/interfaces/enums.
@@ -394,6 +425,14 @@ Enforce that `function` and `const` keywords when used in an import `use` statem
394425

395426
Companion sniff to the PHPCS native `Generic.PHP.LowerCaseKeyword` sniff which doesn't cover these keywords when used in an import `use` statement.
396427

428+
#### `Universal.UseStatements.KeywordSpacing` :wrench: :bar_chart: :books:
429+
430+
Enforce the use of a single space after the `use`, `function`, `const` keywords and both before and after the `as` keyword in import `use` statements.
431+
432+
Companion sniff to the PHPCS native `Generic.WhiteSpace.LanguageConstructSpacing` sniff which doesn't cover the `function`, `const` and `as` keywords when used in an import `use` statement.
433+
434+
The sniff has modular error codes to allow for disabling individual checks. The error codes are: `SpaceAfterUse`, `SpaceAfterFunction`, `SpaceAfterConst`, `SpaceBeforeAs` and `SpaceAfterAs`.
435+
397436
#### `Universal.UseStatements.NoLeadingBackslash` :wrench: :bar_chart: :books:
398437

399438
Verify that a name being imported in an import `use` statement does not start with a leading backslash.
@@ -402,13 +441,40 @@ Names in import `use` statements should always be fully qualified, so a leading
402441

403442
This sniff handles all types of import use statements supported by PHP, in contrast to other sniffs for the same in, for instance, the PHPCS native `PSR12` or the Slevomat standard, which are incomplete.
404443

444+
#### `Universal.UseStatements.NoUselessAliases` :wrench: :books:
445+
446+
Detects useless aliases in import use statements.
447+
448+
Aliasing something to the same name as the original construct is considered useless (though allowed in PHP).
449+
Note: as OO and function names in PHP are case-insensitive, aliasing to the same name, using a different case is also considered useless.
450+
405451
#### `Universal.WhiteSpace.AnonClassKeywordSpacing` :wrench: :bar_chart: :books:
406452

407453
Standardize the amount of spacing between the `class` keyword and the open parenthesis (if any) for anonymous class declarations.
408454

409455
* This sniff contains an `spacing` property to set the amount of spaces the sniff should check for.
410456
Accepted values: (int) number of spaces. Defaults to `0` (spaces).
411457

458+
#### `Universal.WhiteSpace.CommaSpacing` :wrench: :bar_chart: :books:
459+
460+
Enforce that there is no space before a comma and exactly one space, or a new line, after a comma.
461+
462+
Additionally, the sniff also enforces that the comma should follow the code and not be placed after a trailing comment.
463+
464+
For the spacing part, the sniff makes the following exceptions:
465+
1. A comma preceded or followed by a parenthesis, curly or square bracket.
466+
These will not be flagged to prevent conflicts with sniffs handling spacing around braces.
467+
2. A comma preceded or followed by another comma, like for skipping items in a list assignment.
468+
These will not be flagged.
469+
470+
* The sniff has a separate error code - `TooMuchSpaceAfterCommaBeforeTrailingComment` - for when a comma is found with more than one space after it, followed by a trailing comment.
471+
Exclude this error code to allow trailing comment alignment.
472+
* The other error codes the sniff uses, `SpaceBefore`, `TooMuchSpaceAfter` and `NoSpaceAfter`, may be suffixed with a context indicator - `*InFunctionDeclaration`, `*InFunctionCall`, `*InClosureUse` or `*InDeclare` -.
473+
This allows for disabling the sniff in any of these contexts by excluding the specific suffixed error codes.
474+
* The sniff will respect a potentially set [`php_version` configuration option][php_version-config] when deciding how to handle the spacing after a heredoc/nowdoc closer.
475+
In effect, this means that the sniff will enforce a new line between the closer and a comma if the configured PHP version is less than 7.3.
476+
When no `php_version` is passed, the sniff will handle the spacing between a heredoc/nowdoc closer and a comma based on whether it is a cross-version compatible heredoc/nowdoc (enforce new line) or a flexible heredoc/nowdoc (enforce no space).
477+
412478
#### `Universal.WhiteSpace.DisallowInlineTabs` :wrench: :books:
413479

414480
Enforce using spaces for mid-line alignment.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0"?>
2+
<documentation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://phpcsstandards.github.io/PHPCSDevTools/phpcsdocs.xsd"
4+
title="No Echo Sprintf"
5+
>
6+
<standard>
7+
<![CDATA[
8+
Detects use of `echo [v]sprintf(...);`. Use `[v]printf()` instead.
9+
]]>
10+
</standard>
11+
<code_comparison>
12+
<code title="Valid: using [v]printf() or echo with anything but [v]sprintf().">
13+
<![CDATA[
14+
<em>printf</em>('text %s text', $var);
15+
<em>echo callMe</em>('text %s text', $var);
16+
]]>
17+
</code>
18+
<code title="Invalid: using echo [v]sprintf().">
19+
<![CDATA[
20+
<em>echo sprintf</em>('text %s text', $var);
21+
<em>echo vsprintf</em>('text %s text', [$var]);
22+
]]>
23+
</code>
24+
</code_comparison>
25+
</documentation>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0"?>
2+
<documentation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://phpcsstandards.github.io/PHPCSDevTools/phpcsdocs.xsd"
4+
title="No Long Closures"
5+
>
6+
<standard>
7+
<![CDATA[
8+
Forbids the use of long closures and recommends using named functions instead.
9+
10+
By default a closure is considered "longish" (warning) when it contains more than 5 lines of code and too long (error) when it contains more than 8 lines of code.
11+
Also, by default only code lines are counted and blank lines and comment lines are ignored.
12+
Each of these settings can be changed via the sniff configuration.
13+
]]>
14+
</standard>
15+
<code_comparison>
16+
<code title="Valid: Short closure.">
17+
<![CDATA[
18+
$closure = function() {
19+
line1();
20+
line2();
21+
line3();
22+
};
23+
]]>
24+
</code>
25+
<code title="Invalid: Long closure.">
26+
<![CDATA[
27+
$closure = function() {
28+
line1();
29+
line2();
30+
line3();
31+
line4();
32+
line5();
33+
line6();
34+
line7();
35+
line8();
36+
line9();
37+
line10();
38+
};
39+
]]>
40+
</code>
41+
</code_comparison>
42+
</documentation>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0"?>
2+
<documentation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://phpcsstandards.github.io/PHPCSDevTools/phpcsdocs.xsd"
4+
title="Require Final Methods in Traits"
5+
>
6+
<standard>
7+
<![CDATA[
8+
Requires the use of the `final` keyword for non-abstract, non-private methods in traits.
9+
]]>
10+
</standard>
11+
<code_comparison>
12+
<code title="Valid: Final methods in a trait.">
13+
<![CDATA[
14+
trait Foo {
15+
<em>final</em> public function bar() {}
16+
<em>final</em> public static function baz() {}
17+
18+
// Also valid (out of scope):
19+
protected abstract function overload() {}
20+
private function okay() {}
21+
}
22+
]]>
23+
</code>
24+
<code title="Invalid: Non-final methods in a trait.">
25+
<![CDATA[
26+
trait Foo {
27+
<em>public function</em> bar() {}
28+
<em>protected static function</em> baz() {}
29+
}
30+
]]>
31+
</code>
32+
</code_comparison>
33+
</documentation>

0 commit comments

Comments
 (0)