This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the puli/installer package. |
||
5 | * |
||
6 | * (c) Bernhard Schussek <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace Puli\Installer; |
||
13 | |||
14 | use Exception; |
||
15 | use Humbug\SelfUpdate\VersionParser; |
||
16 | use Phar; |
||
17 | use PharException; |
||
18 | use RuntimeException; |
||
19 | use UnexpectedValueException; |
||
20 | |||
21 | /** |
||
22 | * Installs the puli.phar on the local system. |
||
23 | * |
||
24 | * Use it like this: |
||
25 | * |
||
26 | * ``` |
||
27 | * $ curl -sS https://puli.io/installer | php |
||
28 | * ``` |
||
29 | * |
||
30 | * This file was adapted from the installer file bundled with Composer. For the |
||
31 | * original file, authors and copyright information see |
||
32 | * |
||
33 | * https://github.com/composer/getcomposer.org/blob/master/web/installer |
||
34 | * |
||
35 | * @author Nils Adermann <[email protected]> |
||
36 | * @author Jordi Boggiano <[email protected]> |
||
37 | * @author Thomas Rudolph <[email protected]> |
||
38 | * @author Bernhard Schussek <[email protected]> |
||
39 | */ |
||
40 | class Installer |
||
41 | { |
||
42 | /** |
||
43 | * The help text of the installer. |
||
44 | */ |
||
45 | const HELP_TEXT = <<<'HELP' |
||
46 | Puli Installer |
||
47 | -------------- |
||
48 | Options |
||
49 | --help this help |
||
50 | --check for checking environment only |
||
51 | --force forces the installation even if the system requirements are not satisfied |
||
52 | --ansi force ANSI color output |
||
53 | --no-ansi disable ANSI color output |
||
54 | --quiet do not output unimportant messages |
||
55 | --install-dir="..." set the target installation directory |
||
56 | --version="..." install a specific version |
||
57 | --filename="..." set the target filename (default: puli.phar) |
||
58 | |||
59 | HELP; |
||
60 | |||
61 | /** |
||
62 | * The api url to determine the available versions of puli. |
||
63 | */ |
||
64 | const VERSION_API_URL = 'https://puli.io/download/versions.json'; |
||
65 | |||
66 | /** |
||
67 | * The phar download url. |
||
68 | */ |
||
69 | const PHAR_DOWNLOAD_URL = 'https://puli.io/download/%s/puli.phar'; |
||
70 | |||
71 | /** |
||
72 | * @var string |
||
73 | */ |
||
74 | private $stability; |
||
75 | |||
76 | /** |
||
77 | * @var bool |
||
78 | */ |
||
79 | private $check; |
||
80 | |||
81 | /** |
||
82 | * @var bool |
||
83 | */ |
||
84 | private $help; |
||
85 | |||
86 | /** |
||
87 | * @var bool |
||
88 | */ |
||
89 | private $force; |
||
90 | |||
91 | /** |
||
92 | * @var bool |
||
93 | */ |
||
94 | private $quiet; |
||
95 | |||
96 | /** |
||
97 | * @var string |
||
98 | */ |
||
99 | private $installDir; |
||
100 | |||
101 | /** |
||
102 | * @var string |
||
103 | */ |
||
104 | private $version; |
||
105 | |||
106 | /** |
||
107 | * @var string |
||
108 | */ |
||
109 | private $filename; |
||
110 | |||
111 | /** |
||
112 | * Runs the installer. |
||
113 | * |
||
114 | * @param array $argv The console arguments. |
||
115 | * |
||
116 | * @return int The return status. |
||
117 | */ |
||
118 | 5 | public function run(array $argv) |
|
119 | { |
||
120 | 5 | $this->parseOptions($argv); |
|
121 | |||
122 | 5 | if ($this->help) { |
|
123 | echo self::HELP_TEXT; |
||
124 | |||
125 | return 0; |
||
126 | } |
||
127 | |||
128 | 5 | $ok = $this->validateSystem() && $this->validateOptions(); |
|
129 | |||
130 | 5 | if ($this->check) { |
|
131 | return $ok ? 0 : 1; |
||
132 | } |
||
133 | |||
134 | 5 | if ($ok || $this->force) { |
|
135 | 5 | return $this->installPuli(); |
|
136 | } |
||
137 | |||
138 | return 1; |
||
139 | } |
||
140 | |||
141 | /** |
||
142 | * Installs puli to the current working directory. |
||
143 | * |
||
144 | * @return int The return status. |
||
145 | * |
||
146 | * @throws Exception |
||
147 | */ |
||
148 | 5 | private function installPuli() |
|
149 | { |
||
150 | 5 | $workingDir = str_replace('\\', '/', getcwd()); |
|
151 | 5 | $installDir = is_dir($this->installDir) ? realpath($this->installDir) : $workingDir; |
|
152 | 5 | $installPath = str_replace('\\', '/', $installDir).'/'.$this->filename; |
|
153 | 5 | $shortInstallPath = $installPath; |
|
154 | |||
155 | // Strip the current working directory if possible |
||
156 | 5 | if (0 === strpos($shortInstallPath, $workingDir.'/')) { |
|
157 | 3 | $shortInstallPath = substr($shortInstallPath, strlen($workingDir.'/')); |
|
158 | 3 | } |
|
159 | |||
160 | 5 | if (is_readable($installPath)) { |
|
161 | @unlink($installPath); |
||
0 ignored issues
–
show
|
|||
162 | } |
||
163 | |||
164 | 5 | $httpClient = new HttpClient(); |
|
165 | |||
166 | 5 | $versions = array(); |
|
167 | 5 | for ($retries = 3; $retries > 0; --$retries) { |
|
168 | 5 | if (!$this->quiet) { |
|
169 | 5 | $this->info('Downloading available versions...'); |
|
170 | 5 | } |
|
171 | |||
172 | try { |
||
173 | 5 | $versions = $this->downloadVersions($httpClient, static::VERSION_API_URL); |
|
174 | 5 | break; |
|
175 | } catch (RuntimeException $e) { |
||
176 | $this->error($e->getMessage()); |
||
177 | } |
||
178 | } |
||
179 | |||
180 | 5 | if (0 === $retries || empty($versions)) { |
|
181 | $this->error('fatal: The download failed repeatedly, aborting.'); |
||
182 | |||
183 | return 1; |
||
184 | } |
||
185 | |||
186 | 5 | $versionParser = new VersionParser($versions); |
|
187 | 5 | if (!empty($this->version)) { |
|
188 | 1 | if (!in_array($this->version, $versions, true)) { |
|
189 | $this->error(sprintf( |
||
190 | 'fatal: Could not find version: %s.', |
||
191 | $this->version |
||
192 | )); |
||
193 | |||
194 | return 1; |
||
195 | } |
||
196 | 5 | } elseif ('stable' === $this->stability) { |
|
197 | 1 | $this->version = $versionParser->getMostRecentStable(); |
|
198 | 1 | if (false === $this->version) { |
|
199 | 1 | $this->error('fatal: Could not find a stable version.'); |
|
200 | |||
201 | 1 | return 1; |
|
202 | } |
||
203 | } else { |
||
204 | 3 | $this->version = $versionParser->getMostRecentAll(); |
|
205 | } |
||
206 | |||
207 | 4 | $url = sprintf( |
|
208 | 4 | static::PHAR_DOWNLOAD_URL, |
|
209 | 4 | $this->version |
|
210 | 4 | ); |
|
211 | |||
212 | 4 | for ($retries = 3; $retries > 0; --$retries) { |
|
213 | 4 | if (!$this->quiet) { |
|
214 | 4 | $this->info(sprintf( |
|
215 | 4 | 'Downloading puli.phar at version %s...', |
|
216 | 4 | $this->version) |
|
217 | 4 | ); |
|
218 | 4 | } |
|
219 | |||
220 | 4 | if (!$this->downloadFile($httpClient, $url, $installPath)) { |
|
221 | continue; |
||
222 | } |
||
223 | |||
224 | try { |
||
225 | 4 | $this->validatePhar($installPath); |
|
226 | 4 | } catch (Exception $e) { |
|
227 | unlink($installPath); |
||
228 | |||
229 | if (!$e instanceof UnexpectedValueException && !$e instanceof PharException) { |
||
230 | throw $e; |
||
231 | } |
||
232 | |||
233 | if ($retries > 0) { |
||
234 | if (!$this->quiet) { |
||
235 | $this->error('The download is corrupt, retrying...'); |
||
236 | } |
||
237 | } else { |
||
238 | $this->error(sprintf( |
||
239 | 'fatal: The download is corrupt (%s), aborting.', |
||
240 | $e->getMessage() |
||
241 | )); |
||
242 | |||
243 | return 1; |
||
244 | } |
||
245 | } |
||
246 | |||
247 | 4 | break; |
|
248 | } |
||
249 | |||
250 | 4 | if (0 === $retries) { |
|
251 | $this->error('fatal: The download failed repeatedly, aborting.'); |
||
252 | |||
253 | return 1; |
||
254 | } |
||
255 | |||
256 | 4 | chmod($installPath, 0755); |
|
257 | |||
258 | 4 | if (!$this->quiet) { |
|
259 | 4 | $this->success(PHP_EOL.'Puli successfully installed to: '.$installPath); |
|
260 | 4 | $this->info('Use it: php '.$shortInstallPath); |
|
261 | 4 | } |
|
262 | |||
263 | 4 | return 0; |
|
264 | } |
||
265 | |||
266 | /** |
||
267 | * Downloads a URL to a path. |
||
268 | * |
||
269 | * @param HttpClient $httpClient The client to use. |
||
270 | * @param string $url The URL to download. |
||
271 | * @param string $targetPath The path to download the URL to. |
||
272 | * |
||
273 | * @return bool Whether the download completed successfully. |
||
274 | */ |
||
275 | 4 | private function downloadFile(HttpClient $httpClient, $url, $targetPath) |
|
276 | { |
||
277 | 4 | ErrorHandler::register(); |
|
278 | |||
279 | 4 | $fh = fopen($targetPath, 'w'); |
|
280 | |||
281 | 4 | if (!$fh) { |
|
282 | $this->error(sprintf( |
||
283 | 'Could not create file %s: %s', |
||
284 | $targetPath, |
||
285 | implode(PHP_EOL, ErrorHandler::getErrors()) |
||
286 | )); |
||
287 | } |
||
288 | |||
289 | 4 | if (!fwrite($fh, $httpClient->download($url))) { |
|
290 | $this->error(sprintf( |
||
291 | 'Download failed: %s', |
||
292 | implode(PHP_EOL, ErrorHandler::getErrors()) |
||
293 | )); |
||
294 | } |
||
295 | |||
296 | 4 | fclose($fh); |
|
297 | |||
298 | 4 | ErrorHandler::unregister(); |
|
299 | |||
300 | 4 | return !ErrorHandler::hasErrors(); |
|
301 | } |
||
302 | |||
303 | /** |
||
304 | * Downloads the available puli versions. |
||
305 | * |
||
306 | * @param HttpClient $httpClient The client to use. |
||
307 | * @param string $url The URL to download. |
||
308 | * |
||
309 | * @return array The available versions, null if the download failed. |
||
310 | * |
||
311 | * @throws RuntimeException If an error occurs. |
||
312 | */ |
||
313 | 5 | public function downloadVersions(HttpClient $httpClient, $url) |
|
314 | { |
||
315 | 5 | ErrorHandler::register(); |
|
316 | 5 | $versions = $httpClient->download($url); |
|
317 | 5 | ErrorHandler::unregister(); |
|
318 | |||
319 | 5 | if (ErrorHandler::hasErrors()) { |
|
320 | throw new RuntimeException(sprintf( |
||
321 | 'Could not download %s:'.PHP_EOL.'%s', |
||
322 | $url, |
||
323 | implode(PHP_EOL, ErrorHandler::getErrors()) |
||
324 | )); |
||
325 | } |
||
326 | |||
327 | 5 | $versions = json_decode($versions); |
|
328 | 5 | if (json_last_error() !== JSON_ERROR_NONE || !is_array($versions)) { |
|
329 | throw new RuntimeException(sprintf( |
||
330 | 'Could not download %s:'.PHP_EOL.'Malformed JSON returned.', |
||
331 | $url |
||
332 | )); |
||
333 | } |
||
334 | |||
335 | 5 | usort($versions, 'version_compare'); |
|
336 | |||
337 | 5 | return $versions; |
|
338 | } |
||
339 | |||
340 | /** |
||
341 | * Validates that the given path is a valid PHAR file. |
||
342 | * |
||
343 | * @param string $path A path to a PHAR file. |
||
344 | * |
||
345 | * @throws Exception If an error occurs. |
||
346 | */ |
||
347 | 4 | private function validatePhar($path) |
|
348 | { |
||
349 | 4 | $tmpFile = $path; |
|
350 | |||
351 | try { |
||
352 | // create a temp file ending in .phar since the Phar class only accepts that |
||
353 | 4 | if ('.phar' !== substr($path, -5)) { |
|
354 | copy($path, $path.'.tmp.phar'); |
||
355 | $tmpFile = $path.'.tmp.phar'; |
||
356 | } |
||
357 | |||
358 | 4 | if (!ini_get('phar.readonly')) { |
|
359 | // test the phar validity |
||
360 | 4 | $phar = new Phar($tmpFile); |
|
361 | |||
362 | // free the variable to unlock the file |
||
363 | 4 | unset($phar); |
|
364 | 4 | } |
|
365 | 4 | } catch (Exception $e) { |
|
366 | // clean up temp file if needed |
||
367 | if ($path !== $tmpFile) { |
||
368 | unlink($tmpFile); |
||
369 | } |
||
370 | |||
371 | throw $e; |
||
372 | } |
||
373 | |||
374 | // clean up temp file if needed |
||
375 | 4 | if ($path !== $tmpFile) { |
|
376 | unlink($tmpFile); |
||
377 | } |
||
378 | 4 | } |
|
379 | |||
380 | /** |
||
381 | * Check the platform for possible issues on running Puli. |
||
382 | * |
||
383 | * @return bool Whether the platform requirements are satisfied. |
||
384 | */ |
||
385 | 5 | private function validateSystem() |
|
386 | { |
||
387 | 5 | $errors = array(); |
|
388 | 5 | $warnings = array(); |
|
389 | |||
390 | 5 | $iniPath = php_ini_loaded_file(); |
|
391 | 5 | $displayIniMessage = false; |
|
392 | |||
393 | 5 | if ($iniPath) { |
|
394 | 5 | $iniMessage = PHP_EOL.PHP_EOL.'The php.ini used by your command-line PHP is: '.$iniPath; |
|
395 | 5 | } else { |
|
396 | $iniMessage = PHP_EOL.PHP_EOL.'A php.ini file does not exist. You will have to create one.'; |
||
397 | } |
||
398 | |||
399 | 5 | $iniMessage .= PHP_EOL.'If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.'; |
|
400 | |||
401 | 5 | if (ini_get('detect_unicode')) { |
|
402 | $errors['unicode'] = 'On'; |
||
403 | } |
||
404 | |||
405 | 5 | if (extension_loaded('suhosin')) { |
|
406 | $suhosin = ini_get('suhosin.executor.include.whitelist'); |
||
407 | $suhosinBlacklist = ini_get('suhosin.executor.include.blacklist'); |
||
408 | if (false === stripos($suhosin, |
||
409 | 'phar') && (!$suhosinBlacklist || false !== stripos($suhosinBlacklist, |
||
410 | 'phar')) |
||
411 | ) { |
||
412 | $errors['suhosin'] = $suhosin; |
||
413 | } |
||
414 | } |
||
415 | |||
416 | 5 | if (!function_exists('json_decode')) { |
|
417 | $errors['json'] = true; |
||
418 | } |
||
419 | |||
420 | 5 | if (!extension_loaded('Phar')) { |
|
421 | $errors['phar'] = true; |
||
422 | } |
||
423 | |||
424 | 5 | if (!ini_get('allow_url_fopen')) { |
|
425 | $errors['allow_url_fopen'] = true; |
||
426 | } |
||
427 | |||
428 | 5 | if (extension_loaded('ionCube Loader') && ioncube_loader_iversion() < 40009) { |
|
429 | $errors['ioncube'] = ioncube_loader_version(); |
||
430 | } |
||
431 | |||
432 | 5 | if (version_compare(PHP_VERSION, '5.3.9', '<')) { |
|
433 | $errors['php'] = PHP_VERSION; |
||
434 | } |
||
435 | |||
436 | 5 | if (!extension_loaded('openssl')) { |
|
437 | $errors['openssl'] = true; |
||
438 | } |
||
439 | |||
440 | 5 | if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) { |
|
441 | $warnings['apc_cli'] = true; |
||
442 | } |
||
443 | |||
444 | 5 | ob_start(); |
|
445 | 5 | phpinfo(INFO_GENERAL); |
|
446 | 5 | $phpinfo = ob_get_clean(); |
|
447 | 5 | if (preg_match('{Configure Command(?: *</td><td class="v">| *=> *)(.*?)(?:</td>|$)}m', |
|
448 | 5 | $phpinfo, $match)) { |
|
449 | 5 | $configure = $match[1]; |
|
450 | |||
451 | 5 | if (false !== strpos($configure, '--enable-sigchild')) { |
|
452 | $warnings['sigchild'] = true; |
||
453 | } |
||
454 | |||
455 | 5 | if (false !== strpos($configure, '--with-curlwrappers')) { |
|
456 | $warnings['curlwrappers'] = true; |
||
457 | } |
||
458 | 5 | } |
|
459 | |||
460 | 5 | if (!empty($errors)) { |
|
461 | $this->error('Some settings on your machine make Puli unable to work properly.'); |
||
462 | $this->error('Make sure that you fix the issues listed below and run this script again:'); |
||
463 | |||
464 | foreach ($errors as $error => $current) { |
||
465 | $text = ''; |
||
466 | switch ($error) { |
||
467 | case 'json': |
||
468 | $text = PHP_EOL.'The json extension is missing.'.PHP_EOL; |
||
469 | $text .= 'Install it or recompile php without --disable-json'; |
||
470 | break; |
||
471 | |||
472 | case 'phar': |
||
473 | $text = PHP_EOL.'The phar extension is missing.'.PHP_EOL; |
||
474 | $text .= 'Install it or recompile php without --disable-phar'; |
||
475 | break; |
||
476 | |||
477 | View Code Duplication | case 'unicode': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
478 | $text = PHP_EOL.'The detect_unicode setting must be disabled.'.PHP_EOL; |
||
479 | $text .= 'Add the following to the end of your `php.ini`:'.PHP_EOL; |
||
480 | $text .= ' detect_unicode = Off'; |
||
481 | $displayIniMessage = true; |
||
482 | break; |
||
483 | |||
484 | View Code Duplication | case 'suhosin': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
485 | $text = PHP_EOL.'The suhosin.executor.include.whitelist setting is incorrect.'.PHP_EOL; |
||
486 | $text .= 'Add the following to the end of your `php.ini` or suhosin.ini (Example path [for Debian]: /etc/php5/cli/conf.d/suhosin.ini):'.PHP_EOL; |
||
487 | $text .= ' suhosin.executor.include.whitelist = phar '.$current; |
||
488 | $displayIniMessage = true; |
||
489 | break; |
||
490 | |||
491 | case 'php': |
||
492 | $text = PHP_EOL."Your PHP ({$current}) is too old, you must upgrade to PHP 5.3.9 or higher."; |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $current instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
493 | break; |
||
494 | |||
495 | View Code Duplication | case 'allow_url_fopen': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
496 | $text = PHP_EOL.'The allow_url_fopen setting is incorrect.'.PHP_EOL; |
||
497 | $text .= 'Add the following to the end of your `php.ini`:'.PHP_EOL; |
||
498 | $text .= ' allow_url_fopen = On'; |
||
499 | $displayIniMessage = true; |
||
500 | break; |
||
501 | |||
502 | View Code Duplication | case 'ioncube': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
503 | $text = PHP_EOL."Your ionCube Loader extension ($current) is incompatible with Phar files.".PHP_EOL; |
||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $current instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||
504 | $text .= 'Upgrade to ionCube 4.0.9 or higher or remove this line (path may be different) from your `php.ini` to disable it:'.PHP_EOL; |
||
505 | $text .= ' zend_extension = /usr/lib/php5/20090626+lfs/ioncube_loader_lin_5.3.so'; |
||
506 | $displayIniMessage = true; |
||
507 | break; |
||
508 | |||
509 | case 'openssl': |
||
510 | $text = PHP_EOL.'The openssl extension is missing, which means that secure HTTPS transfers are impossible.'.PHP_EOL; |
||
511 | $text .= 'If possible you should enable it or recompile php with --with-openssl'; |
||
512 | break; |
||
513 | } |
||
514 | |||
515 | if ($displayIniMessage) { |
||
516 | $text .= $iniMessage; |
||
517 | } |
||
518 | |||
519 | $this->info($text); |
||
520 | } |
||
521 | |||
522 | echo PHP_EOL; |
||
523 | |||
524 | return false; |
||
525 | } |
||
526 | |||
527 | 5 | if (!empty($warnings)) { |
|
528 | $this->error('Some settings on your machine may cause stability issues with Puli.'); |
||
529 | $this->error('If you encounter issues, try to change the following:'); |
||
530 | |||
531 | foreach ($warnings as $warning => $current) { |
||
532 | $text = ''; |
||
533 | switch ($warning) { |
||
534 | View Code Duplication | case 'apc_cli': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
535 | $text = PHP_EOL.'The apc.enable_cli setting is incorrect.'.PHP_EOL; |
||
536 | $text .= 'Add the following to the end of your `php.ini`:'.PHP_EOL; |
||
537 | $text .= ' apc.enable_cli = Off'; |
||
538 | $displayIniMessage = true; |
||
539 | break; |
||
540 | |||
541 | case 'sigchild': |
||
542 | $text = PHP_EOL.'PHP was compiled with --enable-sigchild which can cause issues on some platforms.'.PHP_EOL; |
||
543 | $text .= 'Recompile it without this flag if possible, see also:'.PHP_EOL; |
||
544 | $text .= ' https://bugs.php.net/bug.php?id=22999'; |
||
545 | break; |
||
546 | |||
547 | case 'curlwrappers': |
||
548 | $text = PHP_EOL.'PHP was compiled with --with-curlwrappers which will cause issues with HTTP authentication and GitHub.'.PHP_EOL; |
||
549 | $text .= 'Recompile it without this flag if possible'; |
||
550 | break; |
||
551 | |||
552 | case 'openssl': |
||
553 | $text = PHP_EOL.'The openssl extension is missing, which means that secure HTTPS transfers are impossible.'.PHP_EOL; |
||
554 | $text .= 'If possible you should enable it or recompile php with --with-openssl'; |
||
555 | break; |
||
556 | } |
||
557 | if ($displayIniMessage) { |
||
558 | $text .= $iniMessage; |
||
559 | } |
||
560 | $this->info($text); |
||
561 | } |
||
562 | |||
563 | echo PHP_EOL; |
||
564 | |||
565 | return true; |
||
566 | } |
||
567 | |||
568 | 5 | if (!$this->quiet) { |
|
569 | 5 | $this->success('All settings correct for using Puli'); |
|
570 | 5 | } |
|
571 | |||
572 | 5 | return true; |
|
573 | } |
||
574 | |||
575 | /** |
||
576 | * Validate whether the passed command line options are correct. |
||
577 | * |
||
578 | * @return bool Returns `true` if the options are valid and `false` otherwise. |
||
579 | */ |
||
580 | 5 | private function validateOptions() |
|
581 | { |
||
582 | 5 | $ok = true; |
|
583 | |||
584 | 5 | if (false !== $this->installDir && !is_dir($this->installDir)) { |
|
585 | $this->info(sprintf( |
||
586 | 'The defined install dir (%s) does not exist.', |
||
587 | $this->installDir |
||
588 | )); |
||
589 | $ok = false; |
||
590 | } |
||
591 | |||
592 | 5 | if (false !== $this->version && 1 !== preg_match('/^\d+\.\d+\.\d+(\-(alpha|beta)\d+)*$/', $this->version)) { |
|
593 | $this->info(sprintf( |
||
594 | 'The defined install version (%s) does not match release pattern.', |
||
595 | $this->version |
||
596 | )); |
||
597 | $ok = false; |
||
598 | } |
||
599 | |||
600 | 5 | return $ok; |
|
601 | } |
||
602 | |||
603 | /** |
||
604 | * Parses the command line options. |
||
605 | * |
||
606 | * @param string[] $argv The command line options. |
||
607 | */ |
||
608 | 5 | private function parseOptions(array $argv) |
|
609 | { |
||
610 | 5 | $this->check = in_array('--check', $argv); |
|
611 | 5 | $this->help = in_array('--help', $argv); |
|
612 | 5 | $this->force = in_array('--force', $argv); |
|
613 | 5 | $this->quiet = in_array('--quiet', $argv); |
|
614 | 5 | $this->installDir = false; |
|
0 ignored issues
–
show
The property
$installDir was declared of type string , but false is of type false . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
615 | 5 | $this->version = false; |
|
0 ignored issues
–
show
The property
$version was declared of type string , but false is of type false . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
616 | 5 | $this->filename = 'puli.phar'; |
|
617 | 5 | $this->stability = 'unstable'; |
|
618 | 5 | if (in_array('--stable', $argv)) { |
|
619 | 1 | $this->stability = 'stable'; |
|
620 | 1 | } |
|
621 | |||
622 | // --no-ansi wins over --ansi |
||
623 | 5 | if (in_array('--no-ansi', $argv)) { |
|
624 | 4 | define('USE_ANSI', false); |
|
625 | 5 | } elseif (in_array('--ansi', $argv)) { |
|
626 | define('USE_ANSI', true); |
||
627 | } else { |
||
628 | // On Windows, default to no ANSI, except in ANSICON and ConEmu. |
||
629 | // Everywhere else, default to ANSI if stdout is a terminal. |
||
630 | 1 | define('USE_ANSI', ('\\' === DIRECTORY_SEPARATOR) |
|
631 | 1 | ? (false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI')) |
|
632 | 1 | : (function_exists('posix_isatty') && posix_isatty(1))); |
|
633 | } |
||
634 | |||
635 | 5 | foreach ($argv as $key => $val) { |
|
636 | 5 | View Code Duplication | if (0 === strpos($val, '--install-dir')) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
637 | 2 | if (13 === strlen($val) && isset($argv[$key + 1])) { |
|
638 | 2 | $this->installDir = trim($argv[$key + 1]); |
|
639 | 2 | } else { |
|
640 | $this->installDir = trim(substr($val, 14)); |
||
641 | } |
||
642 | 2 | } |
|
643 | |||
644 | 5 | View Code Duplication | if (0 === strpos($val, '--version')) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
645 | 1 | if (9 === strlen($val) && isset($argv[$key + 1])) { |
|
646 | 1 | $this->version = trim($argv[$key + 1]); |
|
647 | 1 | } else { |
|
648 | $this->version = trim(substr($val, 10)); |
||
649 | } |
||
650 | 1 | } |
|
651 | |||
652 | 5 | View Code Duplication | if (0 === strpos($val, '--filename')) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
653 | if (10 === strlen($val) && isset($argv[$key + 1])) { |
||
654 | $this->filename = trim($argv[$key + 1]); |
||
655 | } else { |
||
656 | $this->filename = trim(substr($val, 11)); |
||
657 | } |
||
658 | } |
||
659 | 5 | } |
|
660 | 5 | } |
|
661 | |||
662 | /** |
||
663 | * Prints output indicating a success. |
||
664 | * |
||
665 | * @param string $text The text to print. |
||
666 | */ |
||
667 | 5 | private function success($text) |
|
668 | { |
||
669 | 5 | printf(USE_ANSI ? "\033[0;32m%s\033[0m" : '%s', $text.PHP_EOL); |
|
670 | 5 | } |
|
671 | |||
672 | /** |
||
673 | * Prints output indicating an error. |
||
674 | * |
||
675 | * @param string $text The text to print. |
||
676 | */ |
||
677 | 1 | private function error($text) |
|
678 | { |
||
679 | 1 | printf(USE_ANSI ? "\033[31;31m%s\033[0m" : '%s', $text.PHP_EOL); |
|
680 | 1 | } |
|
681 | |||
682 | /** |
||
683 | * Prints output indicating some information. |
||
684 | * |
||
685 | * @param string $text The text to print. |
||
686 | */ |
||
687 | 5 | private function info($text) |
|
688 | { |
||
689 | 5 | printf(USE_ANSI ? "\033[33;33m%s\033[0m" : '%s', $text.PHP_EOL); |
|
690 | 5 | } |
|
691 | } |
||
692 |
If you suppress an error, we recommend checking for the error condition explicitly: