Browse Source

Merge branch '1.12'

Conflicts:
	README.rst
	Symfony/CS/ConfigurationResolver.php
	Symfony/CS/Console/Command/FixCommand.php
	Symfony/CS/Fixer/Contrib/HeaderCommentFixer.php
Dariusz Ruminski 9 years ago
parent
commit
b0a90c2023

+ 12 - 1
README.rst

@@ -124,7 +124,7 @@ problems as possible on a given file or files in a given directory and its subdi
     php php-cs-fixer.phar fix /path/to/dir
     php php-cs-fixer.phar fix /path/to/file
 
-The ``--format`` option can be used to set the output format of the results; ``txt`` (default one), ``xml`` or ``json``.
+The ``--format`` option for the output format. Supported formats are ``txt`` (default one), ``json`` and ``xml``.
 
 The ``--verbose`` option will show the applied fixers. When using the ``txt`` format it will also displays progress notifications.
 
@@ -803,6 +803,17 @@ for PHP CS Fixer cache files and have Travis cache it between builds.
 Note: This will only trigger a build if you have a subscription for Travis
 or are using their free open source plan.
 
+Exit codes
+----------
+
+Exit code are build using following bit flags:
+
+*  0 OK
+*  4 Some files have invalid syntax (only in dry-run mode)
+*  8 Some files need fixing (only in dry-run mode)
+* 16 Configuration error of the application
+* 32 Configuration error of a Fixer
+
 Helpers
 -------
 

+ 32 - 0
Symfony/CS/ConfigurationException/InvalidConfigurationException.php

@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the PHP CS utility.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\CS\ConfigurationException;
+
+use Symfony\CS\Console\Command\FixCommand;
+
+/**
+ * Exceptions of this type are thrown on misconfiguration of the Fixer.
+ *
+ * @author SpacePossum
+ *
+ * @internal
+ */
+class InvalidConfigurationException extends \InvalidArgumentException
+{
+    /**
+     * @param string $message
+     */
+    public function __construct($message)
+    {
+        parent::__construct($message, FixCommand::EXIT_STATUS_FLAG_HAS_INVALID_CONFIG);
+    }
+}

+ 33 - 0
Symfony/CS/ConfigurationException/InvalidFixerConfigurationException.php

@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the PHP CS utility.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\CS\ConfigurationException;
+
+use Symfony\CS\Console\Command\FixCommand;
+
+/**
+ * Exception thrown by Fixers on misconfiguration.
+ *
+ * @author SpacePossum
+ *
+ * @internal
+ */
+class InvalidFixerConfigurationException extends InvalidConfigurationException
+{
+    /**
+     * @param string $fixerName
+     * @param string $message
+     */
+    public function __construct($fixerName, $message)
+    {
+        parent::__construct(sprintf('[%s] %s', $fixerName, $message), FixCommand::EXIT_STATUS_FLAG_HAS_INVALID_FIXER_CONFIG);
+    }
+}

+ 28 - 11
Symfony/CS/Console/Command/FixCommand.php

