Pular para o conteúdo

Primeiros passos

Instalação

Instale Greph por meio de Composer:

Shell
composer require greph/greph

Isso instala a biblioteca e quatro executáveis em vendor/bin/:

  • greph: pesquisa nativa de texto, pesquisa AST e reescrita AST
  • greph-index: índice de texto aquecido, índice de fatos AST e pesquisa AST em cache
  • rg: wrapper de compatibilidade no estilo ripgrep
  • sg: 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:

Shell
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, grep e sg para 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().

O modo padrão de Greph é a pesquisa de texto compatível com grep:

Shell
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.

Text
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.

Passe -p e um padrão no formato de PHP para mudar para a pesquisa estrutural:

Shell
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:

Text
src/Greph.php:43:new FileWalker()
src/Greph.php:52:new TextSearchOptions()
src/Greph.php:54:new TextSearcher()

Outros padrões úteis:

Shell
# 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:

Shell
# 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:

PHP
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.

Cargas de trabalho repetidas se beneficiam de índices aquecidos. Crie o índice uma vez e faça consultas várias vezes:

Shell
# 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:

Shell
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

Você pode pesquisar em vários índices aquecidos com um único comando:

Shell
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:

Shell
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:

Shell
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:

Shell
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-ignore para 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.