Skip to content

Commit 8de999d

Browse files
committed
initial commit
0 parents  commit 8de999d

File tree

13 files changed

+444
-0
lines changed

13 files changed

+444
-0
lines changed

.eslintrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "./vendor/space48/code-quality/rulesets/.eslintrc"
3+
}

.gitignore

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# These are some examples of commonly ignored file patterns.
2+
# You should customize this list as applicable to your project.
3+
# Learn more about .gitignore:
4+
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore
5+
6+
# Node artifact files
7+
node_modules/
8+
dist/
9+
10+
# Compiled Java class files
11+
*.class
12+
13+
# Compiled Python bytecode
14+
*.py[cod]
15+
16+
# Log files
17+
*.log
18+
19+
# Package files
20+
*.jar
21+
22+
# Maven
23+
target/
24+
dist/
25+
26+
# JetBrains IDE
27+
.idea/
28+
29+
# Unit test reports
30+
TEST*.xml
31+
32+
# Generated by MacOS
33+
.DS_Store
34+
35+
# Generated by Windows
36+
Thumbs.db
37+
38+
# Applications
39+
*.app
40+
*.exe
41+
*.war
42+
43+
# Large media files
44+
*.mp4
45+
*.tiff
46+
*.avi
47+
*.flv
48+
*.mov
49+
*.wmv
50+

README.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Space48 Code Quality tool
2+
3+
A module that helps to easily apply static code analysers to the project`s code.
4+
It uses [grumphp](https://github.com/phpro/grumphp) under the hood and has predefined set of rules
5+
based on Magento 2 coding standards and tuned to be less annoying.
6+
7+
## Usage
8+
After pulling and installing a project locally just run following command to update local git hooks
9+
and install npm packages inside Docker container:
10+
```shell
11+
make linters-install
12+
```
13+
Now on pre-commit either from console or from phpstorm a linter will run against committed code
14+
15+
To run precommit manually:
16+
```shell
17+
make precommit
18+
```
19+
To run linters as it would run on CI (from starting commit till HEAD):
20+
```shell
21+
make analyse
22+
```
23+
24+
## Installation
25+
26+
Add Code Quality tool to the Magento Project:
27+
28+
### Installation on a regular _Space48 Warden based Magento 2_ project:
29+
30+
#### 1. Run following commands from project root:
31+
```
32+
warden env exec php-fpm composer require --dev space48/code-quality:@dev
33+
warden env exec php-fpm chmod +x ./vendor/space48/code-quality/script/install.sh
34+
warden env exec ./vendor/space48/code-quality/script/install.sh
35+
vendor/bin/grumphp git:init
36+
git add ruleset.xml phpmd.xml .eslintrc grumphp.yml
37+
```
38+
39+
#### 2. Add following to project`s 'Makefile':
40+
```makefile
41+
linters-install: # installs Space48 Code Quality
42+
warden env exec php-fpm chmod +x ./vendor/space48/code-quality/script/install.sh
43+
warden env exec php-fpm ./vendor/space48/code-quality/script/install.sh
44+
vendor/bin/grumphp git:init
45+
46+
analyse: # analyses all code from starting commit hash to HEAD
47+
git diff e111c999..HEAD | warden env run --rm php-fpm 'vendor/phpro/grumphp/bin/grumphp' run
48+
49+
precommit: # analyses code staged for commit
50+
git diff --staged | warden env run --rm php-fpm 'vendor/phpro/grumphp/bin/grumphp' run
51+
```
52+
53+
Replace the sample `e111c999` commit hash with the hash from the project where you want to start linting from.
54+
Files modified after the starting commit hash will be linted during project build and will fail the build on linter violations.
55+
56+
#### 3. Commit to project`s repo.
57+
Commit updated composer files, vendor folder, code-quality config files from the root and 'makefile' changes
58+
59+
### Installation on any other Magento 2 project:
60+
1. add module `space48/code-quality` via Composer
61+
2. run `vendor/space48/code-quality/script/install.sh` script to copy necessary files
62+
3. run `vendor/bin/grumphp git:init` to update precommit hooks
63+
64+
## Configuration
65+
66+
Whitelist/exclude folders can be configured at `{project_root}/grumphp.yml`:
67+
```yaml
68+
phpmd:
69+
whitelist_patterns:
70+
- /^app/
71+
triggered_by: [ 'php', 'phtml' ]
72+
exclude: [ ]
73+
phpcs:
74+
whitelist_patterns:
75+
- /^app/
76+
triggered_by: [ 'php', 'phtml' ]
77+
ignore_patterns: [ ]
78+
eslint:
79+
triggered_by: [ js, jsx, ts, tsx, vue ]
80+
whitelist_patterns: [ /^app/ ]
81+
```
82+
To turn off whole linter type (for example 'eslint') - remove or comment out corresponding 'task' section.
83+
84+
Linter rules can be finetuned on a project level by editing `ruleset.xml, phpmd.xml, .eslintrc` files.
85+
See `Space48/code-quality/rulesets/` for examples.
86+
87+
## More info
88+
For more info and for Configuration help refer to [grumphp repo](https://github.com/phpro/grumphp) docs.

composer.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"name": "space48/code-quality",
3+
"version": "1.0",
4+
"type": "codesniffer-standard",
5+
"description": "Provides rulesets for phpmd, phpcs and eslint that overrides some Magento sniffs and provides some new ones as well",
6+
"license": "proprietary",
7+
"minimum-stability": "dev",
8+
"require": {
9+
"phpro/grumphp": "^1.3",
10+
"magento/magento-coding-standard": "*",
11+
"phpmd/phpmd": "^2",
12+
"squizlabs/php_codesniffer": ">=2.9.2 <4.0.0"
13+
},
14+
"require-dev": {
15+
},
16+
"config": {
17+
"platform": {
18+
"php": "7.0.33"
19+
}
20+
},
21+
"authors": [
22+
{
23+
"name": "Stepan Kechedzhi",
24+
"email": "[email protected]"
25+
}
26+
],
27+
"keywords": [
28+
"standards"
29+
],
30+
"autoload": {
31+
"psr-4": {
32+
"Space48\\CodeQuality\\": "src",
33+
"Space48\\CodeQuality\\RuleSets\\": "rulesets",
34+
"PHP_CodeSniffer\\": "../../squizlabs/php_codesniffer/src",
35+
"Magento\\": "../magento-coding-standard/Magento",
36+
"EcgM2\\": "../../magento-ecg/coding-standard/EcgM2",
37+
"Ecg\\": "../../magento-ecg/coding-standard/Ecg"
38+
}
39+
},
40+
"autoload-dev": {
41+
"psr-4": {
42+
"PHP_CodeSniffer\\": "vendor/squizlabs/php_codesniffer/src",
43+
"Magento\\": "vendor/magento/magento-coding-standard/Magento",
44+
"EcgM2\\": "vendor/magento-ecg/coding-standard/EcgM2",
45+
"Ecg\\": "vendor/magento-ecg/coding-standard/Ecg"
46+
}
47+
},
48+
"repositories": [
49+
{
50+
"type": "composer",
51+
"url": "https://repo.magento.com/"
52+
},
53+
{
54+
"type": "composer",
55+
"url": "https://packagist.org/"
56+
}
57+
]
58+
}

