コンテンツへスキップ

Greph

純粋なPHPコード検索、構造検索、書き換えエンジン。grep、ripgrep、ast-grepのワークフローを1つのComposerパッケージにまとめます。

ターミナル
composer require greph/greph

最新リリース v0.2.3 MIT PHP 8.2+

実践例

Composerでパッケージをインストールしてから、コマンドラインまたはPHPで検索や書き換えを実行できます。

検索、マッチ、書き換えのプレビュー

-Fは固定文字列のテキスト検索を実行し、-pはPHP形式のパターンと$CLASSなどのメタ変数を受け付け、-rは置換テンプレートを追加します。--dry-runを使うと、ファイルに書き込まずに書き換え後の内容を表示できます。

静的なGrephファサードから、PHPコードでも同じ操作を利用できます。依存関係としてインストールする場合、vendor/binコマンドにはバージョン0.2.3以降が必要です。

ターミナル
# 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

検索と書き換えはgrep、ripgrep、ast-grepのバイナリなしでPHP 8.2+上で実行できます。json、ctype、tokenizer拡張機能と、キャッシュされたASTストア用のzlibを使用します。

テキスト検索

単語全体、大文字小文字を区別しない検索、コンテキスト、件数、ファイルのみの各モードに対応した固定文字列・正規表現検索。grep互換の出力。

AST検索

PHPソースを対象にした構造検索。$VARおよび$$$VARIADICメタ変数、繰り返しキャプチャ、JSON出力に対応しています。サポート対象の言語はPHPのみです。

AST書き換え

ドライラン、対話型、書き込みモードに対応した構造的な書き換え。マッチしたコードだけが変更され、マッチ範囲外のコメントや配置はそのままです。

インデックスモード

トライグラムテキストインデックス、ASTファクトインデックス、またはキャッシュ済みASTストアを一度構築すれば、再利用できます。プロジェクトのベンチマークでは、ASTファクトインデックスの構築に1.4 sかかり、new $CLASS()を2.9 sから11 msに短縮しました。トライグラムインデックスの構築には12.3 sかかりました。

rg・sgラッパー

vendor/bin/rgとvendor/bin/sgは、同じエンジン上で一般的なripgrepおよびast-grep検索フラグを受け付けます。未対応の機能:rgの複数行検索、--replace、--type-add、--sort、およびsgのYAMLルールとPHP以外の言語。

PHP API

Greph::searchText()、searchAst()、rewriteAst()は型付きの結果オブジェクトを返すため、PHPコードやエージェントはサブプロセスを使わずにエンジンを呼び出せます。

オラクルコーパス

39のシナリオで、grephのテキスト、AST、書き換えの出力をgrep、ripgrep、ast-grepと比較します。リポジトリをクローンしてcomposer test:oracleで実行できます。CIではユニットテストと統合テストを実行します。

Grephを選ぶ理由

ネイティブバイナリ不要

検索と書き換えはPHPプロセス内で実行されます。rg、grep、sgのバイナリは、任意のベンチマーク比較にのみ使用します。

すべてのモードで1つのエンジン

テキスト検索、PHP構造検索、書き換えを1つのComposerパッケージにまとめています。rgとsgのラッパーは、vendor/bin/grephと同じエンジンを呼び出します。

書き換えるのはマッチした箇所だけ

書き換え処理は、レンダリングしたテンプレートをマッチしたバイト範囲に挿入します。マッチ範囲外のコードでは、インデント、コメント、空行が保たれます。

デーモン不要のウォームインデックス

インデックスはディスクに保存され、実行間で再利用されます。ライフサイクルプロファイルに応じて、古いインデックスをそのまま残すか、検索中に更新するか、使用を拒否します。

との比較

Grephは検索と書き換えをPHP内で行います。これらのツールも関連する問題を解決しますが、Grephにはない機能もあります。

他のツールとGrephの比較
ripgrep 得意なことWindows、macOS、Linuxでの確かなサポートと、各リリースのバイナリダウンロードを備えた再帰的な正規表現検索ツールです。gitignoreルールに従い、デフォルトで隠しファイルとバイナリファイルをスキップします。 Grephとの違いGrephはComposerでインストールでき、PHPで実行できます。WordPressコーパスを使ったCIベンチマークでは、rgはすべてのコールドテキスト検索でより高速でした。たとえば、リテラル検索は81.62 msで完了し、rgは458.82 msでした。ウォーム状態のGrephインデックスでは、件数検索に10.90 msかかり、rgでは49.61 msでした。
ast-grep 得意なことtree-sitterを基盤とする、構造検索、lint、書き換えのためのコンパイル済みCLIです。多くの言語を組み込みでサポートし、その中にはPHPも含まれます。また、lintルールやコード変更用のYAMLルールファイルにも対応します。 Grephとの違いGrephはPHPのみを扱い、YAMLルールは読み込みません。コールドスキャンでは、GrephのCIベンチマークでarray($$$ITEMS)に対してsgの方が高速でした。GrephのウォームASTインデックスは、4093.61 msのsgに対し、new $CLASS()を10.89 msで処理しました。
Rector 得意なことルールとルールセットを使ってPHPコードをアップグレード、リファクタリングします。PHPのバージョン5.3~8.5をカバーし、Symfony、PHPUnit、Doctrineなどのプロジェクトに対応します。 Grephとの違いGrephは、作成したパターンとテンプレートに基づいて書き換えます。ドキュメントでは、変更がPHP-Parserで単一ファイルから解決できない型情報に依存する場合や、ファイル間でインポートを追加または削除する必要がある場合には適さないとしています。
PHP CS Fixer 得意なことコード規約に従うようコードを修正します。PHP-FIGのPERコーディングスタイルなどのルールセットを組み込みで備えています。 Grephとの違いGrephはファイルを再フォーマットしません。パターンにマッチしたコードだけを変更します。フォーマッターが必要な場合は、ドキュメントでPHP CS Fixerを案内しています。

質問と回答

Grephのドキュメントから、簡潔に回答します。

Grephのドキュメントでは、CLIリファレンス、PHP API、インデックスモード、rgとsgのラッパーについて説明しています。