overtrue / phplint

:bug: A tool that can speed up linting of php files by running several lint processes at once.
MIT License
988 stars 88 forks source link

[9.0.0] Enhance Cache support for Windows platform #176

Closed knallcharge closed 1 year ago

knallcharge commented 1 year ago

New Issue

Diagnose

Using version 9.0.0 via composer, upgraded from 5.5. Running on Windows with XAMPP.

Summary

When starting phplint, I get the error: "Cache key "C:\full\path(...)\Some.php" contains reserved characters "{}()/\@:"." where the cache key is the complete path to the first file being checked.

Expected behaviour

phplint should not issue an error and cache results (as in v5.5).

Actual behaviour

phplint issues an error when using cache. Using the --no-cache-flag runs fine.

llaville commented 1 year ago

Did you check Open-Source Code ? if answer is yes, please specify URL of repository

knallcharge commented 1 year ago

No, I was checking a private project which is not available to the public.

llaville commented 1 year ago

As it seems you are checking files on Windows, could you at least specify directories tree with command tree /A on windows prompt

knallcharge commented 1 year ago

I'm only checking src and tests with phplint, this is the src-folder with "tree /A"

+---Command
+---Controller
+---Core
+---Datatables
+---Entity
+---Exception
+---Form
|   \---Extension
+---Repository
+---Security
+---Service
+---Twig
\---Util

and this is tests

+---Controller
+---Entity
+---Form
+---Repository
\---Service
llaville commented 1 year ago

There are no special characters on your directories, probably it's one of the files you are checking that have special char.

Could you identify it, when you it with the progress (printer by default) output ?

Don't forget to specify verbose level max -vvv that will gave us a backtrace of last steps executed too !

knallcharge commented 1 year ago

Thanks for getting back! This is the command I'm now executing: vendor\bin\phplint -c build\phplint.yml --progress=printer -vvv My phplint.yml is this:

path:
    - src
    - tests
jobs: 10
cache: build/phplint.cache
extensions:
    - php

The output I'm getting from the above command is this:

phplint 9.0.0 by overtrue and contributors.

Runtime       : PHP 8.1.10
Configuration : C:\xampp\htdocs_my-project\my-project\build\phplint.yml

┌──────────────────┬───────────────────────┬─────────┐
│ Name             │ Value                 │ Help    │
├──────────────────┼───────────────────────┼─────────┤
│ path             │ ["src","tests"]       │ command │
├──────────────────┼───────────────────────┼─────────┤
│ configuration    │ "build\\phplint.yml"  │ command │
│ no-configuration │ false                 │ command │
│ exclude          │ []                    │ command │
│ extensions       │ ["php"]               │ command │
│ jobs             │ 10                    │ command │
│ no-cache         │ false                 │ command │
│ cache            │ "build/phplint.cache" │ command │
│ no-progress      │ false                 │ command │
│ progress         │ "printer"             │ command │
│ log-json         │ null                  │ command │
│ log-junit        │ null                  │ command │
│ warning          │ false                 │ command │
│ memory-limit     │ "4G"                  │ command │
│ ignore-exit-code │ false                 │ command │
└──────────────────┴───────────────────────┴─────────┘

In CacheItem.php line 139:

  [Symfony\Component\Cache\Exception\InvalidArgumentException]
  Cache key "C:\xampp\htdocs_my-project\my-project\src\Command\CheckCommand.php" contains reserved characters "{}()/\@:".

