Browse Source

Merge branch 'master' into 3.0

Dariusz Ruminski 3 years ago
parent
commit
5c755cde70

+ 32 - 0
doc/usage.rst

@@ -2,6 +2,9 @@
 Usage
 =====
 
+The ``fix`` command
+-------------------
+
 The ``fix`` command tries to fix as much coding standards
 problems as possible on a given file or files in a given directory and its subdirectories:
 
@@ -113,6 +116,35 @@ fixed but without actually modifying them:
 By using ``--using-cache`` option with ``yes`` or ``no`` you can set if the caching
 mechanism should be used.
 
+The ``list-files`` command
+--------------------------
+
+The ``list-files`` command will list all files which need fixing.
+
+.. code-block:: console
+
+    $ php php-cs-fixer.phar list-files
+
+The ``--config`` option can be used, like in the ``fix`` command, to tell from which path a config file should be loaded.
+
+.. code-block:: console
+
+    $ php php-cs-fixer.phar list-files --config=.php-cs-fixer.dist.php
+
+The output is build in a form that its easy to use in combination with ``xargs`` command in a linux pipe.
+This can be useful e.g. in situations where the caching might mechanism not available (CI, Docker) and distributing
+fixing across several processes might speedup the process.
+
+Note: You need to pass the config to the ``fix`` command, in order to make it work with several files being passed by ``list-files``.
+
+.. code-block:: console
+
+    $ php php-cs-fixer.phar list-files --config=.php-cs-fixer.dist.php | xargs -n 10 -P 8 php php-cs-fixer.phar fix --config=.php-cs-fixer.dist.php --path-mode intersection -v
+
+* `-n` defines how many files a single subprocess process
+* `-P` defines how many subprocesses the shell is allowed to spawn for parallel processing (usually similar to the number of CPUs your system has)
+
+
 Rule descriptions
 -----------------
 

+ 3 - 0
src/Console/Application.php

@@ -17,6 +17,7 @@ namespace PhpCsFixer\Console;
 use PhpCsFixer\Console\Command\DescribeCommand;
 use PhpCsFixer\Console\Command\FixCommand;
 use PhpCsFixer\Console\Command\HelpCommand;
+use PhpCsFixer\Console\Command\ListFilesCommand;
 use PhpCsFixer\Console\Command\SelfUpdateCommand;
 use PhpCsFixer\Console\SelfUpdate\GithubClient;
 use PhpCsFixer\Console\SelfUpdate\NewVersionChecker;
@@ -50,8 +51,10 @@ final class Application extends BaseApplication
 
         $this->toolInfo = new ToolInfo();
 
+        // in alphabetical order
         $this->add(new DescribeCommand());
         $this->add(new FixCommand($this->toolInfo));
+        $this->add(new ListFilesCommand($this->toolInfo));
         $this->add(new SelfUpdateCommand(
             new NewVersionChecker(new GithubClient()),
             $this->toolInfo,

+ 98 - 0
src/Console/Command/ListFilesCommand.php

@@ -0,0 +1,98 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer\Console\Command;
+
+use PhpCsFixer\Config;
+use PhpCsFixer\ConfigInterface;
+use PhpCsFixer\Console\ConfigurationResolver;
+use PhpCsFixer\ToolInfoInterface;
+use SplFileInfo;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * @author Markus Staab <markus.staab@redaxo.org>
+ *
+ * @internal
+ */
+final class ListFilesCommand extends Command
+{
+    protected static $defaultName = 'list-files';
+
+    /**
+     * @var ConfigInterface
+     */
+    private $defaultConfig;
+
+    /**
+     * @var ToolInfoInterface
+     */
+    private $toolInfo;
+
+    public function __construct(ToolInfoInterface $toolInfo)
+    {
+        parent::__construct();
+
+        $this->defaultConfig = new Config();
+        $this->toolInfo = $toolInfo;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure(): void
+    {
+        $this
+            ->setDefinition(
+                [
+                    new InputOption('config', '', InputOption::VALUE_REQUIRED, 'The path to a .php-cs-fixer.php file.'),
+                ]
+            )
+            ->setDescription('List all files being fixed by the given config.')
+        ;
+    }
+
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $passedConfig = $input->getOption('config');
+        $cwd = getcwd();
+
+        $resolver = new ConfigurationResolver(
+            $this->defaultConfig,
+            [
+                'config' => $passedConfig,
+            ],
+            getcwd(),
+            $this->toolInfo
+        );
+
+        $finder = $resolver->getFinder();
+
+        /** @var SplFileInfo $file */
+        foreach ($finder as $file) {
+            if ($file->isFile()) {
+                $relativePath = str_replace($cwd, '.', $file->getRealPath());
+                // unify directory separators across operating system
+                $relativePath = str_replace('/', \DIRECTORY_SEPARATOR, $relativePath);
+
+                $output->writeln(escapeshellarg($relativePath));
+            }
+        }
+
+        return 0;
+    }
+}

+ 55 - 0
tests/Console/Command/ListFilesCommandTest.php

@@ -0,0 +1,55 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of PHP CS Fixer.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace PhpCsFixer\Tests\Console\Command;
+
+use PhpCsFixer\Console\Application;
+use PhpCsFixer\Console\Command\ListFilesCommand;
+use PhpCsFixer\Tests\TestCase;
+use PhpCsFixer\ToolInfo;
+use Symfony\Component\Console\Tester\CommandTester;
+
+/**
+ * @internal
+ *
+ * @covers \PhpCsFixer\Console\Command\ListFilesCommand
+ */
+final class ListFilesCommandTest extends TestCase
+{
+    public function testListWithConfig(): void
+    {
+        $commandTester = $this->doTestExecute([
+            '--config' => __DIR__.'/../../Fixtures/ListFilesTest/.php-cs-fixer.php',
+        ]);
+
+        $expectedPath = './tests/Fixtures/ListFilesTest/needs-fixing/needs-fixing.php';
+        // make the test also work on windows
+        $expectedPath = str_replace('/', \DIRECTORY_SEPARATOR, $expectedPath);
+
+        static::assertSame(escapeshellarg($expectedPath).PHP_EOL, $commandTester->getDisplay());
+    }
+
+    private function doTestExecute(array $arguments): CommandTester
+    {
+        $application = new Application();
+        $application->add(new ListFilesCommand(new ToolInfo()));
+
+        $command = $application->find('list-files');
+        $commandTester = new CommandTester($command);
+
+        $commandTester->execute($arguments);
+
+        return $commandTester;
+    }
+}

+ 20 - 0
tests/Fixtures/ListFilesTest/.php-cs-fixer.php

@@ -0,0 +1,20 @@
+<?php
+
+$finder = PhpCsFixer\Finder::create()
+    ->in([
+        __DIR__.'/needs-fixing/',
+    ])
+    ->exclude([
+        __DIR__.'/excluded/',
+    ])
+;
+
+$config = new PhpCsFixer\Config();
+return $config
+    ->setUsingCache(false)
+    ->setRules([
+        '@Symfony' => true,
+    ])
+    ->setRiskyAllowed(true)
+    ->setFinder($finder)
+    ;

+ 8 - 0
tests/Fixtures/ListFilesTest/excluded/needs-fixing.php

@@ -0,0 +1,8 @@
+<?php
+
+function abc() {}
+
+function def()
+{
+
+}

+ 8 - 0
tests/Fixtures/ListFilesTest/needs-fixing/needs-fixing.php

@@ -0,0 +1,8 @@
+<?php
+
+function abc() {}
+
+function def()
+{
+
+}