grumphp.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
grumphp:
2+
git_hook_variables:
3+
EXEC_GRUMPHP_COMMAND: 'warden env run --rm php-fpm'
4+
ignore_unstaged_changes: false
5+
tasks:
6+
phpmd:
7+
whitelist_patterns:
8+
- /^app/
9+
triggered_by: [ 'php', 'phtml' ]
10+
exclude: [ ]
11+
report_format: ansi
12+
ruleset: [ 'phpmd.xml' ]
13+
phpcs:
14+
standard: [ 'ruleset.xml' ]
15+
severity: ~
16+
error_severity: ~
17+
warning_severity: ~
18+
tab_width: ~
19+
report: full
20+
report_width: ~
21+
whitelist_patterns:
22+
- /^app/
23+
triggered_by: [ 'php', 'phtml' ]
24+
encoding: ~
25+
ignore_patterns: [ ]
26+
sniffs: [ ]
27+
exclude: [ ]
28+
eslint:
29+
bin: node_modules/.bin/eslint
30+
triggered_by: [ js, jsx, ts, tsx, vue ]
31+
whitelist_patterns: [ /^app/ ]
32+
config: .eslintrc
33+
debug: false
34+
format: ~
35+
max_warnings: ~
36+
no_eslintrc: false
37+
quiet: false

phpmd.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0"?>
2+
3+
<ruleset name="Space48 Coding Standard Project Specific">
4+
<rule ref="vendor/space48/code-quality/rulesets/phpmd.xml" >
5+
</rule>
6+
7+
</ruleset>

