Estou tentando analisar um diretório recursivo de arquivos PHP usando o linter PHP embutido, que funciona assim:
$ php -l good.php
No syntax errors detected in good.php
$ php -l bad.php
PHP Parse error: syntax error, unexpected ''foo'' (T_CONSTANT_ENCAPSED_STRING), expecting ')' in bad.php on line 3
Errors parsing bad.php
Podemos ver que os arquivos que passam o linting produzem uma linha contendo No syntax errors
e aqueles que falham o linting produzem uma linha contendo Errors parsing
.
Vejo que tenho 12147 arquivos PHP recursivamente no diretório atual, no entanto, o linter do PHP está gerando apenas sete linhas:
$ find . -name \*.php -print0 | xargs -0 ls -l | wc -l
12147
$ find . -name \*.php -print0 | xargs -0 php -l | wc -l
7
Como havia apenas 7 arquivos analisados pelo PHP, posso usar meu head
with ls
para encontrar alguns arquivos que não foram analisados:
$ find . -name \*.php -print0 | xargs -0 ls -l | head
-rw-r--r-- 1 dotan dotan 1927 Jan 13 10:13 ./bootstrap/app.php
-rw-r--r-- 1 dotan dotan 1076 Jan 13 10:13 ./bootstrap/autoload.php
-rw-rw-r-- 1 dotan dotan 25620 Mar 12 12:29 ./bootstrap/cache/services.php
-rw-r--r-- 1 dotan dotan 2493 Jan 13 10:13 ./bootstrap/paths.php
-rwxrwxr-x 1 dotan dotan 20008 Mar 12 12:30 ./config/app.php
-rw-r--r-- 1 dotan dotan 3304 Jan 13 10:13 ./config/auth.php
-rw-r--r-- 1 dotan dotan 1819 Jan 13 10:13 ./config/cache.php
-rw-r--r-- 1 dotan dotan 3751 Jan 13 10:13 ./config/cartalyst.sentinel-addons.social.php
-rw-r--r-- 1 dotan dotan 6849 Jan 13 10:13 ./config/cartalyst.sentinel.php
-rw-r--r-- 1 dotan dotan 1020 Jan 13 10:13 ./config/compile.php
xargs: ls: terminated by signal 13
$ find . -name \*.php -print0 | xargs -0 php -l
No syntax errors detected in ./bootstrap/paths.php
No syntax errors detected in ./vendor/watson/validating/src/ValidatingTrait.php
No syntax errors detected in ./vendor/giggsey/libphonenumber-for-php/src/libphonenumber/data/PhoneNumberMetadata_SI.php
No syntax errors detected in ./vendor/php-vcr/php-vcr/src/VCR/Event/BeforePlaybackEvent.php
No syntax errors detected in ./vendor/laravel/framework/src/Illuminate/Support/Facades/Blade.php
No syntax errors detected in ./resources/views/emails/appointment/updated/body.blade.php
No syntax errors detected in ./app/WL/Modules/Location/Commands/RemoveClientLocationCommand.php
No entanto, quando tento analisar um desses arquivos, vejo que ele produz a saída esperada (passando ou falhando na análise):
$ php -l ./bootstrap/cache/services.php
No syntax errors detected in ./bootstrap/cache/services.php
Verifiquei que nem a passagem nem a falha do linting estão imprimindo as linhas esperadas para stderr:
$ php -l good.php | grep rr
No syntax errors detected in good.php
$ php -l bad.php | grep rr
PHP Parse error: syntax error, unexpected ''foo'' (T_CONSTANT_ENCAPSED_STRING), expecting ')' in bad.php on line 3
Errors parsing bad.php
O que devo verificar agora? Meu objetivo final é fazer o lint de todos os arquivos e, em seguida, grep para Error parsing
corrigir esses problemas.
Para ver se xargs faz diferença, execute as linhas de comando que ele executa. Aqui estão algumas maneiras de ver exatamente o que ele executa, sem correr o risco de alterar o que ele executa:
php
em um diretório temporário e coloque-o no início de$PATH
. Neste script, registre os argumentos (e, opcionalmente, execute o realphp
depois).strace
.Você verá que o comando é algo como
A próxima etapa é investigar o que esse comando faz.
Eu não estou familiarizado
php
, mas acho que ele trata apenas o primeiro nome de arquivo como um nome de script PHP e, no modo lint, ele simplesmente ignora todos os argumentos subsequentes. Portanto, você precisa executarphp -l
uma vez para cada script, 12.147 vezes no total, em vez de usarxargs
o comportamento de agrupamento do .A maneira mais fácil de fazer isso é
mas esse comando sempre retornará 0, mesmo que algumas invocações de
php
retornem um status diferente de zero. Embora find principalmente não precise de xargs no século 21, um benefício de xargs é que ele retorna um status diferente de zero se qualquer invocação do comando retornar um status diferente de zero. Portanto, execute xargs, mas diga a ele para processar apenas um arquivo por vez com a-n
opção.