Pular para o conteúdo

Greph

Pesquisa de código PHP pura, pesquisa estrutural e mecanismo de reescrita. Fluxos de trabalho com grep, ripgrep e ast-grep em um único pacote Composer.

Terminal
composer require greph/greph

Versão mais recente v0.2.3 MIT PHP 8.2+

Na prática

Instale o pacote com Composer e, em seguida, pesquise e reescreva pela linha de comando ou em PHP.

Pesquise, encontre correspondências e visualize uma reescrita

-F executa uma pesquisa de texto por string literal; -p recebe um padrão no formato PHP, com met variáveis como $CLASS; e -r adiciona um modelo de substituição. --dry-run exibe os arquivos reescritos sem gravá-los.

A fachada estática Greph expõe as mesmas operações a código PHP. Quando instalados como dependência, os comandos vendor/bin exigem a versão 0.2.3 ou posterior.

Terminal
# Text search
vendor/bin/greph -F "function" src

# Structural search
vendor/bin/greph -p 'new $CLASS()' src

# Structural rewrite preview
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --dry-run src

PHP puro

A pesquisa e a reescrita são executadas em PHP 8.2+, sem binários de grep, ripgrep ou ast-grep. Usa as extensões json, ctype e tokenizer, além de zlib para o armazenamento em cache da AST.

Pesquisa de texto

Pesquisa por string literal e regex com modos de palavra inteira, sem distinção entre maiúsculas e minúsculas, contexto, contagem e somente arquivos. Saída compatível com grep.

Pesquisa AST

Pesquisa estrutural de código PHP com metavariáveis $VAR e $$$VARIADIC, capturas repetidas e saída JSON. PHP é a única linguagem compatível.

Reescrita AST

Reescritas estruturais com modos de simulação, interativo e gravação. Só o código correspondente é alterado; comentários e formatação fora da correspondência permanecem como estavam.

Modos indexados

Crie uma vez um índice de texto por trigramas, um índice de fatos da AST ou um armazenamento em cache da AST e reutilize-o. No benchmark do projeto, o índice de fatos da AST levou 1.4 s para ser criado e reduziu new $CLASS() de 2.9 s para 11 ms; o índice de trigramas levou 12.3 s.

Wrappers rg e sg

vendor/bin/rg e vendor/bin/sg aceitam os sinalizadores de pesquisa comuns de ripgrep e ast-grep no mesmo mecanismo. Não são compatíveis: pesquisa em várias linhas, --replace, --type-add e --sort no rg; regras YAML e linguagens não PHP no sg.

PHP API

Greph::searchText(), searchAst() e rewriteAst() retornam objetos de resultado tipados, para que código PHP e agentes chamem o mecanismo sem um subprocesso.

Corpus de referência

39 cenários comparam por diff a saída de texto, AST e reescrita do greph com grep, ripgrep e ast-grep. Execute-os com composer test:oracle em um clone do repositório; a CI executa as suítes de unidade e integração.

Por que Greph

Sem binários nativos

A pesquisa e a reescrita são executadas dentro do processo PHP. Os binários rg, grep e sg são usados apenas nas comparações opcionais de benchmark.

Um mecanismo para todos os modos

A pesquisa de texto, a pesquisa estrutural PHP e a reescrita fazem parte de um único pacote Composer. Os wrappers rg e sg chamam o mesmo mecanismo que vendor/bin/greph.

As reescritas alteram apenas as correspondências

O reescritor insere o modelo renderizado nos intervalos de bytes correspondentes. O código fora das correspondências mantém o recuo, os comentários e as linhas em branco.

Índices aquecidos sem um daemon

Os índices ficam no disco e são reutilizados entre execuções. Um perfil de ciclo de vida decide se um índice desatualizado é mantido, atualizado durante a pesquisa ou recusado.

Comparação com

Greph mantém a pesquisa e a reescrita em PHP. Essas ferramentas resolvem problemas relacionados e fazem algumas coisas que Greph não faz.

Greph em comparação com outras ferramentas
ripgrep Ideal paraUma ferramenta de pesquisa recursiva com regex e suporte de primeira classe a Windows, macOS e Linux, além de downloads de binários em cada versão. Respeita as regras do gitignore e, por padrão, ignora arquivos ocultos e binários. Diferenças em relação a GrephGreph é instalado com Composer e executado em PHP. No benchmark de CI do corpus WordPress, o rg foi mais rápido em todas as consultas de texto sem índice aquecido, por exemplo, 81.62 ms contra 458.82 ms em uma pesquisa literal. Um índice Greph aquecido respondeu a uma consulta de contagem em 10.90 ms, contra 49.61 ms do rg.
ast-grep Ideal paraUm CLI compilado para pesquisa estrutural, lint e reescrita, desenvolvido com tree-sitter. Tem suporte integrado a muitas linguagens, entre elas PHP, e arquivos de regras YAML para lint e alterações de código. Diferenças em relação a GrephGreph lida apenas com PHP e não lê regras YAML. Em uma varredura sem índice aquecido, o sg foi mais rápido em array($$$ITEMS) no benchmark de CI de Greph. O índice AST aquecido de Greph respondeu a new $CLASS() em 10.89 ms, contra 4093.61 ms do sg.
Rector Ideal paraAtualiza e refatora código PHP com regras e conjuntos de regras, abrangendo as versões PHP de 5.3 a 8.5 e projetos como Symfony, PHPUnit e Doctrine. Diferenças em relação a GrephGreph reescreve código com base em um padrão e um modelo que você cria. A documentação desaconselha seu uso quando uma alteração depende de informações de tipos que PHP-Parser não consegue resolver a partir de um único arquivo ou exige adicionar ou remover imports entre arquivos.
PHP CS Fixer Ideal paraCorrige o código para seguir os padrões de codificação, com conjuntos de regras integrados, como o estilo de código PER do PHP-FIG. Diferenças em relação a GrephGreph não reformata arquivos. Altera apenas o código correspondente ao padrão, e a documentação indica PHP CS Fixer quando você precisa de um formatador.

Perguntas e respostas

Respostas curtas da documentação do Greph.

Leia a documentação de Greph para consultar a referência de CLI, a PHP API, os modos indexados e os wrappers rg e sg.