Skip to content

Commit 3315305

Browse files
committed
✨ Set up the PHPCSDev ruleset
This adds a new external PHPCS standard called `PHPCSDev` for use by sniff developers to check the code style of their sniff repo code. Often, sniff repos will use the code style of the standard they are adding. However, not all sniff repos are actually about code style. So for those repos which need a basic standard which will still keep their code-base consistent, this standard should be useful. The standard checks the following: * Compliance with PSR-12 with a few, selective exceptions: - Constant visibility will not be demanded as the minimum PHP requirement of PHPCS is PHP 5.4 and constant visibility did not become available until PHP 7.1. - The first condition of a multi-line control structure is allowed to be on the same line as the control structure keyword (PSR2 style). **Note:** PSR12 enforces a blank line between each of the file header blocks. This rule can currently not (yet) be turned off in a modular way, i.e. for just one block. It is either on or off. This rule conflicts with the common practice of having no blank line between the PHP open tag and the file docblock. To turn this rule off, add `<exclude name="PSR12.Files.FileHeader.SpacingAfterBlock"/>` to the project specific ruleset. * Use of camelCaps variable and function names. * Use of normalized arrays. * All files, classes, functions and properties are documented with a docblock and contain the minimally needed information. Includes allowing for more than one `@since` tag to document a class's changelog. * Don't use Yoda conditions. * A small number of arbitrary additional code style checks. * PHP cross-version compatibility, while allowing for the tokens back-filled by PHPCS itself. **Note**: for optimal results, the project custom ruleset should set the `testVersion` config variable. This is not done by default as config variables are currently difficult to overrule. Refs: - squizlabs/PHP_CodeSniffer#2197 - squizlabs/PHP_CodeSniffer#1821 The ruleset can be used like any other ruleset and specific sniffs and settings can be added to or overruled from a custom project based ruleset. Includes: * Setting up the `composer.json`. * Adding QA checks for this ruleset via the Travis.
1 parent 2259c73 commit 3315305

File tree

3 files changed

+294
-0
lines changed

3 files changed

+294
-0
lines changed

.travis.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
dist: trusty
2+
3+
language: php
4+
5+
## Cache composer and apt downloads.
6+
cache:
7+
apt: true
8+
directories:
9+
# Cache directory for older Composer versions.
10+
- $HOME/.composer/cache/files
11+
# Cache directory for more recent Composer versions.
12+
- $HOME/.cache/composer/files
13+
14+
php:
15+
- 7.4
16+
17+
addons:
18+
apt:
19+
packages:
20+
- libxml2-utils
21+
22+
23+
before_install:
24+
# Speed up build time by disabling Xdebug when its not needed.
25+
- phpenv config-rm xdebug.ini || echo 'No xdebug config.'
26+
27+
- export XMLLINT_INDENT=" "
28+
29+
# --prefer-dist will allow for optimal use of the travis caching ability.
30+
- composer install --prefer-dist --no-suggest
31+
32+
script:
33+
# Validate the xml file.
34+
# @link http://xmlsoft.org/xmllint.html
35+
- xmllint --noout --schema ./vendor/squizlabs/php_codesniffer/phpcs.xsd ./PHPCSDev/ruleset.xml
36+
37+
# Check the code-style consistency of the xml files.
38+
- diff -B ./PHPCSDev/ruleset.xml <(xmllint --format "./PHPCSDev/ruleset.xml")
39+
40+
# Validate the composer.json file on low/high PHP versions.
41+
# @link https://getcomposer.org/doc/03-cli.md#validate
42+
- composer validate --no-check-all --strict