ruleset.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0"?>
2+
3+
<ruleset name="Space48 Coding Standard Project Specific">
4+
<rule ref="vendor/space48/code-quality/rulesets/ruleset.xml">
5+
</rule>
6+
7+
</ruleset>

rulesets/.eslintrc

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"rules": {
3+
"indent": ["error", 4],
4+
"semi": [2, "always"],
5+
"one-var": ["error", { "var": "consecutive" }],
6+
"yoda": ["error", "never"],
7+
"no-tabs": "error",
8+
"camelcase": "error",
9+
"max-len": ["error", { "code": 120, "comments": 150 }],
10+
"max-lines": ["error", {"max": 250, "skipComments": true}],
11+
"complexity": ["error", { "max": 12 }],
12+
"no-undef": "off",
13+
"padded-blocks": "off",
14+
"guard-for-in": "off",
15+
// VCQ1
16+
"no-mixed-operators": [
17+
"error",
18+
{
19+
"groups": [
20+
["==", "!=", "===", "!==", ">", ">=", "<", "<="],
21+
["in", "instanceof"]
22+
],
23+
"allowSamePrecedence": true
24+
}
25+
],
26+
// VCQ2
27+
"id-length": [
28+
"error",
29+
{
30+
"min": 3,
31+
"max": 30,
32+
"exceptions": ["x", "i", "j", "e", "$", "_", "__", "ko"],
33+
"properties": "never"
34+
}
35+
],
36+
// VCQ3
37+
"valid-jsdoc": ["error", {
38+
"preferType": {
39+
},
40+
"requireReturn": false,
41+
"requireReturnDescription": false,
42+
"requireParamDescription": false
43+
}],
44+
"eqeqeq": "warn",
45+
"no-unneeded-ternary": "off"
46+
}
47+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace Space48\CodeQuality\RuleSets\PhpMd\Design;
4+
5+
use PHPMD\AbstractNode;
6+
use PHPMD\AbstractRule;
7+
use PHPMD\Rule\FunctionAware;
8+
use PHPMD\Rule\MethodAware;
9+
10+
/**
11+
* Extends LongParameterList class with different threshold for constructor.
12+
*/
13+
class LongParameterList extends AbstractRule implements FunctionAware, MethodAware
14+
{
15+
/**
16+
* Checks the number of arguments for the given function or method node against a configured threshold.
17+
*
18+
* @param \PHPMD\AbstractNode $node
19+
* @return void
20+
*/
21+
public function apply(AbstractNode $node)
22+
{
23+
$threshold = $this->getIntProperty('minimum');
24+
25+
if ($node->getName() === '__construct') {
26+
$threshold = $this->getIntProperty('constructor_minimum');
27+
}
28+
29+
$count = $node->getParameterCount();
30+
31+
if ($count > $threshold) {
32+
$this->addViolation(
33+
$node,
34+
[
35+
$node->getType(),
36+
$node->getName(),
37+
$count,
38+
$threshold,
39+
]
40+
);
41+
}
42+
}
43+
}

rulesets/PhpMd/extra.xml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?xml version="1.0"?>
2+
3+
<ruleset name="Space48 Coding Standard Extra"
4+
xmlns="http://pmd.sf.net/ruleset/1.0.0"
5+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6+
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
7+
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
8+
9+
<rule name="ExcessiveParameterList"
10+
since="0.1"
11+
message="The {0} {1} has {2} parameters. Consider reducing the number of parameters to less than {3}."
12+
class="Space48\CodeQuality\RuleSets\PhpMd\Design\LongParameterList"
13+
externalInfoUrl="http://phpmd.org/rules/codesize.html#excessiveparameterlist">
14+
<description>
15+
Long parameter lists can indicate that a new object should be created to
16+
wrap the numerous parameters. Basically, try to group the parameters together.
17+
</description>
18+
<priority>3</priority>
19+
<properties>
20+
<property name="minimum" description="The parameter count reporting threshold" value="5"/>
21+
<property name="constructor_minimum" description="reporting threshold for '__construct()'" value="13"/>
22+
</properties>
23+
<example>
24+
<![CDATA[
25+
class Foo {
26+
public function addData(
27+
$p0, $p1, $p2, $p3, $p4, $p5,
28+
$p5, $p6, $p7, $p8, $p9, $p10) {
29+
}
30+
}
31+
]]>
32+
</example>
33+
34+
</rule>
35+
</ruleset>

0 commit comments

Comments
 (0)