From 4d76194685566b07c87c7db642ac0b9bab9a9ef5 Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Mon, 11 Sep 2023 08:53:48 +0200 Subject: [PATCH] Enable phpcs and phpcbf checks to run from phar We need the 2 CLI scripts and the CodeSniffer.conf file to be added to the phar, so we can "include" the scripts for execution and copy the conf file temporarily to be together with the phar (that's the way CodeSniffer expects it). Note this will reduce a little bit code-coverage but in a future PR I want to add some integration tests to cover the execution from phar, hardly can be done from unit tests. --- box.json | 8 ++++++++ docs/CHANGELOG.md | 1 + src/Command/CodeCheckerCommand.php | 30 ++++++++++++++++++++++++++--- src/Command/CodeFixerCommand.php | 31 +++++++++++++++++++++++++++--- 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/box.json b/box.json index 624ee131..4d0e220c 100644 --- a/box.json +++ b/box.json @@ -36,6 +36,14 @@ "Docs", "pix" ] + }, + { + "in": "vendor/squizlabs/php_codesniffer", + "name": [ + "phpcs", + "phpcbf", + "CodeSniffer.conf" + ] } ], "compactors": "KevinGH\\Box\\Compactor\\Php", diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 8b62d0f4..566ed1b0 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -11,6 +11,7 @@ The format of this change log follows the advice given at [Keep a CHANGELOG](htt ## [Unreleased] ### Fixed - Fix the `mustache` command to work from within the PHAR archive. +- Fix the `phpcs` and `phpcbf` commands to work from within the PHAR archive. ## [4.1.3] - 2023-09-08 ### Changed diff --git a/src/Command/CodeCheckerCommand.php b/src/Command/CodeCheckerCommand.php index 8fc34fdb..51804f6a 100644 --- a/src/Command/CodeCheckerCommand.php +++ b/src/Command/CodeCheckerCommand.php @@ -61,8 +61,23 @@ protected function execute(InputInterface $input, OutputInterface $output): int return $this->outputSkip($output); } - $cmd = [ - 'php', __DIR__ . '/../../vendor/squizlabs/php_codesniffer/bin/phpcs', + $filesystem = new Filesystem(); + $pathToPHPCS = __DIR__ . '/../../vendor/squizlabs/php_codesniffer/bin/phpcs'; + $pathToConf = __DIR__ . '/../../vendor/squizlabs/php_codesniffer/CodeSniffer.conf'; + $basicCMD = ['php', $pathToPHPCS]; + // If we are running phpcs within a PHAR, the command is different, and we need also to copy the .conf file. + // @codeCoverageIgnoreStart + // (This is not executed when running tests, only when within a PHAR) + if (\Phar::running() !== '') { + // Invoke phpcs from the PHAR (via include, own params after --). + $basicCMD = ['php', '-r', 'include "' . $pathToPHPCS . '";', '--']; + // Copy the .conf file to the directory where the PHAR is running. That way phpcs will find it. + $targetPathToConf = dirname(\Phar::running(false)) . '/CodeSniffer.conf'; + $filesystem->copy($pathToConf, $targetPathToConf, true); + } + // @codeCoverageIgnoreEnd + + $cmd = array_merge($basicCMD, [ '--standard=' . ($input->getOption('standard') ?: 'moodle'), '--extensions=php', '-p', @@ -73,7 +88,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int '--report-full', '--report-width=132', '--encoding=utf-8', - ]; + ]); // If we aren't using the max-warnings option, then we can forget about warnings and tell phpcs // to ignore them for exit-code purposes (still they will be reported in the output). @@ -98,6 +113,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int $process = $this->execute->passThroughProcess(new Process($cmd, $this->plugin->directory, null, null, null)); + // If we are running phpcs within a PHAR, we need to remove the previously copied conf file. + // @codeCoverageIgnoreStart + // (This is not executed when running tests, only when within a PHAR) + if (\Phar::running() !== '') { + $targetPathToConf = dirname(\Phar::running(false)) . '/CodeSniffer.conf'; + $filesystem->remove($targetPathToConf); + } + // @codeCoverageIgnoreEnd + // If we aren't using the max-warnings option, process exit code is enough for us. if ($input->getOption('max-warnings') < 0) { return $process->isSuccessful() ? 0 : 1; diff --git a/src/Command/CodeFixerCommand.php b/src/Command/CodeFixerCommand.php index 0b0da88e..306cfe42 100644 --- a/src/Command/CodeFixerCommand.php +++ b/src/Command/CodeFixerCommand.php @@ -15,6 +15,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; use Symfony\Component\Process\Process; @@ -42,8 +43,23 @@ protected function execute(InputInterface $input, OutputInterface $output): int return $this->outputSkip($output); } - $cmd = [ - 'php', __DIR__ . '/../../vendor/squizlabs/php_codesniffer/bin/phpcbf', + $filesystem = new Filesystem(); + $pathToPHPCBF = __DIR__ . '/../../vendor/squizlabs/php_codesniffer/bin/phpcbf'; + $pathToConf = __DIR__ . '/../../vendor/squizlabs/php_codesniffer/CodeSniffer.conf'; + $basicCMD = ['php', $pathToPHPCBF]; + // If we are running phpcs within a PHAR, the command is different, and we need also to copy the .conf file. + // @codeCoverageIgnoreStart + // (This is not executed when running tests, only when within a PHAR) + if (\Phar::running() !== '') { + // Invoke phpcbf from the PHAR (via include, own params after --). + $basicCMD = ['php', '-r', 'include "' . $pathToPHPCBF . '";', '--']; + // Copy the .conf file to the directory where the PHAR is running. That way phpcbf will find it. + $targetPathToConf = dirname(\Phar::running(false)) . '/CodeSniffer.conf'; + $filesystem->copy($pathToConf, $targetPathToConf, true); + } + // @codeCoverageIgnoreEnd + + $cmd = array_merge($basicCMD, [ '--standard=' . ($input->getOption('standard') ?: 'moodle'), '--extensions=php', '-p', @@ -54,7 +70,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int '--report-full', '--report-width=132', '--encoding=utf-8', - ]; + ]); // Add the files to process. foreach ($files as $file) { @@ -63,6 +79,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->execute->passThroughProcess(new Process($cmd, $this->plugin->directory, null, null, null)); + // If we are running phpcbf within a PHAR, we need to remove the previously copied conf file. + // @codeCoverageIgnoreStart + // (This is not executed when running tests, only when within a PHAR) + if (\Phar::running() !== '') { + $targetPathToConf = dirname(\Phar::running(false)) . '/CodeSniffer.conf'; + $filesystem->remove($targetPathToConf); + } + // @codeCoverageIgnoreEnd + return 0; } }