Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

LintCommand.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 7.74 KiB


001  <?php
002   
003  /*
004   * This file is part of the Symfony package.
005   *
006   * (c) Fabien Potencier <fabien@symfony.com>
007   *
008   * For the full copyright and license information, please view the LICENSE
009   * file that was distributed with this source code.
010   */
011   
012  namespace Symfony\Component\Yaml\Command;
013   
014  use Symfony\Component\Console\Command\Command;
015  use Symfony\Component\Console\Exception\InvalidArgumentException;
016  use Symfony\Component\Console\Exception\RuntimeException;
017  use Symfony\Component\Console\Input\InputInterface;
018  use Symfony\Component\Console\Input\InputOption;
019  use Symfony\Component\Console\Output\OutputInterface;
020  use Symfony\Component\Console\Style\SymfonyStyle;
021  use Symfony\Component\Yaml\Exception\ParseException;
022  use Symfony\Component\Yaml\Parser;
023  use Symfony\Component\Yaml\Yaml;
024   
025  /**
026   * Validates YAML files syntax and outputs encountered errors.
027   *
028   * @author Grégoire Pineau <lyrixx@lyrixx.info>
029   * @author Robin Chalas <robin.chalas@gmail.com>
030   */
031  class LintCommand extends Command
032  {
033      protected static $defaultName = 'lint:yaml';
034   
035      private $parser;
036      private $format;
037      private $displayCorrectFiles;
038      private $directoryIteratorProvider;
039      private $isReadableProvider;
040   
041      public function __construct($name = null, $directoryIteratorProvider = null, $isReadableProvider = null)
042      {
043          parent::__construct($name);
044   
045          $this->directoryIteratorProvider = $directoryIteratorProvider;
046          $this->isReadableProvider = $isReadableProvider;
047      }
048   
049      /**
050       * {@inheritdoc}
051       */
052      protected function configure()
053      {
054          $this
055              ->setDescription('Lints a file and outputs encountered errors')
056              ->addArgument('filename', null, 'A file or a directory or STDIN')
057              ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
058              ->addOption('parse-tags', null, InputOption::VALUE_NONE, 'Parse custom tags')
059              ->setHelp(<<<EOF
060  The <info>%command.name%</info> command lints a YAML file and outputs to STDOUT
061  the first encountered syntax error.
062   
063  You can validates YAML contents passed from STDIN:
064   
065    <info>cat filename | php %command.full_name%</info>
066   
067  You can also validate the syntax of a file:
068   
069    <info>php %command.full_name% filename</info>
070   
071  Or of a whole directory:
072   
073    <info>php %command.full_name% dirname</info>
074    <info>php %command.full_name% dirname --format=json</info>
075   
076  EOF
077              )
078          ;
079      }
080   
081      protected function execute(InputInterface $input, OutputInterface $output)
082      {
083          $io = new SymfonyStyle($input, $output);
084          $filename = $input->getArgument('filename');
085          $this->format = $input->getOption('format');
086          $this->displayCorrectFiles = $output->isVerbose();
087          $flags = $input->getOption('parse-tags') ? Yaml::PARSE_CUSTOM_TAGS : 0;
088   
089          if (!$filename) {
090              if (!$stdin = $this->getStdin()) {
091                  throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
092              }
093   
094              return $this->display($io, [$this->validate($stdin, $flags)]);
095          }
096   
097          if (!$this->isReadable($filename)) {
098              throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename));
099          }
100   
101          $filesInfo = [];
102          foreach ($this->getFiles($filename) as $file) {
103              $filesInfo[] = $this->validate(file_get_contents($file), $flags, $file);
104          }
105   
106          return $this->display($io, $filesInfo);
107      }
108   
109      private function validate($content, $flags, $file = null)
110      {
111          $prevErrorHandler = set_error_handler(function ($level, $message, $file, $line) use (&$prevErrorHandler) {
112              if (\E_USER_DEPRECATED === $level) {
113                  throw new ParseException($message, $this->getParser()->getRealCurrentLineNb() + 1);
114              }
115   
116              return $prevErrorHandler ? $prevErrorHandler($level, $message, $file, $line) : false;
117          });
118   
119          try {
120              $this->getParser()->parse($content, Yaml::PARSE_CONSTANT | $flags);
121          } catch (ParseException $e) {
122              return ['file' => $file, 'line' => $e->getParsedLine(), 'valid' => false, 'message' => $e->getMessage()];
123          } finally {
124              restore_error_handler();
125          }
126   
127          return ['file' => $file, 'valid' => true];
128      }
129   
130      private function display(SymfonyStyle $io, array $files)
131      {
132          switch ($this->format) {
133              case 'txt':
134                  return $this->displayTxt($io, $files);
135              case 'json':
136                  return $this->displayJson($io, $files);
137              default:
138                  throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format));
139          }
140      }
141   
142      private function displayTxt(SymfonyStyle $io, array $filesInfo)
143      {
144          $countFiles = \count($filesInfo);
145          $erroredFiles = 0;
146   
147          foreach ($filesInfo as $info) {
148              if ($info['valid'] && $this->displayCorrectFiles) {
149                  $io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
150              } elseif (!$info['valid']) {
151                  ++$erroredFiles;
152                  $io->text('<error> ERROR </error>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
153                  $io->text(sprintf('<error> >> %s</error>', $info['message']));
154              }
155          }
156   
157          if (0 === $erroredFiles) {
158              $io->success(sprintf('All %d YAML files contain valid syntax.', $countFiles));
159          } else {
160              $io->warning(sprintf('%d YAML files have valid syntax and %d contain errors.', $countFiles - $erroredFiles, $erroredFiles));
161          }
162   
163          return min($erroredFiles, 1);
164      }
165   
166      private function displayJson(SymfonyStyle $io, array $filesInfo)
167      {
168          $errors = 0;
169   
170          array_walk($filesInfo, function (&$v) use (&$errors) {
171              $v['file'] = (string) $v['file'];
172              if (!$v['valid']) {
173                  ++$errors;
174              }
175          });
176   
177          $io->writeln(json_encode($filesInfo, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES));
178   
179          return min($errors, 1);
180      }
181   
182      private function getFiles($fileOrDirectory)
183      {
184          if (is_file($fileOrDirectory)) {
185              yield new \SplFileInfo($fileOrDirectory);
186   
187              return;
188          }
189   
190          foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) {
191              if (!\in_array($file->getExtension(), ['yml', 'yaml'])) {
192                  continue;
193              }
194   
195              yield $file;
196          }
197      }
198   
199      /**
200       * @return string|null
201       */
202      private function getStdin()
203      {
204          if (0 !== ftell(\STDIN)) {
205              return null;
206          }
207   
208          $inputs = '';
209          while (!feof(\STDIN)) {
210              $inputs .= fread(\STDIN, 1024);
211          }
212   
213          return $inputs;
214      }
215   
216      private function getParser()
217      {
218          if (!$this->parser) {
219              $this->parser = new Parser();
220          }
221   
222          return $this->parser;
223      }
224   
225      private function getDirectoryIterator($directory)
226      {
227          $default = function ($directory) {
228              return new \RecursiveIteratorIterator(
229                  new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
230                  \RecursiveIteratorIterator::LEAVES_ONLY
231              );
232          };
233   
234          if (null !== $this->directoryIteratorProvider) {
235              return \call_user_func($this->directoryIteratorProvider, $directory, $default);
236          }
237   
238          return $default($directory);
239      }
240   
241      private function isReadable($fileOrDirectory)
242      {
243          $default = function ($fileOrDirectory) {
244              return is_readable($fileOrDirectory);
245          };
246   
247          if (null !== $this->isReadableProvider) {
248              return \call_user_func($this->isReadableProvider, $fileOrDirectory, $default);
249          }
250   
251          return $default($fileOrDirectory);
252      }
253  }
254