1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the humbug/php-scoper package. |
5
|
|
|
* |
6
|
|
|
* Copyright (c) 2017 Théo FIDRY <[email protected]>, |
7
|
|
|
* Pádraic Brady <[email protected]> |
8
|
|
|
* |
9
|
|
|
* For the full copyright and license information, please view the LICENSE |
10
|
|
|
* file that was distributed with this source code. |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
namespace Humbug\PhpScoper; |
14
|
|
|
|
15
|
|
|
use Humbug\PhpScoper\Autoload\Requirements; |
16
|
|
|
use Symfony\Requirements\Requirement; |
17
|
|
|
|
18
|
|
|
// |
19
|
|
|
// Code in this file must be PHP 5.3+ compatible as is used to know if PHP-Scoper can be run or not. |
20
|
|
|
// |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* @param string $composerJson |
24
|
|
|
* @param bool $verbose |
25
|
|
|
* |
26
|
|
|
* @return bool |
27
|
|
|
*/ |
28
|
|
|
function check_requirements($composerJson, $verbose) |
29
|
|
|
{ |
30
|
|
|
$lineSize = 70; |
31
|
|
|
$requirements = new Requirements($composerJson); |
32
|
|
|
$iniPath = $requirements->getPhpIniPath(); |
33
|
|
|
|
34
|
|
|
$checkPassed = array_reduce( |
35
|
|
|
$requirements->getRequirements(), |
36
|
|
|
/** |
37
|
|
|
* @param bool $checkPassed |
38
|
|
|
* @param Requirement $requirement |
39
|
|
|
* |
40
|
|
|
* @return bool |
41
|
|
|
*/ |
42
|
|
|
function ($checkPassed, Requirement $requirement) use ($lineSize) { |
43
|
|
|
return $checkPassed || null === get_error_message($requirement, $lineSize); |
44
|
|
|
}, |
45
|
|
|
false |
46
|
|
|
); |
47
|
|
|
|
48
|
|
|
if (false === $checkPassed) { |
49
|
|
|
// Override the default verbosity to output errors regardless of the verbosity asked by the user |
50
|
|
|
$verbose = true; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
echo_title('PHP-Scoper Requirements Checker', null, $verbose); |
|
|
|
|
54
|
|
|
|
55
|
|
|
vecho('> PHP is using the following php.ini file:'.PHP_EOL, $verbose); |
56
|
|
|
|
57
|
|
|
if ($iniPath) { |
|
|
|
|
58
|
|
|
echo_style('green', ' '.$iniPath, $verbose); |
|
|
|
|
59
|
|
|
} else { |
60
|
|
|
echo_style('yellow', ' WARNING: No configuration file (php.ini) used by PHP!', $verbose); |
|
|
|
|
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
vecho(PHP_EOL.PHP_EOL, $verbose); |
64
|
|
|
vecho('> Checking PHP-Scoper requirements:'.PHP_EOL.' ', $verbose); |
65
|
|
|
|
66
|
|
|
$messages = []; |
67
|
|
|
|
68
|
|
|
foreach ($requirements->getRequirements() as $requirement) { |
69
|
|
View Code Duplication |
if ($helpText = get_error_message($requirement, $lineSize)) { |
|
|
|
|
70
|
|
|
echo_style('red', 'E', $verbose); |
|
|
|
|
71
|
|
|
$messages['error'][] = $helpText; |
72
|
|
|
} else { |
73
|
|
|
echo_style('green', '.', $verbose); |
|
|
|
|
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
foreach ($requirements->getRecommendations() as $requirement) { |
78
|
|
View Code Duplication |
if ($helpText = get_error_message($requirement, $lineSize)) { |
|
|
|
|
79
|
|
|
echo_style('yellow', 'W', $verbose); |
|
|
|
|
80
|
|
|
$messages['warning'][] = $helpText; |
81
|
|
|
} else { |
82
|
|
|
echo_style('green', '.', $verbose); |
|
|
|
|
83
|
|
|
} |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
if ($checkPassed) { |
87
|
|
|
echo_block('success', 'OK', 'Your system is ready to run PHP-Scoper.', $verbose); |
|
|
|
|
88
|
|
|
} else { |
89
|
|
|
echo_block('error', 'ERROR', 'Your system is not ready to run PHP-Scoper', $verbose); |
|
|
|
|
90
|
|
|
|
91
|
|
|
echo_title('Fix the following mandatory requirements', 'red', $verbose); |
|
|
|
|
92
|
|
|
|
93
|
|
|
foreach ($messages['error'] as $helpText) { |
94
|
|
|
vecho(' * '.$helpText.PHP_EOL, $verbose); |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
if (!empty($messages['warning'])) { |
99
|
|
|
echo_title('Optional recommendations to improve your setup', 'yellow', $verbose); |
|
|
|
|
100
|
|
|
|
101
|
|
|
foreach ($messages['warning'] as $helpText) { |
102
|
|
|
vecho(' * '.$helpText.PHP_EOL, $verbose); |
103
|
|
|
} |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
return $checkPassed; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
function vecho($message, $verbose) |
110
|
|
|
{ |
111
|
|
|
if (false === $verbose) { |
112
|
|
|
return; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
echo $message; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @param Requirement $requirement |
120
|
|
|
* @param int $lineSize |
121
|
|
|
* |
122
|
|
|
* @return string|null |
123
|
|
|
*/ |
124
|
|
|
function get_error_message(Requirement $requirement, $lineSize) |
125
|
|
|
{ |
126
|
|
|
if ($requirement->isFulfilled()) { |
127
|
|
|
return null; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
$errorMessage = wordwrap($requirement->getTestMessage(), $lineSize - 3, PHP_EOL.' ').PHP_EOL; |
131
|
|
|
|
132
|
|
|
if ('' !== $requirement->getHelpText()) { |
133
|
|
|
$errorMessage .= ' > '.wordwrap($requirement->getHelpText(), $lineSize - 5, PHP_EOL.' > ').PHP_EOL; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
return $errorMessage; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* @param string $title |
141
|
|
|
* @param string|null $style |
142
|
|
|
* @param bool $verbose |
143
|
|
|
*/ |
144
|
|
|
function echo_title($title, $style = null, $verbose) |
145
|
|
|
{ |
146
|
|
|
if (false === $verbose) { |
147
|
|
|
return; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
$style = $style ?: 'title'; |
151
|
|
|
|
152
|
|
|
echo PHP_EOL; |
153
|
|
|
echo_style($style, $title.PHP_EOL, $verbose); |
|
|
|
|
154
|
|
|
echo_style($style, str_repeat('~', strlen($title)).PHP_EOL, $verbose); |
|
|
|
|
155
|
|
|
echo PHP_EOL; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* @param string $style |
160
|
|
|
* @param string $message |
161
|
|
|
* @param bool $verbose |
162
|
|
|
*/ |
163
|
|
|
function echo_style($style, $message, $verbose) |
164
|
|
|
{ |
165
|
|
|
if (false === $verbose) { |
166
|
|
|
return; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
// ANSI color codes |
170
|
|
|
$styles = array( |
171
|
|
|
'reset' => "\033[0m", |
172
|
|
|
'red' => "\033[31m", |
173
|
|
|
'green' => "\033[32m", |
174
|
|
|
'yellow' => "\033[33m", |
175
|
|
|
'error' => "\033[37;41m", |
176
|
|
|
'success' => "\033[37;42m", |
177
|
|
|
'title' => "\033[34m", |
178
|
|
|
); |
179
|
|
|
$supports = has_color_support(); |
180
|
|
|
|
181
|
|
|
echo($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : ''); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* @param string $style |
186
|
|
|
* @param string $title |
187
|
|
|
* @param string $message |
188
|
|
|
* @param bool $verbose |
189
|
|
|
*/ |
190
|
|
|
function echo_block($style, $title, $message, $verbose) |
191
|
|
|
{ |
192
|
|
|
if (false === $verbose) { |
193
|
|
|
return; |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
$message = ' '.trim($message).' '; |
197
|
|
|
$width = strlen($message); |
198
|
|
|
|
199
|
|
|
echo PHP_EOL.PHP_EOL; |
200
|
|
|
|
201
|
|
|
echo_style($style, str_repeat(' ', $width), $verbose); |
|
|
|
|
202
|
|
|
echo PHP_EOL; |
203
|
|
|
echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT), $verbose); |
|
|
|
|
204
|
|
|
echo PHP_EOL; |
205
|
|
|
echo_style($style, $message, $verbose); |
|
|
|
|
206
|
|
|
echo PHP_EOL; |
207
|
|
|
echo_style($style, str_repeat(' ', $width), $verbose); |
|
|
|
|
208
|
|
|
echo PHP_EOL; |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* @return bool |
213
|
|
|
*/ |
214
|
|
|
function has_color_support() |
215
|
|
|
{ |
216
|
|
|
static $support; |
217
|
|
|
|
218
|
|
|
if (null === $support) { |
219
|
|
|
if (DIRECTORY_SEPARATOR == '\\') { |
220
|
|
|
$support = false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'); |
221
|
|
|
} else { |
222
|
|
|
$support = function_exists('posix_isatty') && @posix_isatty(STDOUT); |
223
|
|
|
} |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
return $support; |
227
|
|
|
} |
228
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.