Skip to content

Commit b267a73

Browse files
committed
Initial commit
0 parents  commit b267a73

27 files changed

+1600
-0
lines changed

.gitattributes

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/src/Readme/ export-ignore
2+
/tests/ export-ignore
3+
/.gitattributes export-ignore
4+
/.gitignore export-ignore
5+
/.travis.yml export-ignore

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/vendor/
2+
/composer.lock

.travis.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
git:
2+
depth: 1
3+
4+
cache:
5+
directories:
6+
- $HOME/.composer/cache
7+
8+
sudo: false
9+
10+
language: php
11+
12+
notifications:
13+
email: false
14+
15+
before_install:
16+
- composer self-update --stable
17+
18+
matrix:
19+
include:
20+
- php: '7.1'
21+
install: composer update --prefer-lowest
22+
- php: '7.1'
23+
- php: '7.2'
24+
25+
install:
26+
- composer install
27+
28+
script:
29+
- vendor/bin/phpcs --report-full --standard=PSR2 src tests
30+
- vendor/bin/php-cs-fixer fix --config=tests/php-cs-fixer.config.php --diff --dry-run
31+
- vendor/bin/types-checker src tests
32+
- vendor/bin/psalm --config=tests/psalm.xml
33+
- phpdbg -qrr vendor/bin/phpunit --configuration=tests

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 Kuba Werłos
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# PHP CS Fixer: custom fixers
2+
3+
[![Latest Stable Version](https://img.shields.io/packagist/v/kubawerlos/php-cs-fixer-custom-fixers.svg)](https://packagist.org/packages/kubawerlos/php-cs-fixer-custom-fixers)
4+
[![PHP Version](https://img.shields.io/badge/php-%5E7.1-8892BF.svg)](https://php.net)
5+
[![License](https://img.shields.io/github/license/kubawerlos/php-cs-fixer-custom-fixers.svg)](https://packagist.org/packages/kubawerlos/php-cs-fixer-custom-fixers)
6+
[![Build Status](https://img.shields.io/travis/kubawerlos/php-cs-fixer-custom-fixers/master.svg)](https://travis-ci.org/kubawerlos/php-cs-fixer-custom-fixers)
7+
8+
A set of custom fixers for [PHP CS Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer).
9+
10+
## Installation
11+
PHP CS Fixer custom fixers can be installed by running:
12+
```bash
13+
composer require --dev kubawerlos/php-cs-fixer-custom-fixers
14+
```
15+
16+
17+
## Usage
18+
In your PHP CS Fixer configuration register fixers and use them:
19+
```diff
20+
<?php
21+
22+
return PhpCsFixer\Config::create()
23+
+ ->registerCustomFixers(new PhpCsFixerCustomFixers\Fixers())
24+
->setRules([
25+
'@PSR2' => true,
26+
'array_syntax' => ['syntax' => 'short'],
27+
+ PhpCsFixerCustomFixers\Fixer\NoLeadingSlashInGlobalNamespaceFixer::name() => true,
28+
+ PhpCsFixerCustomFixers\Fixer\NoTwoConsecutiveEmptyLinesFixer::name() => true,
29+
]);
30+
31+
```
32+
33+
34+
## Fixers
35+
- **NoLeadingSlashInGlobalNamespaceFixer** - when in global namespace there should be no leading slash for class.
36+
```diff
37+
<?php
38+
-$x = new \Foo();
39+
+$x = new Foo();
40+
namespace Bar;
41+
$y = new \Baz();
42+
43+
```
44+
45+
- **NoPhpStormGeneratedCommentFixer** - there should be no comment generated by PhpStorm.
46+
```diff
47+
<?php
48+
-/**
49+
- * Created by PhpStorm.
50+
- * User: root
51+
- * Date: 01.01.70
52+
- * Time: 12:00
53+
- */
54+
namespace Foo;
55+
56+
```
57+
58+
- **NoTwoConsecutiveEmptyLinesFixer** - there should be no two consecutive empty lines in code.
59+
```diff
60+
<?php
61+
namespace Foo;
62+
63+
-
64+
class Foo {};
65+
66+
```
67+
68+
- **NoUselessClassCommentFixer** - there should be no comment like: "Class Foo\Bar".
69+
```diff
70+
<?php
71+
/**
72+
- * Class Foo\Bar
73+
* Class to do something
74+
*/
75+
76+
```
77+
78+
79+
## Contributing
80+
Request a feature or report a bug by creating [issue](https://github.com/kubawerlos/php-cs-fixer-custom-fixers/issues).
81+
82+
Alternatively, fork the repo, develop your changes, regenerate `README.md`:
83+
```bash
84+
src/Readme/run > README.md
85+
```
86+
make sure all checks pass:
87+
```bash
88+
vendor/bin/phpcs --report-full --standard=PSR2 src tests
89+
vendor/bin/php-cs-fixer fix --config=tests/php-cs-fixer.config.php --diff --dry-run
90+
vendor/bin/types-checker src tests
91+
vendor/bin/psalm --config=tests/psalm.xml
92+
phpdbg -qrr vendor/bin/phpunit --configuration=tests
93+
```
94+
and submit a pull request.

composer.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "kubawerlos/php-cs-fixer-custom-fixers",
3+
"description": "A set of custom fixers for PHP CS Fixer",
4+
"type": "library",
5+
"keywords": [
6+
"fixer",
7+
"php-cs-fixer"
8+
],
9+
"license": "MIT",
10+
"authors": [
11+
{
12+
"name": "Kuba Werłos",
13+
"email": "[email protected]"
14+
}
15+
],
16+
"require": {
17+
"php": "^7.1",
18+
"ext-json": "*",
19+
"ext-tokenizer": "*",
20+
"friendsofphp/php-cs-fixer": "^2.11"
21+
},
22+
"require-dev": {
23+
"kubawerlos/types-checker": "^1.1",
24+
"phpunit/phpunit": "^7.1",
25+
"sebastian/diff": "^3.0",
26+
"squizlabs/php_codesniffer": "^3.2",
27+
"symfony/console": "^4.0",
28+
"symfony/finder": "^4.0",
29+
"symfony/yaml": "^4.0",
30+
"vimeo/psalm": "^2.0"
31+
},
32+
"autoload": {
33+
"psr-4": {
34+
"PhpCsFixerCustomFixers\\": "src/"
35+
}
36+
},
37+
"autoload-dev": {
38+
"psr-4": {
39+
"Tests\\": "tests/"
40+
}
41+
}
42+
}

src/Fixer/AbstractFixer.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace PhpCsFixerCustomFixers\Fixer;
6+
7+
use PhpCsFixer\Fixer\DefinedFixerInterface;
8+
9+
abstract class AbstractFixer implements DefinedFixerInterface
10+
{
11+
final public static function name() : string
12+
{
13+
return 'PhpCsFixerCustomFixers/' . \preg_replace_callback(
14+
'/(^|[a-z0-9])([A-Z])/',
15+
static function (array $matches) : string {
16+
return \strtolower($matches[1] !== '' ? $matches[1] . '_' . $matches[2] : $matches[2]);
17+
},
18+
\preg_replace('/^.*\\\\([a-zA-Z0-1]+)Fixer$/', '$1', static::class)
19+
);
20+
}
21+
22+
final public function getName() : string
23+
{
24+
return self::name();
25+
}
26+
27+
final public function isRisky() : bool
28+
{
29+
return false;
30+
}
31+
32+
final public function supports(\SplFileInfo $file) : bool
33+
{
34+
return true;
35+
}
36+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace PhpCsFixerCustomFixers\Fixer;
6+
7+
use PhpCsFixer\FixerDefinition\CodeSample;
8+
use PhpCsFixer\FixerDefinition\FixerDefinition;
9+
use PhpCsFixer\Tokenizer\Tokens;
10+
11+
final class NoLeadingSlashInGlobalNamespaceFixer extends AbstractFixer
12+
{
13+
public function getDefinition() : FixerDefinition
14+
{
15+
return new FixerDefinition(
16+
'When in global namespace there should be no leading slash for class.',
17+
[new CodeSample('<?php
18+
$x = new \Foo();
19+
namespace Bar;
20+
$y = new \Baz();
21+
')]
22+
);
23+
}
24+
25+
public function isCandidate(Tokens $tokens) : bool
26+
{
27+
return $tokens->isTokenKindFound(T_NS_SEPARATOR);
28+
}
29+
30+
public function fix(\SplFileInfo $file, Tokens $tokens) : void
31+
{
32+
foreach ($tokens as $index => $token) {
33+
if ($token->isGivenKind(T_NAMESPACE)) {
34+
return;
35+
}
36+
37+
if (!$token->isGivenKind(T_NS_SEPARATOR)) {
38+
continue;
39+
}
40+
41+
$prevIndex = $tokens->getPrevMeaningfulToken($index);
42+
if ($tokens[$prevIndex]->isGivenKind(T_STRING)) {
43+
continue;
44+
}
45+
46+
$tokens->clearTokenAndMergeSurroundingWhitespace($index);
47+
}
48+
}
49+
50+
public function getPriority() : int
51+
{
52+
// must be run before PhpdocToCommentFixer
53+
return 26;
54+
}
55+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace PhpCsFixerCustomFixers\Fixer;
6+
7+
use PhpCsFixer\FixerDefinition\CodeSample;
8+
use PhpCsFixer\FixerDefinition\FixerDefinition;
9+
use PhpCsFixer\Tokenizer\Token;
10+
use PhpCsFixer\Tokenizer\Tokens;
11+
12+
final class NoPhpStormGeneratedCommentFixer extends AbstractFixer
13+
{
14+
public function getDefinition() : FixerDefinition
15+
{
16+
return new FixerDefinition(
17+
'There should be no comment generated by PhpStorm.',
18+
[new CodeSample('<?php
19+
/**
20+
* Created by PhpStorm.
21+
* User: root
22+
* Date: 01.01.70
23+
* Time: 12:00
24+
*/
25+
namespace Foo;
26+
')]
27+
);
28+
}
29+
30+
public function isCandidate(Tokens $tokens) : bool
31+
{
32+
return $tokens->isAnyTokenKindsFound([T_COMMENT, T_DOC_COMMENT]);
33+
}
34+
35+
public function fix(\SplFileInfo $file, Tokens $tokens) : void
36+
{
37+
foreach ($tokens as $index => $token) {
38+
if (!$tokens[$index]->isGivenKind([T_COMMENT, T_DOC_COMMENT])) {
39+
continue;
40+
}
41+
42+
if (\preg_match('/\*\h+Created by PhpStorm/i', $token->getContent(), $matches) !== 1) {
43+
continue;
44+
}
45+
46+
$this->removeTrailingHorizontalWhitespaces($tokens, $index - 1);
47+
48+
$this->removeLeadingNewline($tokens, $index + 1);
49+
50+
$tokens->clearTokenAndMergeSurroundingWhitespace($index);
51+
}
52+
}
53+
54+
public function getPriority() : int
55+
{
56+
return 0;
57+
}
58+
59+
private function removeTrailingHorizontalWhitespaces(Tokens $tokens, int $index) : void
60+
{
61+
if (!$tokens[$index]->isGivenKind(T_WHITESPACE)) {
62+
return;
63+
}
64+
65+
$newContent = \preg_replace('/\h+$/', '', $tokens[$index]->getContent());
66+
67+
if (empty($newContent)) {
68+
$tokens->clearAt($index);
69+
70+
return;
71+
}
72+
73+
if ($newContent === $tokens[$index]->getContent()) {
74+
return;
75+
}
76+
77+
$tokens[$index] = new Token([T_WHITESPACE, $newContent]);
78+
}
79+
80+
private function removeLeadingNewline(Tokens $tokens, int $index) : void
81+
{
82+
if (!$tokens[$index]->isGivenKind(T_WHITESPACE)) {
83+
return;
84+
}
85+
86+
$newContent = \preg_replace('/^\h*\R/', '', $tokens[$index]->getContent());
87+
88+
if ($newContent === $tokens[$index]->getContent()) {
89+
return;
90+
}
91+
92+
if (empty($newContent)) {
93+
$tokens->clearAt($index);
94+
95+
return;
96+
}
97+
98+
$tokens[$index] = new Token([T_WHITESPACE, $newContent]);
99+
}
100+
}

0 commit comments

Comments
 (0)