![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/cartforge.co/vendor/rector/rector/vendor/symfony/yaml/Command/ |
<?php /* * This file is part of the Symfony package. * * (c) Fabien Potencier <[email protected]> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace RectorPrefix202410\Symfony\Component\Yaml\Command; use RectorPrefix202410\Symfony\Component\Console\Attribute\AsCommand; use RectorPrefix202410\Symfony\Component\Console\CI\GithubActionReporter; use RectorPrefix202410\Symfony\Component\Console\Command\Command; use RectorPrefix202410\Symfony\Component\Console\Completion\CompletionInput; use RectorPrefix202410\Symfony\Component\Console\Completion\CompletionSuggestions; use RectorPrefix202410\Symfony\Component\Console\Exception\InvalidArgumentException; use RectorPrefix202410\Symfony\Component\Console\Exception\RuntimeException; use RectorPrefix202410\Symfony\Component\Console\Input\InputArgument; use RectorPrefix202410\Symfony\Component\Console\Input\InputInterface; use RectorPrefix202410\Symfony\Component\Console\Input\InputOption; use RectorPrefix202410\Symfony\Component\Console\Output\OutputInterface; use RectorPrefix202410\Symfony\Component\Console\Style\SymfonyStyle; use RectorPrefix202410\Symfony\Component\Yaml\Exception\ParseException; use RectorPrefix202410\Symfony\Component\Yaml\Parser; use RectorPrefix202410\Symfony\Component\Yaml\Yaml; /** * Validates YAML files syntax and outputs encountered errors. * * @author Grégoire Pineau <[email protected]> * @author Robin Chalas <[email protected]> */ class LintCommand extends Command { /** * @var \Symfony\Component\Yaml\Parser */ private $parser; /** * @var string|null */ private $format; /** * @var bool */ private $displayCorrectFiles; /** * @var \Closure|null */ private $directoryIteratorProvider; /** * @var \Closure|null */ private $isReadableProvider; public function __construct(?string $name = null, ?callable $directoryIteratorProvider = null, ?callable $isReadableProvider = null) { parent::__construct($name); $this->directoryIteratorProvider = null === $directoryIteratorProvider ? null : \Closure::fromCallable($directoryIteratorProvider); $this->isReadableProvider = null === $isReadableProvider ? null : \Closure::fromCallable($isReadableProvider); } protected function configure() : void { $this->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')->addOption('format', null, InputOption::VALUE_REQUIRED, \sprintf('The output format ("%s")', \implode('", "', $this->getAvailableFormatOptions())))->addOption('exclude', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Path(s) to exclude')->addOption('parse-tags', null, InputOption::VALUE_NEGATABLE, 'Parse custom tags', null)->setHelp(<<<EOF The <info>%command.name%</info> command lints a YAML file and outputs to STDOUT the first encountered syntax error. You can validates YAML contents passed from STDIN: <info>cat filename | php %command.full_name% -</info> You can also validate the syntax of a file: <info>php %command.full_name% filename</info> Or of a whole directory: <info>php %command.full_name% dirname</info> <info>php %command.full_name% dirname --format=json</info> You can also exclude one or more specific files: <info>php %command.full_name% dirname --exclude="dirname/foo.yaml" --exclude="dirname/bar.yaml"</info> EOF ); } protected function execute(InputInterface $input, OutputInterface $output) : int { $io = new SymfonyStyle($input, $output); $filenames = (array) $input->getArgument('filename'); $excludes = $input->getOption('exclude'); $this->format = $input->getOption('format'); $flags = $input->getOption('parse-tags'); if (null === $this->format) { // Autodetect format according to CI environment $this->format = \class_exists(GithubActionReporter::class) && GithubActionReporter::isGithubActionEnvironment() ? 'github' : 'txt'; } $flags = $flags ? Yaml::PARSE_CUSTOM_TAGS : 0; $this->displayCorrectFiles = $output->isVerbose(); if (['-'] === $filenames) { return $this->display($io, [$this->validate(\file_get_contents('php://stdin'), $flags)]); } if (!$filenames) { throw new RuntimeException('Please provide a filename or pipe file content to STDIN.'); } $filesInfo = []; foreach ($filenames as $filename) { if (!$this->isReadable($filename)) { throw new RuntimeException(\sprintf('File or directory "%s" is not readable.', $filename)); } foreach ($this->getFiles($filename) as $file) { if (!\in_array($file->getPathname(), $excludes, \true)) { $filesInfo[] = $this->validate(\file_get_contents($file), $flags, $file); } } } return $this->display($io, $filesInfo); } private function validate(string $content, int $flags, ?string $file = null) : array { $prevErrorHandler = \set_error_handler(function ($level, $message, $file, $line) use(&$prevErrorHandler) { if (\E_USER_DEPRECATED === $level) { throw new ParseException($message, $this->getParser()->getRealCurrentLineNb() + 1); } return $prevErrorHandler ? $prevErrorHandler($level, $message, $file, $line) : \false; }); try { $this->getParser()->parse($content, Yaml::PARSE_CONSTANT | $flags); } catch (ParseException $e) { return ['file' => $file, 'line' => $e->getParsedLine(), 'valid' => \false, 'message' => $e->getMessage()]; } finally { \restore_error_handler(); } return ['file' => $file, 'valid' => \true]; } private function display(SymfonyStyle $io, array $files) : int { switch ($this->format) { case 'txt': return $this->displayTxt($io, $files); case 'json': return $this->displayJson($io, $files); case 'github': return $this->displayTxt($io, $files, \true); default: throw new InvalidArgumentException(\sprintf('Supported formats are "%s".', \implode('", "', $this->getAvailableFormatOptions()))); } } private function displayTxt(SymfonyStyle $io, array $filesInfo, bool $errorAsGithubAnnotations = \false) : int { $countFiles = \count($filesInfo); $erroredFiles = 0; $suggestTagOption = \false; if ($errorAsGithubAnnotations) { $githubReporter = new GithubActionReporter($io); } foreach ($filesInfo as $info) { if ($info['valid'] && $this->displayCorrectFiles) { $io->comment('<info>OK</info>' . ($info['file'] ? \sprintf(' in %s', $info['file']) : '')); } elseif (!$info['valid']) { ++$erroredFiles; $io->text('<error> ERROR </error>' . ($info['file'] ? \sprintf(' in %s', $info['file']) : '')); $io->text(\sprintf('<error> >> %s</error>', $info['message'])); if (\strpos($info['message'], 'PARSE_CUSTOM_TAGS') !== \false) { $suggestTagOption = \true; } if ($errorAsGithubAnnotations) { $githubReporter->error($info['message'], $info['file'] ?? 'php://stdin', $info['line']); } } } if (0 === $erroredFiles) { $io->success(\sprintf('All %d YAML files contain valid syntax.', $countFiles)); } else { $io->warning(\sprintf('%d YAML files have valid syntax and %d contain errors.%s', $countFiles - $erroredFiles, $erroredFiles, $suggestTagOption ? ' Use the --parse-tags option if you want parse custom tags.' : '')); } return \min($erroredFiles, 1); } private function displayJson(SymfonyStyle $io, array $filesInfo) : int { $errors = 0; \array_walk($filesInfo, function (&$v) use(&$errors) { $v['file'] = (string) $v['file']; if (!$v['valid']) { ++$errors; } if (isset($v['message']) && \strpos($v['message'], 'PARSE_CUSTOM_TAGS') !== \false) { $v['message'] .= ' Use the --parse-tags option if you want parse custom tags.'; } }); $io->writeln(\json_encode($filesInfo, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES)); return \min($errors, 1); } private function getFiles(string $fileOrDirectory) : iterable { if (\is_file($fileOrDirectory)) { (yield new \SplFileInfo($fileOrDirectory)); return; } foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) { if (!\in_array($file->getExtension(), ['yml', 'yaml'])) { continue; } (yield $file); } } private function getParser() : Parser { return $this->parser = $this->parser ?? new Parser(); } private function getDirectoryIterator(string $directory) : iterable { $default = function ($directory) { return new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS), \RecursiveIteratorIterator::LEAVES_ONLY); }; if (null !== $this->directoryIteratorProvider) { return ($this->directoryIteratorProvider)($directory, $default); } return $default($directory); } private function isReadable(string $fileOrDirectory) : bool { $default = \Closure::fromCallable('is_readable'); if (null !== $this->isReadableProvider) { return ($this->isReadableProvider)($fileOrDirectory, $default); } return $default($fileOrDirectory); } public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void { if ($input->mustSuggestOptionValuesFor('format')) { $suggestions->suggestValues($this->getAvailableFormatOptions()); } } private function getAvailableFormatOptions() : array { return ['txt', 'json', 'github']; } }