PHPCSDev/ruleset.xml

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
<?xml version="1.0"?>
2+
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PHPCSDev" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd">
3+
4+
<description>A PSR-12 based standard for use by sniff developers to check the code style of external PHPCS standards</description>
5+
6+
<!--
7+
####################################################################
8+
PHP: Check PHP cross version compatibility.
9+
For optimal results, the custom project ruleset should set the testVersion
10+
config variable.
11+
For compatibility with the PHP version supported by PHP_CodeSniffer 3.0+,
12+
this would typically be set like: <config name="testVersion" value="5.4-"/>.
13+
####################################################################
14+
-->
15+
<rule ref="PHPCompatibility">
16+
<exclude name="PHPCompatibility.Constants.NewConstants.t_finallyFound"/>
17+
<exclude name="PHPCompatibility.Constants.NewConstants.t_yieldFound"/>
18+
<exclude name="PHPCompatibility.Constants.NewConstants.t_ellipsisFound"/>
19+
<exclude name="PHPCompatibility.Constants.NewConstants.t_powFound"/>
20+
<exclude name="PHPCompatibility.Constants.NewConstants.t_pow_equalFound"/>
21+
<exclude name="PHPCompatibility.Constants.NewConstants.t_spaceshipFound"/>
22+
<exclude name="PHPCompatibility.Constants.NewConstants.t_coalesceFound"/>
23+
<exclude name="PHPCompatibility.Constants.NewConstants.t_coalesce_equalFound"/>
24+
<exclude name="PHPCompatibility.Constants.NewConstants.t_yield_fromFound"/>
25+
<exclude name="PHPCompatibility.Constants.NewConstants.t_bad_characterFound"/>
26+
</rule>
27+
28+
29+
<!--
30+
####################################################################
31+
Code style: Check style for compliance with PSR12.
32+
####################################################################
33+
-->
34+
<rule ref="PSR12">
35+
<!-- As PHP 5.4 is the minimum supported PHP version for PHP_CodeSniffer and
36+
most external standards, adding constant visibility is not (yet) an option. -->
37+
<exclude name="PSR12.Properties.ConstantVisibility"/>
38+
39+
<!-- Allow for the first condition of a multi-line control structure to be on the same line
40+
as the control structure keyword. -->
41+
<exclude name="PSR12.ControlStructures.ControlStructureSpacing.FirstExpressionLine"/>
42+
</rule>
43+
44+
45+
<!--
46+
####################################################################
47+
Code style: Naming Conventions.
48+
####################################################################
49+
-->
50+
51+
<!-- Check that variable names are in camelCase. -->
52+
<rule ref="Squiz.NamingConventions.ValidVariableName">
53+
<exclude name="Squiz.NamingConventions.ValidVariableName.PrivateNoUnderscore"/>
54+
</rule>
55+
56+
<!-- Check that function and method names are in camelCase. -->
57+
<rule ref="Generic.NamingConventions.CamelCapsFunctionName">
58+
<properties>
59+
<!-- Allow for two adjacent capital letters for acronyms. -->
60+
<property name="strict" value="false"/>
61+
</properties>
62+
</rule>
63+
64+
65+
<!--
66+
####################################################################
67+
Code style: Various other additions.
68+
####################################################################
69+
-->
70+
71+
<!-- PSR12 appears to ignore blank lines for superfluous whitespace and in several other places. Let's fix that. -->
72+
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace">
73+
<properties>
74+
<property name="ignoreBlankLines" value="false"/>
75+
</properties>
76+
</rule>
77+
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.StartFile">
78+
<severity>5</severity>
79+
</rule>
80+
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EndFile">
81+
<severity>5</severity>
82+
</rule>
83+
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EmptyLines">
84+
<severity>5</severity>
85+
</rule>
86+
87+
<!-- Ensure exactly one blank line before each property declaration. -->
88+
<rule ref="Squiz.WhiteSpace.MemberVarSpacing"/>
89+
90+
<!-- Ensure exactly one blank line before each function declaration, two blank lines
91+
before the first function and 0 after the last. -->
92+
<rule ref="Squiz.WhiteSpace.FunctionSpacing">
93+
<properties>
94+
<property name="spacing" value="1"/>
95+
<property name="spacingBeforeFirst" value="1"/>
96+
<property name="spacingAfterLast" value="0"/>
97+
</properties>
98+
</rule>
99+
100+
<rule ref="Generic.WhiteSpace.ArbitraryParenthesesSpacing"/>
101+
102+
<!-- Align the equal operator in assignment blocks. -->
103+
<rule ref="Generic.Formatting.MultipleStatementAlignment">
104+
<properties>
105+
<property name="maxPadding" value="25"/>
106+
</properties>
107+
</rule>
108+
109+
<rule ref="PEAR.Files.IncludingFile"/>
110+
<rule ref="PEAR.Files.IncludingFile.UseInclude">
111+
<severity>0</severity>
112+
</rule>
113+
<rule ref="PEAR.Files.IncludingFile.UseIncludeOnce">
114+
<severity>0</severity>
115+
</rule>
116+
117+
<!-- Disallow Yoda conditions. -->
118+
<rule ref="Generic.ControlStructures.DisallowYodaConditions"/>
119+
120+
<!-- Use self or static when referring to the class in use. -->
121+
<rule ref="Squiz.Classes.SelfMemberReference"/>
122+
123+
<!-- Only one object structure per file. -->
124+
<rule ref="Generic.Files.OneObjectStructurePerFile"/>
125+
126+
127+
<!--
128+
####################################################################
129+
Code style: Array declarations.
130+
####################################################################
131+
-->
132+
133+
<!-- Use normalized array indentation. -->
134+
<rule ref="Generic.Arrays.ArrayIndent"/>
135+
<rule ref="Squiz.Arrays.ArrayDeclaration"/>
136+
137+
<!-- Ignoring the Squiz indentation rules as normalized arrays are preferred. -->
138+
<rule ref="Squiz.Arrays.ArrayDeclaration.KeyNotAligned">
139+
<severity>0</severity>
140+
</rule>
141+
<rule ref="Squiz.Arrays.ArrayDeclaration.ValueNotAligned">
142+
<severity>0</severity>
143+
</rule>
144+
<rule ref="Squiz.Arrays.ArrayDeclaration.CloseBraceNotAligned">
145+
<severity>0</severity>
146+
</rule>
147+
148+
<!-- Single and multi-line arrays are both allowed. -->
149+
<rule ref="Squiz.Arrays.ArrayDeclaration.SingleLineNotAllowed">
150+
<severity>0</severity>
151+
</rule>
152+
<rule ref="Squiz.Arrays.ArrayDeclaration.MultiLineNotAllowed">
153+
<severity>0</severity>
154+
</rule>
155+
156+
157+
<!--
158+
####################################################################
159+
Docs: Verify the documentation.
160+
####################################################################
161+
-->
162+
163+
<rule ref="Generic.Commenting.DocComment">
164+
<!-- Having a @see or @internal tag before the @param tags is fine. -->
165+
<exclude name="Generic.Commenting.DocComment.ParamNotFirst"/>
166+
</rule>
167+
168+
<rule ref="PEAR.Commenting">
169+
<!-- Exclude PEAR specific tag requirements. -->
170+
<exclude name="PEAR.Commenting.FileComment.MissingVersion"/>
171+
<exclude name="PEAR.Commenting.FileComment.MissingAuthorTag"/>
172+
<exclude name="PEAR.Commenting.FileComment.MissingCategoryTag"/>
173+
<exclude name="PEAR.Commenting.FileComment.MissingLicenseTag"/>
174+
<exclude name="PEAR.Commenting.FileComment.MissingLinkTag"/>
175+
<exclude name="PEAR.Commenting.ClassComment.MissingAuthorTag"/>
176+
<exclude name="PEAR.Commenting.ClassComment.MissingCategoryTag"/>
177+
<exclude name="PEAR.Commenting.ClassComment.MissingLicenseTag"/>
178+
<exclude name="PEAR.Commenting.ClassComment.MissingLinkTag"/>
179+
<exclude name="PEAR.Commenting.ClassComment.MissingPackageTag"/>
180+
181+
<!-- Having a @see or @internal tag before the @category tag is fine. -->
182+
<exclude name="PEAR.Commenting.ClassComment.CategoryTagOrder"/>
183+
184+
<!-- Using @since for class changelog demands multiple tags. -->
185+
<exclude name="PEAR.Commenting.ClassComment.DuplicateSinceTag"/>
186+
</rule>
187+
188+
189+
<!--
190+
####################################################################
191+
Code Analysis additions.
192+
####################################################################
193+
-->
194+
195+
<!-- Efficiency: don't use function calls within the condition of a for loop. -->
196+
<rule ref="Generic.CodeAnalysis.ForLoopWithTestFunctionCall"/>
197+
198+
<!-- Efficiency: don't use size functions within a loop. -->
199+
<rule ref="Squiz.PHP.DisallowSizeFunctionsInLoops"/>
200+
201+
<!-- Efficiency: don't unnecessarily use double quotes. -->
202+
<rule ref="Squiz.Strings.DoubleQuoteUsage.NotRequired"/>
203+
204+
<!-- Error prevention: warns when an inner loop uses the same incrementor as the outer loop. -->
205+
<rule ref="Generic.CodeAnalysis.JumbledIncrementer"/>
206+
207+
<!-- Error prevention: don't assign from within a condition. -->
208+
<rule ref="Generic.CodeAnalysis.AssignmentInCondition">
209+
<exclude name="Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition"/>
210+
</rule>
211+
212+
<!-- Clean up: remove redundant code. -->
213+
<rule ref="Squiz.PHP.NonExecutableCode"/>
214+
215+
<!-- Clean up: no empty statements. -->
216+
<rule ref="Generic.CodeAnalysis.EmptyPHPStatement"/>
217+
218+
<!-- Parse error prevention: guard against merge conflict artifacts. -->
219+
<rule ref="Generic.VersionControl.GitMergeConflict"/>
220+
221+
</ruleset>