@@ -41,6 +41,8 @@ final class FixCommand extends Command
 {
     const EXIT_STATUS_FLAG_HAS_INVALID_FILES = 4;
     const EXIT_STATUS_FLAG_HAS_CHANGED_FILES = 8;
+    const EXIT_STATUS_FLAG_HAS_INVALID_CONFIG = 16;
+    const EXIT_STATUS_FLAG_HAS_INVALID_FIXER_CONFIG = 32;
 
     /**
      * EventDispatcher instance.
@@ -124,7 +126,7 @@ problems as possible on a given file or files in a given directory and its subdi
     <info>php %command.full_name% /path/to/dir</info>
     <info>php %command.full_name% /path/to/file</info>
 
-The <comment>--format</comment> option can be used to set the output format of the results; ``txt`` (default one), ``xml`` or ``json``.
+The <comment>--format</comment> option for the output format. Supported formats are ``txt`` (default one), ``json`` and ``xml``.
 
 The <comment>--verbose</comment> option will show the applied fixers. When using the ``txt`` format it will also displays progress notifications.
 
@@ -289,6 +291,17 @@ for PHP CS Fixer cache files and have Travis cache it between builds.
 
 Note: This will only trigger a build if you have a subscription for Travis
 or are using their free open source plan.
+
+Exit codes
+----------
+
+Exit code are build using following bit flags:
+
+*  0 OK
+*  4 Some files have invalid syntax (only in dry-run mode)
+*  8 Some files need fixing (only in dry-run mode)
+* 16 Configuration error of the application
+* 32 Configuration error of a Fixer
 EOF
             );
     }
@@ -298,6 +311,11 @@ EOF
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        $stdErr = ($output instanceof ConsoleOutputInterface) ? $output->getErrorOutput() : null;
+        if ($stdErr && extension_loaded('xdebug')) {
+            $stdErr->writeln(sprintf($stdErr->isDecorated() ? '<bg=yellow;fg=black;>%s</>' : '%s', 'You are running php-cs-fixer with xdebug enabled. This has a major impact on runtime performance.'));
+        }
+
         $verbosity = $output->getVerbosity();
         $resolver = new ConfigurationResolver();
         $resolver
@@ -314,6 +332,7 @@ EOF
                 'progress' => (OutputInterface::VERBOSITY_VERBOSE <= $verbosity) && 'txt' === $input->getOption('format'),
                 'using-cache' => $input->getOption('using-cache'),
                 'cache-file' => $input->getOption('cache-file'),
+                'format' => $input->getOption('format'),
             ))
             ->resolve()
         ;
@@ -335,11 +354,6 @@ EOF
             }
         }
 
-        if ($output instanceof ConsoleOutputInterface && extension_loaded('xdebug')) {
-            $stdErr = $output->getErrorOutput();
-            $stdErr->writeln(sprintf($stdErr->isDecorated() ? '<bg=yellow;fg=black;>%s</>' : '%s', 'You are running php-cs-fixer with xdebug enabled. This has a major impact on runtime performance.'));
-        }
-
         $showProgress = $resolver->getProgress();
 
         if ($showProgress) {
@@ -358,13 +372,18 @@ EOF
 
         $i = 1;
 
-        switch ($input->getOption('format')) {
+        switch ($resolver->getFormat()) {
             case 'txt':
+                $fixerDetailLine = false;
+                if (OutputInterface::VERBOSITY_VERBOSE <= $verbosity) {
+                    $fixerDetailLine = $output->isDecorated() ? ' (<comment>%s</comment>)' : ' %s';
+                }
+
                 foreach ($changed as $file => $fixResult) {
                     $output->write(sprintf('%4d) %s', $i++, $file));
 
-                    if (OutputInterface::VERBOSITY_VERBOSE <= $verbosity) {
-                        $output->write(sprintf(' (<comment>%s</comment>)', implode(', ', $fixResult['appliedFixers'])));
+                    if ($fixerDetailLine) {
+                        $output->write(sprintf($fixerDetailLine, implode(', ', $fixResult['appliedFixers'])));
                     }
 
                     if ($input->getOption('diff')) {
@@ -506,8 +525,6 @@ EOF
 
                 $output->write(json_encode($json));
                 break;
-            default:
-                throw new \InvalidArgumentException(sprintf('The format "%s" is not defined.', $input->getOption('format')));
         }
 
         $invalidErrors = $this->errorsManager->getInvalidErrors();

+ 38 - 1
Symfony/CS/Console/ConfigurationResolver.php

@@ -14,6 +14,7 @@ namespace Symfony\CS\Console;
 use Symfony\Component\Filesystem\Filesystem;
 use Symfony\CS\Config\Config;
 use Symfony\CS\ConfigInterface;
+use Symfony\CS\ConfigurationException\InvalidConfigurationException;
 use Symfony\CS\Fixer;
 use Symfony\CS\FixerFactory;
 use Symfony\CS\FixerInterface;
@@ -61,6 +62,11 @@ final class ConfigurationResolver
      */
     private $fixerFactory;
 
+    /**
+     * @var string
+     */
+    private $format;
+
     /**
      * @var bool
      */
@@ -89,6 +95,7 @@ final class ConfigurationResolver
         'config' => null,
         'config-file' => null,
         'dry-run' => null,
+        'format' => 'txt',
         'path' => null,
         'progress' => null,
         'using-cache' => null,
@@ -147,6 +154,16 @@ final class ConfigurationResolver
         return $this->fixers;
     }
 
+    /**
+     * Returns output format.
+     *
+     * @return string
+     */
+    public function getFormat()
+    {
+        return $this->format;
+    }
+
     /**
      * Returns path.
      *
@@ -197,6 +214,7 @@ final class ConfigurationResolver
         $this->resolvePath();
         $this->resolveIsStdIn();
         $this->resolveIsDryRun();
+        $this->resolveFormat();
 
         $this->resolveConfig();
         $this->resolveConfigPath();
@@ -372,7 +390,7 @@ final class ConfigurationResolver
             }
 
             if (null === $this->config) {
-                throw new \InvalidArgumentException(sprintf('The configuration "%s" is not defined.', $configOption));
+                throw new InvalidConfigurationException(sprintf('The configuration "%s" is not defined.', $configOption));
             }
         }
 
@@ -439,6 +457,25 @@ final class ConfigurationResolver
         }
     }
 
+    protected function resolveFormat()
+    {
+        static $formats = array('txt', 'xml', 'json');
+
+        if (array_key_exists('format', $this->options)) {
+            $format = $this->options['format'];
+        } elseif (method_exists($this->config, 'getFormat')) {
+            $format = $this->config->getFormat();
+        } else {
+            $format = 'txt'; // default
+        }
+
+        if (!in_array($format, $formats, true)) {
+            throw new InvalidConfigurationException(sprintf('The format "%s" is not defined, supported are %s.', $format, implode(', ', $formats)));
+        }
+
+        $this->format = $format;
+    }
+
     /**
      * Resolve isDryRun based on isStdIn property and dry-run option.
      */

