Skip to content

Commit ed86d20

Browse files
Chris Pennychrispenny
authored andcommitted
Add PHPCS. Remove redundant docblocks. Move test classes
1 parent 624c172 commit ed86d20

17 files changed

+341
-333
lines changed

composer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
},
2929
"require-dev": {
3030
"phpunit/phpunit": "^9.5",
31-
"tractorcow/silverstripe-fluent": "^6.0"
31+
"tractorcow/silverstripe-fluent": "^6.0",
32+
"slevomat/coding-standard": "^8.0"
3233
},
3334
"extra": {
3435
"expose": [
@@ -47,7 +48,8 @@
4748
"allow-plugins": {
4849
"composer/installers": true,
4950
"silverstripe/vendor-plugin": true,
50-
"silverstripe/recipe-plugin": true
51+
"silverstripe/recipe-plugin": true,
52+
"dealerdirect/phpcodesniffer-composer-installer": true
5153
}
5254
}
5355
}

phpcs.xml.dist

Lines changed: 173 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,178 @@
1-
<?xml version="1.0" encoding="UTF-8"?>
2-
<ruleset name="SilverStripe">
3-
<description>CodeSniffer ruleset for SilverStripe coding conventions.</description>
1+
<?xml version="1.0"?>
2+
<ruleset name="project-coding-standards">
3+
<description>Coding standards for SilverStripe based project</description>
44

55
<file>src</file>
66
<file>tests</file>
77

