Browse Source

bug: ListFilesCommand - fix computing of relative path (#7028)

John Paul E. Balandan, CPA 1 year ago
parent
commit
ce0b66b10c

+ 2 - 1
src/Console/Command/ListFilesCommand.php

@@ -23,6 +23,7 @@ use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Filesystem\Path;
 
 /**
  * @author Markus Staab <markus.staab@redaxo.org>
@@ -80,7 +81,7 @@ final class ListFilesCommand extends Command
         /** @var \SplFileInfo $file */
         foreach ($finder as $file) {
             if ($file->isFile()) {
-                $relativePath = str_replace($cwd, '.', $file->getRealPath());
+                $relativePath = './'.Path::makeRelative($file->getRealPath(), $cwd);
                 // unify directory separators across operating system
                 $relativePath = str_replace('/', \DIRECTORY_SEPARATOR, $relativePath);
 

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

@@ -19,6 +19,8 @@ use PhpCsFixer\Console\Command\ListFilesCommand;
 use PhpCsFixer\Tests\TestCase;
 use PhpCsFixer\ToolInfo;
 use Symfony\Component\Console\Tester\CommandTester;
+use Symfony\Component\Filesystem\Filesystem;
+use Symfony\Component\Filesystem\Path;
 
 /**
  * @internal
@@ -27,6 +29,18 @@ use Symfony\Component\Console\Tester\CommandTester;
  */
 final class ListFilesCommandTest extends TestCase
 {
+    private static ?Filesystem $filesystem;
+
+    public static function setUpBeforeClass(): void
+    {
+        self::$filesystem = new Filesystem();
+    }
+
+    public static function tearDownAfterClass(): void
+    {
+        self::$filesystem = null;
+    }
+
     public function testListWithConfig(): void
     {
         $commandTester = $this->doTestExecute([
@@ -41,6 +55,32 @@ final class ListFilesCommandTest extends TestCase
         self::assertSame(escapeshellarg($expectedPath).PHP_EOL, $commandTester->getDisplay());
     }
 
+    /**
+     * @requires OS Linux|Darwin
+     *
+     * Skip test on Windows as `getcwd()` includes the drive letter with a colon `:` which is illegal in filenames.
+     */
+    public function testListFilesDoesNotCorruptListWithGetcwdInName(): void
+    {
+        try {
+            $tmpDir = __DIR__.'/../../Fixtures/ListFilesTest/using-getcwd';
+            $tmpFile = $tmpDir.'/'.ltrim(getcwd(), '/').'-out.php';
+            self::$filesystem->dumpFile($tmpFile, '<?php function a() {  }');
+
+            $tmpFile = realpath($tmpFile);
+            self::assertFileExists($tmpFile);
+
+            $commandTester = $this->doTestExecute([
+                '--config' => __DIR__.'/../../Fixtures/ListFilesTest/.php-cs-fixer.using-getcwd.php',
+            ]);
+            $expectedPath = str_replace('/', \DIRECTORY_SEPARATOR, './'.Path::makeRelative($tmpFile, getcwd()));
+            self::assertSame(0, $commandTester->getStatusCode());
+            self::assertSame(escapeshellarg($expectedPath).PHP_EOL, $commandTester->getDisplay());
+        } finally {
+            self::$filesystem->remove($tmpDir);
+        }
+    }
+
     /**
      * @param array<string, bool|string> $arguments
      */

+ 8 - 0
tests/Fixtures/ListFilesTest/.php-cs-fixer.using-getcwd.php

@@ -0,0 +1,8 @@
+<?php
+
+/** @var PhpCsFixer\Config $config */
+$config = require __DIR__.'/.php-cs-fixer.php';
+
+return $config
+    ->setFinder((new PhpCsFixer\Finder())->in([__DIR__.'/using-getcwd']))
+;