+ 10 - 3
Symfony/CS/Fixer/Contrib/HeaderCommentFixer.php

@@ -12,6 +12,7 @@
 namespace Symfony\CS\Fixer\Contrib;
 
 use Symfony\CS\AbstractFixer;
+use Symfony\CS\ConfigurationException\InvalidFixerConfigurationException;
 use Symfony\CS\Tokenizer\Token;
 use Symfony\CS\Tokenizer\Tokens;
 
@@ -29,10 +30,16 @@ final class HeaderCommentFixer extends AbstractFixer
     public function configure(array $configuration = null)
     {
         if (null === $configuration || !isset($configuration['header'])) {
-            throw new \Exception('Configuration is missing.');
+            throw new InvalidFixerConfigurationException($this->getName(), 'Configuration is missing.');
         }
 
-        $this->setHeader($configuration['header']);
+        $header = $configuration['header'];
+
+        if (!is_string($header)) {
+            throw new InvalidFixerConfigurationException($this->getName(), sprintf('Header configuration is invalid. Expected "string", got "%s".', is_object($header) ? get_class($header) : gettype($header)));
+        }
+
+        $this->setHeader($header);
     }
 
     /**
@@ -168,7 +175,7 @@ final class HeaderCommentFixer extends AbstractFixer
      */
     private function setHeader($header)
     {
-        $this->header = trim((string) $header);
+        $this->header = trim($header);
         $this->headerComment = '';
 
         if ('' !== $this->header) {

+ 3 - 2
Symfony/CS/Fixer/Contrib/PhpUnitConstructFixer.php

@@ -12,6 +12,7 @@
 namespace Symfony\CS\Fixer\Contrib;
 
 use Symfony\CS\AbstractFixer;
+use Symfony\CS\ConfigurationException\InvalidFixerConfigurationException;
 use Symfony\CS\Tokenizer\Tokens;
 
 /**
@@ -43,8 +44,8 @@ final class PhpUnitConstructFixer extends AbstractFixer
         }
 
         foreach ($usingMethods as $method => $fix) {
-            if (!isset($this->configuration[$method])) {
-                throw new \InvalidArgumentException(sprintf('Configured method "%s" cannot be fixed by this fixer.', $method));
+            if (!array_key_exists($method, $this->configuration)) {
+                throw new InvalidFixerConfigurationException($this->getName(), sprintf('Configured method "%s" cannot be fixed by this fixer.', $method));
             }
 
             $this->configuration[$method] = $fix;

+ 10 - 0
Symfony/CS/Tests/Fixer/Contrib/HeaderCommentFixerTest.php

@@ -192,4 +192,14 @@ EOH;
         $input = "<?php\n";
         $this->doTest($expected, $input);
     }
+
+    /**
+     * @expectedException \Symfony\CS\ConfigurationException\InvalidFixerConfigurationException
+     * @expectedExceptionMessage [header_comment] Header configuration is invalid. Expected "string", got "stdClass".
+     */
+    public function testInvalidConfig()
+    {
+        $fixer = $this->getFixer();
+        $fixer->configure(array('header' => new \stdClass()));
+    }
 }

+ 11 - 0
Symfony/CS/Tests/Fixer/Contrib/PhpUnitConstructFixerTest.php

@@ -111,6 +111,17 @@ final class PhpUnitConstructFixerTest extends AbstractFixerTestCase
         );
     }
 
+    /**
+     * @expectedException \Symfony\CS\ConfigurationException\InvalidFixerConfigurationException
+     * @expectedExceptionMessage Configured method "__TEST__" cannot be fixed by this fixer.
+     */
+    public function testInvalidConfig()
+    {
+        /** @var PhpUnitConstructFixer $fixer */
+        $fixer = $this->getFixer();
+        $fixer->configure(array('__TEST__' => 'abc'));
+    }
+
     private function generateCases($expectedTemplate, $inputTemplate)
     {
         $cases = array();