*/ public static function getRawCliArguments(): array { global $argv; if (!$argv) { return []; } return array_slice($argv, 1); } /** * @return list */ public static function getArguments(): array { $argv = self::getRawCliArguments(); $filtered_input_paths = []; for ($i = 0, $iMax = count($argv); $i < $iMax; ++$i) { $input_path = $argv[$i]; if (realpath($input_path) !== false) { continue; } if ($input_path[0] === '-' && strlen($input_path) === 2) { if ($input_path[1] === 'c' || $input_path[1] === 'f') { ++$i; } continue; } if ($input_path[0] === '-' && $input_path[2] === '=') { continue; } $filtered_input_paths[] = $input_path; } return $filtered_input_paths; } /** * @param string|array|null|false $f_paths * * @return list|null */ public static function getPathsToCheck($f_paths): ?array { $paths_to_check = []; if ($f_paths) { $input_paths = is_array($f_paths) ? $f_paths : [$f_paths]; } else { $input_paths = self::getRawCliArguments(); if (!$input_paths) { return null; } } $filtered_input_paths = []; for ($i = 0, $iMax = count($input_paths); $i < $iMax; ++$i) { /** @var string */ $input_path = $input_paths[$i]; if ($input_path[0] === '-' && strlen($input_path) === 2) { if ($input_path[1] === 'c' || $input_path[1] === 'f') { ++$i; } continue; } if ($input_path[0] === '-' && $input_path[2] === '=') { continue; } if (strpos($input_path, '--') === 0 && strlen($input_path) > 2) { if (substr($input_path, 2) === 'config') { ++$i; } continue; } $filtered_input_paths[] = $input_path; } if ($filtered_input_paths === ['-']) { $meta = stream_get_meta_data(STDIN); stream_set_blocking(STDIN, false); if ($stdin = fgets(STDIN)) { $filtered_input_paths = preg_split('/\s+/', trim($stdin)); } $blocked = $meta['blocked']; stream_set_blocking(STDIN, $blocked); } foreach ($filtered_input_paths as $path_to_check) { if ($path_to_check[0] === '-') { fwrite(STDERR, 'Invalid usage, expecting psalm [options] [file...]' . PHP_EOL); exit(1); } if (!file_exists($path_to_check)) { fwrite(STDERR, 'Cannot locate ' . $path_to_check . PHP_EOL); exit(1); } $path_to_check = realpath($path_to_check); if (!$path_to_check) { fwrite(STDERR, 'Error getting realpath for file' . PHP_EOL); exit(1); } $paths_to_check[] = $path_to_check; } if (!$paths_to_check) { $paths_to_check = null; } return $paths_to_check; } /** * @psalm-pure * @todo move to Psalm\Internal\Cli\Psalm once \Psalm\getPsalmHelpText() is removed in Psalm 5 */ public static function getPsalmHelpText(): string { return <<getMessage() . PHP_EOL ); exit(1); } $config->setComposerClassLoader($first_autoloader); return $config; } public static function updateConfigFile(Config $config, string $config_file_path, string $baseline_path): void { if ($config->error_baseline === $baseline_path) { return; } $config_file = $config_file_path; if (is_dir($config_file_path)) { $config_file = Config::locateConfigFile($config_file_path); } if (!$config_file) { fwrite(STDERR, "Don't forget to set errorBaseline=\"{$baseline_path}\" to your config."); return; } $config_file_contents = file_get_contents($config_file); if ($config->error_baseline) { $amended_config_file_contents = preg_replace( '/errorBaseline=".*?"/', "errorBaseline=\"{$baseline_path}\"", $config_file_contents ); } else { $end_psalm_open_tag = strpos($config_file_contents, '>', (int)strpos($config_file_contents, '", $end_psalm_open_tag, 1 ); } else { $amended_config_file_contents = substr_replace( $config_file_contents, " errorBaseline=\"{$baseline_path}\">", $end_psalm_open_tag, 1 ); } } file_put_contents($config_file, $amended_config_file_contents); } public static function getPathToConfig(array $options): ?string { $path_to_config = isset($options['c']) && is_string($options['c']) ? realpath($options['c']) : null; if ($path_to_config === false) { fwrite(STDERR, 'Could not resolve path to config ' . (string) ($options['c'] ?? '') . PHP_EOL); exit(1); } return $path_to_config; } /** * @psalm-pure */ public static function getMemoryLimitInBytes(): int { return self::convertMemoryLimitToBytes(ini_get('memory_limit')); } /** @psalm-pure */ public static function convertMemoryLimitToBytes(string $limit): int { // for unlimited = -1 if ($limit < 0) { return -1; } if (preg_match('/^(\d+)(\D?)$/', $limit, $matches)) { assert(isset($matches[1])); $limit = (int)$matches[1]; switch (strtoupper($matches[2] ?? '')) { case 'G': $limit *= 1024 * 1024 * 1024; break; case 'M': $limit *= 1024 * 1024; break; case 'K': $limit *= 1024; break; } } return (int)$limit; } public static function initPhpVersion(array $options, Config $config, ProjectAnalyzer $project_analyzer): void { $source = null; if (isset($options['php-version'])) { if (!is_string($options['php-version'])) { die('Expecting a version number in the format x.y' . PHP_EOL); } $version = $options['php-version']; $source = 'cli'; } elseif ($version = $config->getPhpVersionFromConfig()) { $source = 'config'; } elseif ($version = $config->getPHPVersionFromComposerJson()) { $source = 'composer'; } if ($version !== null && $source !== null) { $project_analyzer->setPhpVersion($version, $source); } } public static function runningInCI(): bool { return isset($_SERVER['TRAVIS']) || isset($_SERVER['CIRCLECI']) || isset($_SERVER['APPVEYOR']) || isset($_SERVER['JENKINS_URL']) || isset($_SERVER['SCRUTINIZER']) || isset($_SERVER['GITLAB_CI']) || isset($_SERVER['GITHUB_WORKFLOW']); } }