Fork of git://github.com/easybib/coding-standard.git

revision 1802754b05c6a6206c71fbc0871ed4543880c1e9

raw

.gitignore

No idea how to display this file
raw

EasyBib/Sniffs/Commenting/ReturnStatementsSniff.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?php
namespace EasyBib\Sniffs\Commenting;
 
class ReturnStatementsSniff implements \PHP_CodeSniffer_Sniff
{
    /**
     * @var \PHP_CodeSniffer_File
     */
    protected $phpcsFile;
 
    /**
     * @var array
     */
    protected $tokens;
 
    public function register()
    {
        return array(T_FUNCTION);
    }
 
    public function process(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $this->phpcsFile = $phpcsFile;
 
        $methodName = $this->phpcsFile->getDeclarationName($stackPtr);
        if (null === $methodName) {
            return;
        }
 
        $this->tokens = $phpcsFile->getTokens();
 
        // enforce no `@return void` on __construct
        if ('__construct' === $methodName) {
            $this->findReturnVoid($stackPtr, true);
            return;
        }
    }
 
    /**
     * @param int  $stackPtr Position in the stack.
     * @param bool $ctor     Is this a __construct.
     *
     * @return void
     */
    protected function findReturnVoid($stackPtr, $ctor = false)
    {
        $toFind     = array(T_DOC_COMMENT,);
        $commentEnd = $this->phpcsFile->findPrevious(T_DOC_COMMENT, ($stackPtr-1));
        if (false === $commentEnd) {
            return; // no docblock, different concern
        }
 
        $look = $commentEnd-1;
        while (true && ($look > 0)) {
            $docComment = $this->phpcsFile->findPrevious(T_DOC_COMMENT, ($look));
            if (false === $docComment) {
                return;
            }
            $docRow  = $this->tokens[$docComment];
            $content = trim($docRow['content']);
            if (strstr($content, '@return void')) {
                if (true === $ctor) {
                   $this->phpcsFile->addError('`@return void` for __construct is invalid.', $docComment, 'ConstructNoReturnVoid');
                } else {
                    $this->phpcsFile->addWarning('Consider adding a fluent interface instead of `@return void`', $docComment, 'AddSetReturnsVoid');
                }
                return;
            }
            if ('/**' == $content) {
                return;
            }
            --$look;
        }
        return;
    }
}
 
raw

EasyBib/Sniffs/Methods/AddSetShouldBeFluentSniff.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?php
/**
 * EasyBib\Sniffs\Methods\AddSetShouldBeFluentSniff
 *
 * PHP version 5.3
 *
 * @category QA
 * @package  EasyBib\Sniffs
 * @author   Till Klampaeckel <till@php.net>
 * @license  http://opensource.org/licenses/bsd-license.php New BSD License
 * @version  GIT: <git_id>
 * @link     http://
 */
 
namespace EasyBib\Sniffs\Methods;
 
/**
 * EasyBib\Sniffs\Methods\AddSetShouldBeFluentSniff
 *
 * Ensures that there are no `return` statements in a `__construct` and that the docblock
 * says `return $this` - if anything.
 *
 * @category  QA
 * @package   EasyBib\Sniffs
 * @author    Till Klampaeckel <till@php.net>
 * @license   http://opensource.org/licenses/bsd-license.php New BSD License
 * @version   Release: @package_version@
 * @link      http://
 */
class AddSetShouldBeFluentSniff implements \PHP_CodeSniffer_Sniff
{
    public function register()
    {
        return array(T_FUNCTION);
    }
 
    /**
     * Processes the tokens that this sniff is interested in.
     *
     * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
     * @param int                  $stackPtr  The position in the stack where
     *                                        the token was found.
     *
     * @return void
     */
    public function process(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $methodName = $phpcsFile->getDeclarationName($stackPtr);
        if (null === $methodName) {
            return;
        }
 
        // check fluent interface for `set*()` and `add*()`.
        $methodType = substr($methodName, 0, 3);
        if (false === in_array($methodType, array('set', 'add'))) {
            return;
        }
 
        // for `fooAction` methods in controllers
        if (substr($methodName, -6) == 'Action') {
            return;
        }
 
        $error = sprintf('`%s` should implement a fluent interface', $methodName);
 
        $t_return = $phpcsFile->findNext(T_RETURN, $stackPtr);
        if (false === $t_return) {
            $phpcsFile->addError(
                $error,
                $stackPtr,
                'AddSetNoFluentInterface'
            );
            return;
        }
 
        $tokens = $phpcsFile->getTokens();
        if ($tokens[($t_return+1)]['type'] !== 'T_WHITESPACE') {
            $phpcsFile->addError(
                $error,
                ($t_return+1),
                'AddSetNoFluentInterface'
            );
            return;
        }
        if ($tokens[($t_return+2)]['content'] !== '$this') {
            $phpcsFile->addError(
                $error,
                ($t_return+2),
                'AddSetNoFluentInterface'
            );
            return;
        }
    }
}
 
raw

EasyBib/Sniffs/Methods/ConstructShouldNotReturnSniff.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?php
/**
 * EasyBib\Sniffs\Methods\ConstructShouldNotReturnSniff
 *
 * PHP version 5.3
 *
 * @category QA
 * @package  EasyBib\Sniffs
 * @author   Till Klampaeckel <till@php.net>
 * @license  http://opensource.org/licenses/bsd-license.php New BSD License
 * @version  GIT: <git_id>
 * @link     http://
 */
 
