Skip to content

Commit 8efbf43

Browse files
committed
Added plugins: PhpDocblockChecker, SensiolabsInsight, CampfireNotify, FlowdockNotify.
1 parent 9b76ca6 commit 8efbf43

7 files changed

Lines changed: 695 additions & 3 deletions

File tree

composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,14 @@
4343
"ext-simplexml": "*",
4444
"ext-dom": "*",
4545
"ext-pdo": "*",
46+
"ext-curl": "*",
4647
"php-censor/common": "dev-master",
4748
"sensiolabs/security-checker": "^5.0",
4849
"guzzlehttp/guzzle": "^6.5",
4950
"hipchat/hipchat-php": "^1.4",
5051
"maknz/slack": "^1.7",
51-
"sebastian/diff": "^3.0"
52+
"sebastian/diff": "^3.0",
53+
"php-censor/flowdock-client": "^1.0"
5254
},
5355
"require-dev": {
5456
"phpunit/phpunit": "^7.5",
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace PHPCensor\Plugins\CodeQuality;
6+
7+
use PHPCensor\Common\Build\BuildErrorInterface;
8+
use PHPCensor\Common\Build\BuildInterface;
9+
use PHPCensor\Common\Build\BuildMetaWriterInterface;
10+
use PHPCensor\Common\Plugin\Plugin;
11+
use PHPCensor\Common\Plugin\ZeroConfigPluginInterface;
12+
13+
/**
14+
* PHP Docblock Checker Plugin - Checks your PHP files for appropriate uses of Docblocks
15+
*
16+
* @package PHP Censor
17+
* @subpackage Plugins
18+
*
19+
* @author Dmitry Khomutov <poisoncorpsee@gmail.com>
20+
* @author Dan Cryer <dan@block8.co.uk>
21+
*/
22+
class PhpDocblockChecker extends Plugin implements ZeroConfigPluginInterface
23+
{
24+
/**
25+
* @var bool
26+
*/
27+
private $skipClasses = false;
28+
29+
/**
30+
* @var bool
31+
*/
32+
private $skipMethods = false;
33+
34+
/**
35+
* @var bool
36+
*/
37+
private $skipSignatures = false;
38+
39+
/**
40+
* @var int
41+
*/
42+
private $allowedWarnings = 0;
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
public static function getName(): string
48+
{
49+
return 'php_docblock_checker';
50+
}
51+
52+
/**
53+
* {@inheritdoc}
54+
*/
55+
public function execute(): bool
56+
{
57+
$executable = $this->commandExecutor->findBinary($this->binaryNames, $this->binaryPath);
58+
59+
$ignore = '';
60+
if (\is_array($this->ignores)) {
61+
$ignore = \sprintf(' --exclude="%s"', \implode(',', $this->ignores));
62+
}
63+
64+
$add = '';
65+
if ($this->skipClasses) {
66+
$add .= ' --skip-classes';
67+
}
68+
69+
if ($this->skipMethods) {
70+
$add .= ' --skip-methods';
71+
}
72+
73+
if ($this->skipSignatures) {
74+
$add .= ' --skip-signatures';
75+
}
76+
77+
// Build command string:
78+
$cmd = $executable . ' --json --directory="%s"%s%s';
79+
80+
if (!$this->build->isDebug()) {
81+
$this->commandExecutor->disableCommandOutput();
82+
}
83+
// Run checker:
84+
$this->commandExecutor->executeCommand(
85+
$cmd,
86+
$this->directory,
87+
$ignore,
88+
$add
89+
);
90+
$this->commandExecutor->enableCommandOutput();
91+
92+
$output = \json_decode($this->commandExecutor->getLastCommandOutput(), true);
93+
94+
$errors = 0;
95+
if ($output && \is_array($output)) {
96+
$errors = \count($output);
97+
$this->buildLogger->logWarning("Number of error : " . $errors);
98+
99+
$this->reportErrors($output);
100+
}
101+
$this->buildMetaWriter->write($this->build->getId(), self::getName(), BuildMetaWriterInterface::KEY_WARNINGS, $errors);
102+
103+
$success = true;
104+
105+
if (-1 !== $this->allowedWarnings && $errors > $this->allowedWarnings) {
106+
$success = false;
107+
}
108+
109+
return $success;
110+
}
111+
112+
/**
113+
* {@inheritdoc}
114+
*/
115+
public static function canExecute(string $stage, BuildInterface $build): bool
116+
{
117+
if (BuildInterface::STAGE_TEST === $stage) {
118+
return true;
119+
}
120+
121+
return false;
122+
}
123+
124+
/**
125+
* {@inheritdoc}
126+
*/
127+
protected function initPluginSettings(): void
128+
{
129+
if (isset($options['zero_config']) && $options['zero_config']) {
130+
$this->allowedWarnings = -1;
131+
}
132+
133+
$this->allowedWarnings = (int)$this->options->get('allowed_warnings', $this->allowedWarnings);
134+
$this->skipClasses = (bool)$this->options->get('skip_classes', $this->skipClasses);
135+
$this->skipMethods = (bool)$this->options->get('skip_methods', $this->skipMethods);
136+
$this->skipSignatures = (bool)$this->options->get('skip_signatures', $this->skipSignatures);
137+
}
138+
139+
/**
140+
* {@inheritdoc}
141+
*/
142+
protected function getPluginDefaultBinaryNames(): array
143+
{
144+
return [
145+
'phpdoc-checker',
146+
'phpdoc-checker.phar',
147+
];
148+
}
149+
150+
/**
151+
* Report all of the errors we've encountered line-by-line.
152+
*
153+
* @param array $output
154+
*/
155+
private function reportErrors(array $output): void
156+
{
157+
foreach ($output as $error) {
158+
switch ($error['type']) {
159+
case 'class':
160+
$message = 'Class ' . $error['class'] . ' is missing a docblock.';
161+
$severity = BuildErrorInterface::SEVERITY_NORMAL;
162+
break;
163+
164+
case 'method':
165+
$message = 'Method ' . $error['class'] . '::' . $error['method'] . ' is missing a docblock.';
166+
$severity = BuildErrorInterface::SEVERITY_NORMAL;
167+
break;
168+
169+
case 'param-missing':
170+
$message = $error['class'] . '::' . $error['method'] . ' @param ' . $error['param'] . ' missing.';
171+
$severity = BuildErrorInterface::SEVERITY_LOW;
172+
break;
173+
174+
case 'param-mismatch':
175+
$message = $error['class'] . '::' . $error['method'] . ' @param ' . $error['param'] .
176+
'(' . $error['doc-type'] . ') does not match method signature (' . $error['param-type'] . ')';
177+
$severity = BuildErrorInterface::SEVERITY_LOW;
178+
break;
179+
180+
case 'return-missing':
181+
$message = $error['class'] . '::' . $error['method'] . ' @return missing.';
182+
$severity = BuildErrorInterface::SEVERITY_LOW;
183+
break;
184+
185+
case 'return-mismatch':
186+
$message = $error['class'] . '::' . $error['method'] . ' @return ' . $error['doc-type'] .
187+
' does not match method signature (' . $error['return-type'] . ')';
188+
$severity = BuildErrorInterface::SEVERITY_LOW;
189+
break;
190+
191+
default:
192+
$message = 'Class ' . $error['class'] . ' invalid/missing a docblock.';
193+
$severity = BuildErrorInterface::SEVERITY_LOW;
194+
break;
195+
}
196+
197+
$this->buildErrorWriter->write(
198+
$this->build->getId(),
199+
self::getName(),
200+
(string)$message,
201+
$severity,
202+
(string)$error['file'],
203+
(int)$error['line']
204+
);
205+
}
206+
}
207+
}

0 commit comments

Comments
 (0)