forked from squizlabs/PHP_CodeSniffer
-
Notifications
You must be signed in to change notification settings - Fork 2
/
phpcs-svn-pre-commit
executable file
·229 lines (188 loc) · 7.35 KB
/
phpcs-svn-pre-commit
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#!@php_bin@
<?php
/**
* A commit hook for SVN.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Jack Bates <[email protected]>
* @author Greg Sherwood <[email protected]>
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
if (is_file(dirname(__FILE__).'/../CodeSniffer/CLI.php') === true) {
include_once dirname(__FILE__).'/../CodeSniffer/CLI.php';
} else {
include_once 'PHP/CodeSniffer/CLI.php';
}
define('PHP_CODESNIFFER_SVNLOOK', '/usr/bin/svnlook');
/**
* A class to process command line options.
*
* @category PHP
* @package PHP_CodeSniffer
* @author Jack Bates <[email protected]>
* @author Greg Sherwood <[email protected]>
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
* @version Release: @package_version@
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class PHP_CodeSniffer_SVN_Hook extends PHP_CodeSniffer_CLI
{
/**
* Get a list of default values for all possible command line arguments.
*
* @return array
*/
public function getDefaults()
{
$defaults = parent::getDefaults();
$defaults['svnArgs'] = array();
return $defaults;
}//end getDefaults()
/**
* Processes an unknown command line argument.
*
* Assumes all unknown arguments are files and folders to check.
*
* @param string $arg The command line argument.
* @param int $pos The position of the argument on the command line.
*
* @return void
*/
public function processUnknownArgument($arg, $pos)
{
$this->values['svnArgs'][] = escapeshellarg($arg);
}//end processUnknownArgument()
/**
* Runs PHP_CodeSniffer over files are directories.
*
* @param array $values An array of values determined from CLI args.
*
* @return int The number of error and warning messages shown.
* @see getCommandLineValues()
*/
public function process($values=array())
{
if (empty($values) === true) {
$values = $this->getCommandLineValues();
} else {
$values = array_merge($this->getDefaults(), $values);
$this->values = $values;
}
// Get list of files in this transaction.
$command = PHP_CODESNIFFER_SVNLOOK.' changed '.implode(' ', $values['svnArgs']);
$handle = popen($command, 'r');
if ($handle === false) {
echo 'ERROR: Could not execute "'.$command.'"'.PHP_EOL.PHP_EOL;
exit(2);
}
$contents = stream_get_contents($handle);
fclose($handle);
// Do not check deleted paths.
$contents = preg_replace('/^D.*/m', null, $contents);
// Drop the four characters representing the action which precede the path on
// each line.
$contents = preg_replace('/^.{4}/m', null, $contents);
$values['standard'] = $this->validateStandard($values['standard']);
foreach ($values['standard'] as $standard) {
if (PHP_CodeSniffer::isInstalledStandard($standard) === false) {
// They didn't select a valid coding standard, so help them
// out by letting them know which standards are installed.
echo 'ERROR: the "'.$standard.'" coding standard is not installed. ';
$this->printInstalledStandards();
exit(2);
}
}
$phpcs = new PHP_CodeSniffer(
$values['verbosity'],
$values['tabWidth'],
$values['encoding']
);
// Set file extensions if they were specified. Otherwise,
// let PHP_CodeSniffer decide on the defaults.
if (empty($values['extensions']) === false) {
$phpcs->setAllowedFileExtensions($values['extensions']);
} else {
$phpcs->setAllowedFileExtensions(array_keys($phpcs->defaultFileExtensions));
}
// Set ignore patterns if they were specified.
if (empty($values['ignored']) === false) {
$phpcs->setIgnorePatterns($values['ignored']);
}
// Set some convenience member vars.
if ($values['errorSeverity'] === null) {
$this->errorSeverity = PHPCS_DEFAULT_ERROR_SEV;
} else {
$this->errorSeverity = $values['errorSeverity'];
}
if ($values['warningSeverity'] === null) {
$this->warningSeverity = PHPCS_DEFAULT_WARN_SEV;
} else {
$this->warningSeverity = $values['warningSeverity'];
}
if (empty($values['reports']) === true) {
$this->values['reports']['full'] = $values['reportFile'];
}
// Initialize PHP_CodeSniffer listeners but don't process any files.
$phpcs->setCli($this);
$phpcs->initStandard($values['standard'], $values['sniffs']);
// Need double quotes around the following regex beause the vertical whitespace
// char is not always treated correctly for whatever reason.
foreach (preg_split("/\v|\n/", $contents, -1, PREG_SPLIT_NO_EMPTY) as $path) {
// No need to process folders as each changed file is checked.
if (substr($path, -1) === '/') {
continue;
}
// We need to check ignore rules ourself because they are
// not checked when processing a single file.
if ($phpcs->shouldProcessFile($path, dirname($path)) === false) {
continue;
}
// Get the contents of each file, as it would be after this transaction.
$command = PHP_CODESNIFFER_SVNLOOK.' cat '.implode(' ', $values['svnArgs']).' '.escapeshellarg($path);
$handle = popen($command, 'r');
if ($handle === false) {
echo 'ERROR: Could not execute "'.$command.'"'.PHP_EOL.PHP_EOL;
exit(2);
}
$contents = stream_get_contents($handle);
fclose($handle);
$phpcs->processFile($path, $contents);
}//end foreach
return $this->printErrorReport(
$phpcs,
$values['reports'],
$values['showSources'],
$values['reportFile'],
$values['reportWidth']
);
}//end process()
/**
* Prints out the usage information for this script.
*
* @return void
*/
public function printUsage()
{
parent::printUsage();
echo PHP_EOL;
echo ' Each additional argument is passed to the `svnlook changed ...`'.PHP_EOL;
echo ' and `svnlook cat ...` commands. The report is printed on standard output,'.PHP_EOL;
echo ' however Subversion displays only standard error to the user, so in a'.PHP_EOL;
echo ' pre-commit hook, this script should be invoked as follows:'.PHP_EOL;
echo PHP_EOL;
echo ' '.basename($_SERVER['argv'][0]).' ... "$REPOS" -t "$TXN" >&2 || exit 1'.PHP_EOL;
}//end printUsage()
}//end class
$phpcs = new PHP_CodeSniffer_SVN_Hook();
PHP_CodeSniffer_Reporting::startTiming();
$phpcs->checkRequirements();
$numErrors = $phpcs->process();
if ($numErrors !== 0) {
exit(1);
}