namespace EasyBib\Sniffs\Methods;
 
/**
 * EasyBib\Sniffs\Methods\ConstructShouldNotReturnSniff
 *
 * Ensures that there are no `return` statements in a `__construct` and that the docblock
 * says `return $this` - if anything.
 *
 * @category  QA
 * @package   EasyBib\Sniffs
 * @author    Till Klampaeckel <till@php.net>
 * @license   http://opensource.org/licenses/bsd-license.php New BSD License
 * @version   Release: @package_version@
 * @link      http://
 */
class ConstructShouldNotReturnSniff extends \PHP_CodeSniffer_Standards_AbstractScopeSniff
{
    public function __construct()
    {
        parent::__construct(array(T_FUNCTION), array(T_RETURN));
    }
 
    /**
     * Processes the tokens that this sniff is interested in.
     *
     * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
     * @param int                  $stackPtr  The position in the stack where
     *                                        the token was found.
     * @param int                  $currScope The current scope opener token.
     *
     * @return void
     */
    protected function processTokenWithinScope(\PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope)
    {
        $methodName = $phpcsFile->getDeclarationName($currScope);
        if (null === $methodName) {
            return;
        }
        if ('__construct' !== $methodName) {
            return;
        }
 
        $tokens = $phpcsFile->getTokens();
        if (!isset($tokens[$stackPtr])) {
            return;
        }
 
        if ('T_RETURN' === $tokens[$stackPtr]['type'] && 'T_SEMICOLON' !== $tokens[$stackPtr+1]['type']) {
            $phpcsFile->addWarning('__construct cannot return anything', $stackPtr, 'NoReturnInConstruct');
            return;
        }
    }
}
 
raw

EasyBib/ruleset.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?xml version="1.0"?>
<ruleset name="EasyBib">
 
 <description>EasyBib Coding Standard.</description>
 
 <exclude-pattern>*tests/*</exclude-pattern>
 <exclude-pattern>*data/*</exclude-pattern>
 <exclude-pattern>*var/*</exclude-pattern>
 <exclude-pattern>*bin/*</exclude-pattern>
 <exclude-pattern>*vendor/*</exclude-pattern>
 <exclude-pattern>*www/*</exclude-pattern>
 <exclude-pattern>*views/scripts/*</exclude-pattern>
 <exclude-pattern>*etc/*</exclude-pattern>
 <exclude-pattern>*examples/*</exclude-pattern>
 <exclude-pattern>*docs/*</exclude-pattern>
 
 <rule ref="PEAR"/>
 <rule ref="PSR1"/>
 <rule ref="PSR2"/>
 
 <rule ref="Generic.Commenting.Todo.CommentFound">
  <message>Please review this TODO comment: %s</message>
  <severity>3</severity>
 </rule>
 
 <rule ref="Generic.NamingConventions.UpperCaseConstantName"/>
 <rule ref="Generic.NamingConventions.CamelCapsFunctionName">
  <properties>
   <property name="strict" value="false"/>
  </properties>
 </rule>
 
 <rule ref="PEAR.NamingConventions.ValidFunctionName">
  <exclude name="PEAR.NamingConventions.ValidFunctionName.PrivateNoUnderscore"/>
  <exclude name="PEAR.NamingConventions.ValidFunctionName.FunctionUnderscore"/>
 </rule>
 
 <rule ref="PEAR.NamingConventions.ValidVariableName">
  <exclude name="PEAR.NamingConventions.ValidVariableName.PrivateNoUnderscore"/>
 </rule>
 
 <!-- this is primarily for controllers and ZF1 -->
 <rule ref="PSR1.Classes.ClassDeclaration">
  <exclude name="PSR1.Classes.ClassDeclaration.MissingNamespace"/>
 </rule>
 
 <rule ref="PSR2.Files.EndFileNewline">
  <exclude name="PSR2.Files.EndFileNewline.NotFound"/>
 </rule>
 
 <rule ref="PSR2.ControlStructures.SwitchDeclaration">
  <exclude name="PSR2.ControlStructures.SwitchDeclaration.caseIndent"/>
 </rule>
 
 <rule ref="EasyBib.Methods.ConstructShouldNotReturn"/>
 <rule ref="EasyBib.Methods.AddSetShouldBeFluent"/>
 <rule ref="EasyBib.Commenting.ReturnStatements"/>
</ruleset>
 
raw

README.md

EasyBib's Coding Standard

Usage (WIP)

  1. Install: pear install PHP_CodeSniffer
  2. clone this repo
  3. check CS

This is how:

 phpcs \
 --standard=/path/to/repo/EasyBib/ruleset.xml \
 target-dir

Todo

  • create a pear package
  • figure out how to register the style
  • add this to .travis.yml on various projects
raw

composer.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
    "type": "library",
    "license": "BSD",
    "repositories": [
        {
            "type": "pear",
            "url": "http://pear.php.net"
        }
    ],
    "autoload": {
        "psr-0": {
            "EasyBib\\PHP\\CodeSniffer": "library",
            "PHP_CodeSniffer": "vendor/pear-pear.php.net/PHP_CodeSniffer"
        }
    },
    "require-dev": {
        "pear-pear/php_codesniffer": "*"
    }
}
 
raw

test.php

1
2
3
4
5
6
<?php
require './vendor/autoload.php';
 
$cs = new \EasyBib\PHP\CodeSniffer\CodingStandard;
$cs->getIncludedSniffs();
 

History