8-
<!-- base rules are PSR-2 -->
9-
<rule ref="PSR2" >
10-
<!-- Current exclusions -->
11-
<exclude name="PSR1.Methods.CamelCapsMethodName" />
12-
<exclude name="PSR1.Files.SideEffects.FoundWithSymbols" />
13-
<exclude name="PSR2.Classes.PropertyDeclaration" />
14-
<exclude name="PSR2.ControlStructures.SwitchDeclaration" /> <!-- causes php notice while linting -->
15-
<exclude name="PSR2.ControlStructures.SwitchDeclaration.WrongOpenercase" />
16-
<exclude name="PSR2.ControlStructures.SwitchDeclaration.WrongOpenerdefault" />
17-
<exclude name="PSR2.ControlStructures.SwitchDeclaration.TerminatingComment" />
18-
<exclude name="PSR2.Methods.MethodDeclaration.Underscore" />
19-
<exclude name="Squiz.Scope.MethodScope" />
20-
<exclude name="Squiz.Classes.ValidClassName.NotCamelCaps" />
21-
<exclude name="Generic.Files.LineLength.TooLong" />
22-
<exclude name="PEAR.Functions.ValidDefaultValue.NotAtEnd" />
23-
</rule>
24-
25-
<rule ref="Squiz.Strings.ConcatenationSpacing">
26-
<properties>
27-
<property name="spacing" value="1" />
28-
<property name="ignoreNewlines" value="true"/>
29-
</properties>
30-
</rule>
31-
32-
<!-- use short array syntax (less thirdparty) -->
33-
<rule ref="Generic.Arrays.DisallowLongArraySyntax">
34-
<exclude-pattern>/thirdparty/*</exclude-pattern>
35-
</rule>
36-
37-
<!-- include php files only -->
38-
<arg name="extensions" value="php,lib,inc,php5"/>
8+
<!-- Don't sniff third party libraries -->
9+
<exclude-pattern>./vendor/*</exclude-pattern>
10+
<exclude-pattern>*/thirdparty/*</exclude-pattern>
11+
12+
<!-- Show progress and output sniff names on violation, and add colours -->
13+
<arg value="p" />
14+
<arg name="colors" />
15+
<arg value="s" />
16+
17+
<!-- Use PSR-2 as a base standard -->
18+
<rule ref="PSR2">
19+
<!-- Allow non camel cased method names - some base SS method names are PascalCase or snake_case -->
20+
<exclude name="PSR1.Methods.CamelCapsMethodName.NotCamelCaps"/>
21+
<!-- This rule conflicts with Slevomat standards requiring an empty line before closing brace -->
22+
<exclude name="PSR2.Classes.ClassDeclaration.CloseBraceAfterBody"/>
23+
</rule>
24+
25+
<!-- Ensures that arrays are indented one tab stop -->
26+
<rule ref="Generic.Arrays.ArrayIndent"/>
27+
<!-- Makes sure that any use of double quotes strings are warranted -->
28+
<rule ref="Squiz.Strings.DoubleQuoteUsage"/>
29+
30+
<!-- All "use" statements must be used in the code. -->
31+
<rule ref="./vendor/slevomat/coding-standard/SlevomatCodingStandard/ruleset.xml">
32+
<!-- We need to call __invoke for our SerializableClosure -->
33+
<exclude name="SlevomatCodingStandard.PHP.DisallowDirectMagicInvokeCall.DisallowDirectMagicInvokeCall"/>
34+
<!-- Class length does not equal complexity. We absolutely don't care about class length -->
35+
<exclude name="SlevomatCodingStandard.Classes.ClassLength.ClassTooLong"/>
36+
<exclude name="SlevomatCodingStandard.Files.FileLength.FileTooLong"/>
37+
<!-- Don't force the use of early exit. We do try to use it though, and you might get PR feedback where -->
38+
<!-- early exit is appropriate -->
39+
<exclude name="SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed"/>
40+
<!-- Similar to above, "useless conditions" aren't always useless if they increase readability -->
41+
<exclude name="SlevomatCodingStandard.ControlStructures.UselessIfConditionWithReturn.UselessIfCondition"/>
42+
<!-- Multi or single line are both fine. Feel free to remove this exclusion if you prefer to enforce single line where they're possible -->
43+
<exclude name="SlevomatCodingStandard.Commenting.RequireOneLineDocComment.MultiLineDocComment"/>
44+
<exclude name="SlevomatCodingStandard.Commenting.DisallowOneLinePropertyDocComment.OneLinePropertyComment"/>
45+
<!-- We're not punishing folks for adding annotations (even if the method is self documenting) -->
46+
<exclude name="SlevomatCodingStandard.TypeHints.ReturnTypeHint.UselessAnnotation"/>
47+
<!-- There is actually a bug with this sniffer. If you use doc annotation to disable a rule, this sniffer (sometimes) throws an "Undefined index" error -->
48+
<exclude name="SlevomatCodingStandard.Commenting.DisallowCommentAfterCode.DisallowedCommentAfterCode"/>
49+
<!-- Late Static Binding is used often in SS -->
50+
<exclude name="SlevomatCodingStandard.Classes.DisallowLateStaticBindingForConstants"/>
51+
<!-- Multiline comments is what we use as a standard in SS -->
52+
<exclude name="SlevomatCodingStandard.Commenting.RequireOneLinePropertyDocComment"/>
53+
<!-- Disabled by default, but you may be interested in reading up on Yoda conditions to see if it's -->
54+
<!-- something that you would like to start using: https://en.wikipedia.org/wiki/Yoda_conditions -->
55+
<exclude name="SlevomatCodingStandard.ControlStructures.RequireYodaComparison.RequiredYodaComparison"/>
56+
<!-- It's quite common when extended base SS methods or extension points, that there are unused params -->
57+
<exclude name="SlevomatCodingStandard.Functions.UnusedParameter"/>
58+
<!-- Allows us to namespace {} the base Page class -->
59+
<exclude name="SlevomatCodingStandard.Namespaces.NamespaceDeclaration.DisallowedBracketedSyntax"/>
60+
<!-- There are two rules which conflict. NewWithoutParentheses and UselessParentheses. One must be disabled -->
61+
<!-- We allow new Class(); rather than new Class;-->
62+
<exclude name="SlevomatCodingStandard.ControlStructures.NewWithoutParentheses"/>
63+
<!-- Do not require fully qualified class names in annotation -->
64+
<exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions"/>
65+
<exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation.NonFullyQualifiedClassName"/>
66+
<exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedGlobalConstants"/>
67+
<exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedGlobalFunctions.NonFullyQualified"/>
68+
<!-- We generally allow the use of any namespace -->
69+
<exclude name="SlevomatCodingStandard.Namespaces.UseOnlyWhitelistedNamespaces"/>
70+
<!-- Not something we do in SS -->
71+
<exclude name="SlevomatCodingStandard.TypeHints.DeclareStrictTypes"/>
72+
<!-- Array type hint syntax is very useful -->
73+
<exclude name="SlevomatCodingStandard.TypeHints.DisallowArrayTypeHintSyntax"/>
74+
<!-- Using mixed type is a way to get around the fact that we often cannot strictly type our methods if we -->
75+
<!-- are extending a base SS method -->
76+
<exclude name="SlevomatCodingStandard.TypeHints.DisallowMixedTypeHint"/>
77+
<!-- allow private static -->
78+
<exclude name="SlevomatCodingStandard.Classes.UnusedPrivateElements.UnusedProperty"/>
79+
<!-- disable until php 7.3 is implemented in the project -->
80+
<exclude name="SlevomatCodingStandard.Functions.TrailingCommaInCall.MissingTrailingComma"/>
81+
<!-- Don't require traversable type hints -->
82+
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingTraversableTypeHintSpecification"/>
83+
<exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingTraversableTypeHintSpecification"/>
84+
<exclude name="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification"/>
85+
<!-- Even if you strictly type, there are other reasons to add a DocComment (EG: to add @codeCoverageIgnore -->
86+
<exclude name="SlevomatCodingStandard.TypeHints.UselessConstantTypeHintSniff.UselessDocComment"/>
87+
<!-- Even if you strictly type, there are other reasons to add a DocComment (EG: to add @codeCoverageIgnore -->
88+
<exclude name="SlevomatCodingStandard.Commenting.UselessFunctionDocComment.UselessDocComment"/>
89+
<!-- No need to namespace global functions -->
90+
<exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedGlobalFunctions.NonFullyQualified"/>
91+
<!-- Inline doc comments are fine. We use them all the time to describe things like $dataList->first() -->
92+
<exclude name="SlevomatCodingStandard.PHP.RequireExplicitAssertion.RequiredExplicitAssertion"/>
93+
<!-- Allow "useless" annotations -->
94+
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.UselessAnnotation"/>
95+
<!-- Allow "useless" inhreit docs -->
96+
<exclude name="SlevomatCodingStandard.Commenting.UselessInheritDocComment.UselessInheritDocComment"/>
97+
<exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.UselessAnnotation"/>
98+
<!-- We don't require arrow function -->
99+
<exclude name="SlevomatCodingStandard.Functions.RequireArrowFunction.RequiredArrowFunction"/>
100+
<!-- We don't require this -->
101+
<exclude name="SlevomatCodingStandard.Functions.StaticClosure.ClosureNotStatic"/>
102+
<exclude name="SlevomatCodingStandard.Functions.RequireSingleLineCall.RequiredSingleLineCall"/>
103+
<exclude name="SlevomatCodingStandard.Functions.StrictCall.StrictParameterMissing"/>
104+
<!-- Allows us to use $var++ and $var\-\- to incredement/decrement -->
105+
<exclude name="SlevomatCodingStandard.Operators.DisallowIncrementAndDecrementOperators" />
106+
<!-- It is acceptable within Silverstripe to pass by reference for extension hooks -->
107+
<exclude name="SlevomatCodingStandard.PHP.DisallowReference.DisallowedPassingByReference"/>
108+
<!-- Ternary shorthand is acceptable -->
109+
<exclude name="SlevomatCodingStandard.ControlStructures.DisallowShortTernaryOperator.DisallowedShortTernaryOperator"/>
110+
<exclude name="SlevomatCodingStandard.ControlStructures.RequireMultiLineTernaryOperator.MultiLineTernaryOperatorNotUsed"/>
111+
<!-- SS typically uses superfluous suffixes -->
112+
<exclude name="SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming.SuperfluousSuffix"/>
113+
<exclude name="SlevomatCodingStandard.Classes.SuperfluousExceptionNaming.SuperfluousSuffix"/>
114+
<exclude name="SlevomatCodingStandard.Classes.SuperfluousTraitNaming.SuperfluousSuffix"/>
115+
<exclude name="SlevomatCodingStandard.Classes.SuperfluousAbstractClassNaming.SuperfluousPrefix"/>
116+
<!-- Global constants and exceptions do not need to be fully qualified -->
117+
<exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedGlobalConstants.NonFullyQualified"/>
118+
<exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions.NonFullyQualifiedException"/>
119+
<!-- Don't require literal numeric seperator (EG: 1_000 to represent 1000) -->
120+
<exclude name="SlevomatCodingStandard.Numbers.RequireNumericLiteralSeparator.RequiredNumericLiteralSeparator"/>
121+
<exclude name="PSR1.Files.SideEffects.FoundWithSymbols"/>
122+
<!-- Allow use of superglobals -->
123+
<exclude name="SlevomatCodingStandard.Variables.DisallowSuperGlobalVariable.DisallowedSuperGlobalVariable"/>
124+
<!-- Don't really care about group order. We kinda do, but not enough to enforce -->
125+
<exclude name="SlevomatCodingStandard.Classes.ClassStructure.IncorrectGroupOrder"/>
126+
<!-- We do not require trailing commas on multiline methods. Both rules disabled, as we'll allow folks to -->
127+
<!-- add them if they want them, but we don't enforce either way -->
128+
<exclude name="SlevomatCodingStandard.Functions.RequireTrailingCommaInCall.MissingTrailingComma"/>
129+
<exclude name="SlevomatCodingStandard.Functions.DisallowTrailingCommaInCall.DisallowedTrailingComma"/>
130+
<exclude name="SlevomatCodingStandard.Functions.RequireTrailingCommaInDeclaration.MissingTrailingComma"/>
131+
<exclude name="SlevomatCodingStandard.Functions.DisallowTrailingCommaInDeclaration.DisallowedTrailingComma"/>
132+
<exclude name="SlevomatCodingStandard.Functions.RequireTrailingCommaInClosureUse.MissingTrailingComma"/>
133+
<exclude name="SlevomatCodingStandard.Functions.DisallowTrailingCommaInClosureUse.DisallowedTrailingComma"/>
134+
<!-- Length does not determine complexity. We do not care if methods or files are long -->
135+
<exclude name="SlevomatCodingStandard.Functions.FunctionLength.FunctionLength"/>
136+
<exclude name="SlevomatCodingStandard.Files.FunctionLength.FunctionLength"/>
137+
<!-- Don't force our projects to use getters/setters for any/all properties -->
138+
<exclude name="SlevomatCodingStandard.Classes.ForbiddenPublicProperty.ForbiddenPublicProperty"/>
139+
<!-- We can't declare classes as abstract/final because we have plenty of instances where classes are both -->
140+
<!-- used themselves, and also extended (EG: almost all of our DataObjects) -->
141+
<exclude name="SlevomatCodingStandard.Classes.RequireAbstractOrFinal.ClassNeitherAbstractNorFinal"/>
142+
<!-- There are two conflicting rules. We have to pick one. We've opted to *allow* Catches that do not use -->
143+
<!-- the Exception that was thrown (EG: We might be returning some other message) -->
144+
<exclude name="SlevomatCodingStandard.Exceptions.DisallowNonCapturingCatch.DisallowedNonCapturingCatch"/>
145+
<!-- We pass variables by reference all the time, especially as part of modules and extension points-->
146+
<exclude name="SlevomatCodingStandard.PHP.DisallowReference.DisallowedInheritingVariableByReference"/>
147+
<!-- We need to decide if we're specifically going to allow (and enforce) null safe object operators or not -->
148+
<!-- We've opted to enforce them -->
149+
<exclude name="SlevomatCodingStandard.ControlStructures.DisallowNullSafeObjectOperator.DisallowedNullSafeObjectOperator"/>
150+
<!-- Teams have mixed preferences around whether to enforce property promotion or not. Both rules disabled -->
151+
<!-- by default, and each team/project can decide for themselves how they wish to handle them -->
152+
<exclude name="SlevomatCodingStandard.Classes.RequireConstructorPropertyPromotion.RequiredConstructorPropertyPromotion"/>
153+
<exclude name="SlevomatCodingStandard.Classes.DisallowConstructorPropertyPromotion.DisallowedConstructorPropertyPromotion"/>
154+
</rule>
155+
156+
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses">
157+
<properties>
158+
<property name="searchAnnotations" type="bool" value="true"/>
159+
<property name="ignoredAnnotationNames" type="array" value="@config"/>
160+
</properties>
161+
</rule>
162+
163+
<rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
164+
<properties>
165+
<!-- Set the root namespace for our src dir and phpunit dir. Please change these as required -->
166+
<property name="rootNamespaces" type="array" value="src=>Terraformers\EmbargoExpiry,tests=>Terraformers\EmbargoExpiry\Tests"/>
167+
<property name="ignoredNamespaces" type="array" value="Slevomat\Services"/>
168+
</properties>
169+
</rule>
170+
171+
<rule ref="SlevomatCodingStandard.ControlStructures.JumpStatementsSpacing">
172+
<properties>
173+
<property name="linesCountBeforeWhenFirstInCaseOrDefault" value="0"/>
174+
<property name="linesCountAfterWhenLastInCaseOrDefault" value="1"/>
175+
<property name="linesCountAfterWhenLastInLastCaseOrDefault" value="0"/>
176+
</properties>
177+
</rule>
39178
</ruleset>

phpunit.xml.dist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true">
22
<testsuite name="Default">
3-
<directory>tests/php/</directory>
3+
<directory>tests/</directory>
44
</testsuite>
55
<filter>
6-
<whitelist addUncoveredFilesFromWhitelist="true">
6+
<whitelist processUncoveredFilesFromWhitelist="true">
77
<directory suffix=".php">src/</directory>
88
<exclude>
99
<directory suffix=".php">tests/</directory>

0 commit comments

Comments
 (0)