diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml new file mode 100644 index 0000000..8c874b7 --- /dev/null +++ b/.github/workflows/coding-standards.yml @@ -0,0 +1,44 @@ +name: Coding Standards + +on: + workflow_call: + inputs: + php-version: + description: "The PHP version to use when running the job" + default: "8.1" + required: false + type: "string" + composer-options: + description: "Additional flags for the composer install command." + default: "--prefer-dist" + required: false + type: "string" + +jobs: + coding-standards: + name: Coding Standards + runs-on: ubuntu-latest + + strategy: + matrix: + php-version: + - "${{ inputs.php-version }}" + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + + - name: Install composer dependencies + uses: "ramsey/composer-install@v2" + with: + working-directory: "tools/ecs" + composer-options: "${{ inputs.composer-options }}" + + - name: Run ECS + run: tools/ecs/vendor/bin/ecs check --config tools/ecs/ecs.php diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..c006edb --- /dev/null +++ b/composer.json @@ -0,0 +1,29 @@ +{ + "name": "brick/coding-standards", + "description": "Coding standards tools and configurations used in Brick organization.", + "type": "library", + "keywords": [ + "brick", + "coding", + "standard", + "cs", + "code", + "style", + "sniffer", + "rules", + "sniffs", + "checks" + ], + "license": "MIT", + "require": { + "symplify/easy-coding-standard": "^10.3", + "slevomat/coding-standard": "^7.2", + "squizlabs/php_codesniffer": "^3.7" + }, + "config": { + "sort-packages": true, + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + } +} diff --git a/ecs.php b/ecs.php new file mode 100644 index 0000000..7e4dcae --- /dev/null +++ b/ecs.php @@ -0,0 +1,228 @@ +indentation('spaces'); + + $ecsConfig->sets([ + SetList::PSR_12, + ]); + + $ecsConfig->rules( + [ + NoUnusedImportsFixer::class, + BlankLineBeforeStatementFixer::class, + CastSpacesFixer::class, + CommentToPhpdocFixer::class, + DeclareStrictTypesFixer::class, + FunctionTypehintSpaceFixer::class, + LinebreakAfterOpeningTagFixer::class, + LowercaseStaticReferenceFixer::class, + LowercaseCastFixer::class, + MethodChainingIndentationFixer::class, + NativeFunctionCasingFixer::class, + NativeConstantInvocationFixer::class, + NewWithBracesFixer::class, + ModernizeTypesCastingFixer::class, + NoEmptyStatementFixer::class, + NoExtraBlankLinesFixer::class, + NoMultilineWhitespaceAroundDoubleArrowFixer::class, + NoSinglelineWhitespaceBeforeSemicolonsFixer::class, + ObjectOperatorWithoutWhitespaceFixer::class, + PhpUnitDedicateAssertFixer::class, + PhpUnitDedicateAssertInternalTypeFixer::class, + PhpUnitExpectationFixer::class, + NotOperatorWithSuccessorSpaceFixer::class, + PhpUnitStrictFixer::class, + PhpdocAddMissingParamAnnotationFixer::class, + PhpdocToParamTypeFixer::class, + PhpdocToPropertyTypeFixer::class, + PhpdocToReturnTypeFixer::class, + PhpdocAlignFixer::class, + NoEmptyPhpdocFixer::class, + PhpdocIndentFixer::class, + TrimArraySpacesFixer::class, + PhpdocNoEmptyReturnFixer::class, + StandardizeIncrementFixer::class, + IncludeFixer::class, + PhpdocNoUselessInheritdocFixer::class, + NoUnneededControlParenthesesFixer::class, + NoLeadingImportSlashFixer::class, + PhpdocOrderByValueFixer::class, + PhpdocReturnSelfReferenceFixer::class, + PhpdocScalarFixer::class, + PhpdocSeparationFixer::class, + PhpdocSingleLineVarSpacingFixer::class, + PhpdocTagCasingFixer::class, + PhpdocSummaryFixer::class, + PhpdocTrimFixer::class, + PhpdocTypesFixer::class, + PhpdocVarAnnotationCorrectOrderFixer::class, + BinaryOperatorSpacesFixer::class, + SingleQuoteFixer::class, + SemicolonAfterInstructionFixer::class, + ReturnTypeDeclarationFixer::class, + ShortScalarCastFixer::class, + SingleBlankLineBeforeNamespaceFixer::class, + SingleLineCommentStyleFixer::class, + PsrAutoloadingFixer::class, + SpaceAfterSemicolonFixer::class, + NoWhitespaceInBlankLineFixer::class, + StrictComparisonFixer::class, + TernaryOperatorSpacesFixer::class, + TernaryToNullCoalescingFixer::class, + VoidReturnFixer::class, + UnaryOperatorSpacesFixer::class, + WhitespaceAfterCommaInArrayFixer::class, + NoTrailingCommaInSinglelineArrayFixer::class, + TrailingCommaInMultilineFixer::class, + ] + ); + + $ecsConfig->ruleWithConfiguration(ListSyntaxFixer::class, ['syntax' => 'short']); + $ecsConfig->ruleWithConfiguration(MethodArgumentSpaceFixer::class, ['on_multiline' => 'ensure_fully_multiline']); + $ecsConfig->ruleWithConfiguration(OrderedClassElementsFixer::class, ['order' => ['use_trait', 'case', 'constant_public', 'constant_protected', 'constant_private', 'property_public', 'property_protected', 'property_private', 'construct', 'phpunit', 'method_public', 'magic', 'method_protected', 'method_private', 'destruct']]); + $ecsConfig->ruleWithConfiguration(ArraySyntaxFixer::class, ['syntax' => 'short']); + $ecsConfig->ruleWithConfiguration(PhpUnitTestCaseStaticMethodCallsFixer::class, ['call_type' => 'this']); + $ecsConfig->ruleWithConfiguration(PhpdocTypesOrderFixer::class, ['null_adjustment' => 'always_last']); + $ecsConfig->ruleWithConfiguration(NoSuperfluousPhpdocTagsFixer::class, ['allow_mixed' => true]); + $ecsConfig->ruleWithConfiguration(ClassAttributesSeparationFixer::class, ['elements' => ['method' => 'one', 'property' => 'one']]); + + // PHPCS + $ecsConfig->rules( + [ + FunctionCommentSniff::class, + ] + ); + + $ecsConfig->ruleWithConfiguration( + DocCommentSpacingSniff::class, + [ + 'linesCountBetweenAnnotationsGroups' => 1, + 'annotationsGroups' => [ + '@todo', + '@internal,@deprecated', + '@link,@see,@uses', + '@dataProvider', + '@param', + '@return', + '@throws', + ], + ] + ); + + $ecsConfig->ruleWithConfiguration( + ReferenceUsedNamesOnlySniff::class, + [ + 'allowFallbackGlobalConstants' => false, + 'allowFallbackGlobalFunctions' => false, + 'allowFullyQualifiedGlobalClasses' => false, + 'allowFullyQualifiedGlobalConstants' => false, + 'allowFullyQualifiedGlobalFunctions' => false, + 'allowFullyQualifiedNameForCollidingClasses' => true, + 'allowFullyQualifiedNameForCollidingConstants' => true, + 'allowFullyQualifiedNameForCollidingFunctions' => true, + 'searchAnnotations' => true, + ] + ); + + $ecsConfig->ruleWithConfiguration( + UseSpacingSniff::class, + [ + 'linesCountAfterLastUse' => 0, + 'linesCountBetweenUseTypes' => 1, + 'linesCountBeforeFirstUse' => 0, + ] + ); + + $ecsConfig->ruleWithConfiguration( + DuplicateSpacesSniff::class, + [ + 'ignoreSpacesInAnnotation' => 1, + ] + ); +};