-
-
Notifications
You must be signed in to change notification settings - Fork 268
Description
Describe the bug
Cannot override CLI executable with a local copy of any of PHP Linters
Don't be afraid of this long report, I'll provide a PR to fix the problem soon. TL;DR only if you want to know more about such kind of issue.
To Reproduce
Steps to reproduce the behavior:
- Retrieve a repository that may install PHP Linters as dev tools locally; For example https://github.com/llaville/php-compatinfo-db (master branch)
- Run
composer install
to install standard project dependencies - Run
composer bin all install
to install all other dev tools locally on this project - Or just install PHPStan for demo purpose (to issue concept), That's mean run :
composer bin phpstan install
- Run the PHP Flavor with official Docker image :
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock:rw -v $(pwd):/tmp/lint:rw -e LOG_LEVEL=debug -e PARALLEL=false ghcr.io/oxsecurity/megalinter-php:v9.0.1
NB: I've enabled debug mode to see additional message that will help to show problems found, and disabled parallel mode to have log grouped by linters.
Expected behavior
All linters should run without found any errors, especially PHPStan if we run local version installed (with command composer bin phpstan install
)
Something like this :

Additional context
PHPStan installed with MegaLinter (9.0.1) is detailed at https://github.com/oxsecurity/megalinter/blob/v9.0.1/megalinter/descriptors/php.megalinter-descriptor.yml#L130-L140
On my project to have none errors found by MegaLinter, I should have an extra PHPStan extension, see https://github.com/llaville/php-compatinfo-db/blob/master/vendor-bin/phpstan/composer.json#L5
So, on my first approach, I though I could override CLI executable in MegaLinter config file like this
PHP_PHPSTAN_CLI_EXECUTABLE: "vendor/bin/phpstan"
, see llaville/php-compatinfo-db@4b0a09d
But PATH defined does not lookup into /tmp/lint
volume (mounted on docker run), and more than that explains are given by doc itself at https://docs.python.org/3/library/shutil.html#shutil.which
If cmd contains a directory component, which() only checks the specified path directly and does not search the directories listed in path or in the system’s PATH environment variable.
So I got this output
❌ Linted [PHP] files with [phpstan]: Found 1 error(s) and 0 warning(s) - (0.0s)
- Using [phpstan vERROR] https://megalinter.io/9.0.1/descriptors/php_phpstan
- MegaLinter key: [PHP_PHPSTAN]
- Rules config: [/.github/linters/phpstan.neon.dist]
- Command: [vendor/bin/phpstan analyse --no-progress --no-ansi --memory-limit 1G -c /tmp/lint/.github/linters/phpstan.neon.dist]
--Error detail:
Fatal error while calling phpstan: [Errno 2] No such file or directory: 'vendor/bin/phpstan'
The solution is given by this little patch
diff --git a/megalinter/Linter.py b/megalinter/Linter.py
index 0cfcf481d8..162bec5728 100644
--- a/megalinter/Linter.py
+++ b/megalinter/Linter.py
@@ -974,7 +974,7 @@ class Linter:
try:
reporter.produce_report()
except Exception as e:
- logging.error("Unable to process reporter " + reporter.name + str(e))
+ logging.error("Unable to process reporter " + reporter.name + " " + str(e))
return self
@@ -1657,6 +1657,8 @@ class Linter:
cli_absolute = shutil.which(cmd[0])
if cli_absolute is not None:
cmd[0] = cli_absolute
+ cmd_resolved = " ".join(str(element) for element in cmd)
+ logging.debug("Linter version command resolved: " + cmd_resolved)
cmd += self.cli_version_extra_args
if self.cli_version_arg_name != "":
cmd += [self.cli_version_arg_name]
First logging error to avoid collapsed message like Unable to process reporter CONSOLEcan only concatenate str (not "list") to str
(space missing between reporter name CONSOLE and exception message
Second logging to debug how linter is resolved by shutil.which
BUT to solve my situation context, we should only fix the PATH definition to allow local linter first
diff --git a/megalinter/descriptors/php.megalinter-descriptor.yml b/megalinter/descriptors/php.megalinter-descriptor.yml
index 2fcf4fb5bb..b327a684ac 100644
--- a/megalinter/descriptors/php.megalinter-descriptor.yml
+++ b/megalinter/descriptors/php.megalinter-descriptor.yml
@@ -25,7 +25,7 @@ install:
dockerfile:
- RUN update-alternatives --install /usr/bin/php php /usr/bin/php84 110
- COPY --from=composer/composer:2-bin /composer /usr/bin/composer
- - ENV PATH="/root/.composer/vendor/bin:${PATH}"
+ - ENV PATH="/tmp/lint/vendor/bin:/root/.composer/vendor/bin:${PATH}"
linters:
# PHPCS
- linter_name: phpcs