composer.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name" : "phpcsstandards/phpcsdevcs",
3+
"description" : "Sane ruleset for the code in external standards for PHP_CodeSniffer.",
4+
"type" : "phpcodesniffer-standard",
5+
"keywords" : [ "phpcs", "php_codesniffer", "phpcodesniffer-standard" ],
6+
"license" : "LGPL-3.0-or-later",
7+
"authors" : [
8+
{
9+
"name" : "Juliette Reinders Folmer",
10+
"role" : "lead",
11+
"homepage" : "https://github.com/jrfnl"
12+
},
13+
{
14+
"name" : "Contributors",
15+
"homepage" : "https://github.com/PHPCSStandards/PHPCSDevCS/graphs/contributors"
16+
}
17+
],
18+
"support" : {
19+
"issues" : "https://github.com/PHPCSStandards/PHPCSDevCS/issues",
20+
"source" : "https://github.com/PHPCSStandards/PHPCSDevCS"
21+
},
22+
"require" : {
23+
"php" : ">=5.4",
24+
"squizlabs/php_codesniffer" : "^3.5.0",
25+
"phpcompatibility/php-compatibility" : "^9.0.0",
26+
"dealerdirect/phpcodesniffer-composer-installer" : "^0.3 || ^0.4.1 || ^0.5 || ^0.6.2"
27+
},
28+
"require-dev" : {
29+
"roave/security-advisories" : "dev-master"
30+
}
31+
}

0 commit comments

Comments
 (0)