Primeiros passos
Instalação
Instale Greph por meio de Composer:
composer require greph/greph
Isso instala a biblioteca e quatro executáveis em vendor/bin/:
greph: pesquisa nativa de texto, pesquisa AST e reescrita ASTgreph-index: índice de texto aquecido, índice de fatos AST e pesquisa AST em cacherg: wrapper de compatibilidade no estilo ripgrepsg: wrapper de compatibilidade no estilo ast-grep
Esses executáveis funcionam no diretório vendor/bin/ do seu projeto, pois Greph 0.2.3. Versões anteriores só encontravam o autoloader Composer dentro de um clone do repositório Greph; por isso, use ao menos essa versão:
composer require greph/greph:^0.2.3
Requisitos
- PHP 8.2+ para classes somente leitura, enums, sintaxe de callable de primeira classe e promoção de construtor
- ext-json para a saída JSON e payloads de índice em disco
- ext-ctype para análise de padrões e opções
- ext-tokenizer para PHP-Parser e os pré-filtros da AST
- ext-zlib para o armazenamento de AST em cache (
greph-index ast-cache) - nikic/php-parser (instalado automaticamente como dependência de Composer)
ext-json, ext-ctype e ext-tokenizer estão habilitados em quase todas as compilações de PHP. composer.json declara apenas ext-json no momento (#5), então Composer não emite avisos quando algum dos outros está ausente.
Opcional:
- ext-pcntl para varreduras paralelas. Greph recorre normalmente à execução em processo único quando ele está ausente.
- Binários externos de
rg,grepesgpara comparações de benchmark. Eles nunca são necessários em tempo de execução.
A pesquisa, a reescrita e a indexação nunca chamam proc_open() ou shell_exec(); somente as varreduras paralelas criam processos, e recorrem a um único processo sem pcntl_fork(). Consulte Hosts com restrições a processos para saber sobre hosts que desabilitam proc_open(), shell_exec() ou pcntl_fork().
Sua primeira pesquisa de texto
O modo padrão de Greph é a pesquisa de texto compatível com grep:
vendor/bin/greph -F "function" src
A saída usa o formato canônico de file:line:content que grep, ripgrep e a maioria das integrações com editores esperam.
src/Greph.php:41: public static function walk(string|array $paths, ?WalkOptions $options = null): FileList
src/Greph.php:50: public static function searchText(string $pattern, string|array $paths, ?TextSearchOptions $options = null): array
src/Greph.php:81: public static function buildTextIndex(
Adicione -i para ignorar maiúsculas e minúsculas, -w para corresponder a palavras inteiras, -c para contagens, -l apenas para caminhos de arquivos, -C 2 para duas linhas de contexto e assim por diante. A lista completa está na referência de opçõesCLI.
Sua primeira pesquisa de AST
Passe -p e um padrão no formato de PHP para mudar para a pesquisa estrutural:
vendor/bin/greph -p 'new $CLASS()' src
$CLASS é uma metavariável que captura qualquer nome de classe. O padrão new $CLASS() corresponde a todas as expressões new sem argumentos, independentemente da classe, formatação ou dos comentários. Use new $CLASS($$$ARGS) para corresponder a chamadas com quaisquer argumentos.
Cada correspondência de AST é exibida como arquivo, linha inicial e código correspondente:
src/Greph.php:43:new FileWalker()
src/Greph.php:52:new TextSearchOptions()
src/Greph.php:54:new TextSearcher()
Outros padrões úteis:
# Any method call with any arguments
vendor/bin/greph -p '$obj->$method($$$ARGS)' src
# Any function declaration with a void return type
vendor/bin/greph -p 'function $name($$$PARAMS): void {}' src
# Old-style array calls
vendor/bin/greph -p 'array($$$ITEMS)' src
Consulte Modos / Pesquisa de AST para ver a sintaxe completa dos padrões.
Sua primeira reescrita
Adicione -r para transformar a pesquisa de AST em uma reescrita:
# Preview only
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --dry-run src
# Apply
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' src
# Confirm each file before writing
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --interactive src
As reescritas preservam a formatação fora da correspondência: apenas o nó correspondente é substituído, enquanto os espaços em branco, a indentação e os comentários ao redor permanecem intactos. O próprio nó correspondente é gerado novamente a partir do modelo, então sua disposição é normalizada e um comentário dentro dele pode se perder. Consulte Modos / Reescrita para obter detalhes.
PHP API
A fachada estática Greph\Greph expõe as mesmas operações que CLI:
use Greph\Greph;
use Greph\Ast\AstSearchOptions;
use Greph\Text\TextSearchOptions;
$results = Greph::searchText(
'function',
'src',
new TextSearchOptions(fixedString: true, caseInsensitive: true),
);
foreach ($results as $file) {
foreach ($file->matches as $match) {
echo "{$file->file}:{$match->line}:{$match->content}\n";
}
}
$matches = Greph::searchAst(
'new $CLASS()',
'src',
new AstSearchOptions(),
);
foreach ($matches as $match) {
echo "{$match->file}:{$match->startLine}:{$match->code}\n";
}
A interface completa está descrita em API.
Pesquisa indexada
Cargas de trabalho repetidas se beneficiam de índices aquecidos. Crie o índice uma vez e faça consultas várias vezes:
# Text index
vendor/bin/greph-index build .
vendor/bin/greph-index search -F "function" .
# AST fact index
vendor/bin/greph-index ast-index build .
vendor/bin/greph-index ast-index search 'new $CLASS()' src
# Cached parsed-tree index
vendor/bin/greph-index ast-cache build .
vendor/bin/greph-index ast-cache search 'array($$$ITEMS)' src
Por padrão, os índices ficam em .greph-index, .greph-ast-index e .greph-ast-cache na raiz do projeto.
Para árvores que mudam ativamente, escolha um perfil de ciclo de vida em vez de tratar todos os índices aquecidos da mesma forma:
vendor/bin/greph-index build . --lifecycle static
vendor/bin/greph-index build . \
--lifecycle opportunistic-refresh \
--auto-refresh-max-files 32 \
--auto-refresh-max-bytes 1048576
vendor/bin/greph-index stats . --dry-refresh
O padrão mais comum é:
- manter uma base estável como
static - manter sobreposições que mudam ativamente como
opportunistic-refresh - inspecionar comportamentos obsoletos com
stats --dry-refresh
Pesquisa aquecida em vários índices
Você pode pesquisar em vários índices aquecidos com um único comando:
vendor/bin/greph-index search -F "apply_filters" . \
--index-dir wordpress/.greph-index \
--index-dir wp-content/plugins/my-plugin/.greph-index \
--show-index-origin
vendor/bin/greph-index ast-index search 'new $CLASS()' . \
--index-dir wordpress/.greph-ast-index \
--index-dir wp-content/plugins/my-plugin/.greph-ast-index \
--show-index-origin
Conjuntos de índices nomeados
Se você fizer isso repetidamente, coloque a configuração em .greph-index-set.json e use os subcomandos de conjunto em vez de repetir as opções:
vendor/bin/greph-index set build
vendor/bin/greph-index set stats --dry-refresh
vendor/bin/greph-index set search --show-index-origin -F "apply_filters" .
vendor/bin/greph-index set search --mode ast-index 'new $CLASS()' .
vendor/bin/greph-index set search --mode ast-cache 'array($$$ITEMS)' .
Rastreamento do planejador
Para ver como a pesquisa aquecida está reduzindo o conjunto de candidatos, adicione --trace-plan:
vendor/bin/greph-index search --trace-plan -F "function" .
vendor/bin/greph-index ast-index search --trace-plan 'new $CLASS()' .
Consulte Indexado / Texto e Indexado / AST para ver o fluxo completo de trabalho com índices aquecidos.
Wrappers de compatibilidade
Se você tem ferramentas ou agentes que já usam ripgrep ou ast-grep, adicione os wrappers:
vendor/bin/rg --json -F "function" src
vendor/bin/sg --pattern 'new $CLASS()' src --lang php
Ambos os wrappers reutilizam o mesmo mecanismo e são verificados por sondagem em relação aos binários upstream. A interface verificada está documentada em Compatibilidade / rg e Compatibilidade / sg, e reproduzida na matriz de funcionalidades gerada.
Configuração
Greph reconhece duas convenções em disco:
.gitignore: respeitado por padrão. Passe--no-ignorepara desabilitar..grephignore: mesma sintaxe de.gitignore, aplicada por cima. Útil para exclusões específicas de ferramentas que você não quer manter no controle de versão.
Os diretórios de índice padrão são .greph-index, .greph-ast-index e .greph-ast-cache na raiz escolhida. Substitua-os com --index-dir em qualquer subcomando greph-index ou use .greph-index-set.json para configurações repetíveis com vários índices.