Exception trace:
  at C:\xampp\htdocs_my-project\my-project\vendor\symfony\cache\CacheItem.php:139
 Symfony\Component\Cache\CacheItem::validateKey() at C:\xampp\htdocs_my-project\my-project\vendor\symfony\cache\Traits\AbstractAdapterTrait.php:345
 Symfony\Component\Cache\Adapter\AbstractAdapter->getId() at C:\xampp\htdocs_my-project\my-project\vendor\symfony\cache\Traits\AbstractAdapterTrait.php:185
 Symfony\Component\Cache\Adapter\AbstractAdapter->getItem() at C:\xampp\htdocs_my-project\my-project\vendor\symfony\cache\Adapter\TraceableAdapter.php:71
 Symfony\Component\Cache\Adapter\TraceableAdapter->getItem() at C:\xampp\htdocs_my-project\my-project\vendor\overtrue\phplint\src\Cache.php:89
 Overtrue\PHPLint\Cache->getItem() at C:\xampp\htdocs_my-project\my-project\vendor\overtrue\phplint\src\Cache.php:105
 Overtrue\PHPLint\Cache->isHit() at C:\xampp\htdocs_my-project\my-project\vendor\overtrue\phplint\src\Linter.php:100
 Overtrue\PHPLint\Linter->lintFiles() at C:\xampp\htdocs_my-project\my-project\vendor\overtrue\phplint\src\Command\LintCommand.php:96
 Overtrue\PHPLint\Command\LintCommand->execute() at C:\xampp\htdocs_my-project\my-project\vendor\symfony\console\Command\Command.php:312
 Symfony\Component\Console\Command\Command->run() at C:\xampp\htdocs_my-project\my-project\vendor\symfony\console\Application.php:1040
 Symfony\Component\Console\Application->doRunCommand() at C:\xampp\htdocs_my-project\my-project\vendor\symfony\console\Application.php:314
 Symfony\Component\Console\Application->doRun() at C:\xampp\htdocs_my-project\my-project\vendor\overtrue\phplint\src\Console\Application.php:58
 Overtrue\PHPLint\Console\Application->doRun() at C:\xampp\htdocs_my-project\my-project\vendor\symfony\console\Application.php:168
 Symfony\Component\Console\Application->run() at C:\xampp\htdocs_my-project\my-project\vendor\overtrue\phplint\src\Console\Application.php:47
 Overtrue\PHPLint\Console\Application->run() at C:\xampp\htdocs_my-project\my-project\vendor\overtrue\phplint\bin\phplint:61
 include() at C:\xampp\htdocs_my-project\my-project\vendor\bin\phplint:120

lint [--exclude EXCLUDE] [--extensions EXTENSIONS] [-j|--jobs JOBS] [-c|--configuration CONFIGURATION] [--no-configuration] [--cache CACHE] [--no-cache] [-p|--progress PROGRESS] [--no-progress] [--log-json [LOG-JSON]] [--log-junit [LOG-JUNIT]] [-w|--warning] [--memory-limit MEMORY-LIMIT] [--ignore-exit-code] [--] [<path>...]

From the exception message I'd guess that the whole path is used as the cache key which won't work because of the backslashes and the colon.

llaville commented 1 year ago

Docker is a best compromise if you've a such environment installed on your Windows platform !

llaville commented 1 year ago

Otherwise do not use cache anymore ;-)

knallcharge commented 1 year ago

While the filename is already "fixed" in Cache.php, line 141, may I rather suggest replacing the line return str_replace('/', '_', $filename); with return str_replace(['{', '}', '(', ')', '/', '\\', '@', ':'], '_', $filename); instead of having people use a completely different environment or disable the cache? Doing so fixes the issue. I have opened a PR.

llaville commented 1 year ago

Good catch, but your PR is not enough for me (sorry) !

Unit tests are missing, and I prefer to avoid hardcoding values

So instead of

return str_replace(['{', '}', '(', ')', '/', '\\', '@', ':'], '_', $filename);

I'll use

return str_replace(str_split(ItemInterface::RESERVED_CHARACTERS), '_', $filename);

Bugfix release with tests are allready available, will push it in next minutes : you can close your PR

llaville commented 1 year ago

Version 9.0.2 has just been released ! Please check-out.

knallcharge commented 1 year ago

I used hardcoded values, because you did ;) But of course you're right, it's much better that way, thanks for the quick fix! 9.0.2 works as expected. (Application.php still needs bumping of the version)

llaville commented 1 year ago

(Application.php still needs bumping of the version)

I know !