Початок роботи
Встановлення
Встановіть Greph через Composer:
composer require greph/greph
Це встановить бібліотеку й чотири виконувані файли в vendor/bin/:
greph: нативний пошук у тексті, пошук AST і перезапис ASTgreph-index: прогрітий текстовий індекс, індекс фактів AST і кешований пошук ASTrg: обгортка сумісності у стилі ripgrepsg: обгортка сумісності у стилі ast-grep
Ці виконувані файли працюють із каталогу vendor/bin/ вашого проєкту, оскільки Greph 0.2.3. Раніші випуски знаходили автозавантажувач Composer лише всередині клону репозиторію Greph, тому потрібна принаймні ця версія:
composer require greph/greph:^0.2.3
Вимоги
- PHP 8.2+ для класів лише для читання, переліків, синтаксису виклику функцій першого класу та просування властивостей конструктора
- ext-json для виводу JSON і даних індексу на диску
- ext-ctype для розбору шаблонів і параметрів
- ext-tokenizer для PHP-Parser і попередніх фільтрів AST
- ext-zlib для кешованого сховища AST (
greph-index ast-cache) - nikic/php-parser (встановлюється автоматично як залежність Composer)
ext-json, ext-ctype і ext-tokenizer увімкнені майже в кожній збірці PHP. Наразі composer.json оголошує лише ext-json (#5), тому Composer не попереджає, якщо бракує одного з інших модулів.
Необов’язково:
- ext-pcntl для паралельного сканування. Якщо його немає, Greph коректно переходить до виконання в одному процесі.
- Зовнішні бінарні файли
rg,grepіsgдля порівняння результатів тестування швидкодії. Під час виконання вони не потрібні.
Пошук, перезапис і індексація ніколи не викликають proc_open() або shell_exec(); лише паралельне сканування створює дочірні процеси й переходить до одного процесу за відсутності pcntl_fork(). Про хостинги, які вимикають proc_open(), shell_exec() або pcntl_fork(), див. розділ Хостинги з обмеженнями на процеси.
Ваш перший текстовий пошук
Режим за замовчуванням у Greph — текстовий пошук, сумісний із grep:
vendor/bin/greph -F "function" src
У виводі використовується канонічний формат file:line:content, на який очікують grep, ripgrep і більшість інтеграцій із редакторами.
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(
Додайте -i для пошуку без урахування регістру, -w — для пошуку цілих слів, -c — для підрахунку, -l — щоб виводити лише шляхи до файлів, -C 2 — щоб показувати два контекстні рядки, тощо. Повний список наведено в довідці CLI.
Ваш перший пошук AST
Передайте -p і шаблон у формі PHP, щоб перейти до структурного пошуку:
vendor/bin/greph -p 'new $CLASS()' src
$CLASS — метазмінна, що захоплює будь-яке ім’я класу. Шаблон new $CLASS() відповідає кожному виразу new без аргументів, незалежно від класу, форматування чи коментарів. Використовуйте new $CLASS($$$ARGS), щоб шукати виклики з будь-якими аргументами.
Кожен збіг AST виводиться у вигляді файлу, початкового рядка та знайденого фрагмента коду:
src/Greph.php:43:new FileWalker()
src/Greph.php:52:new TextSearchOptions()
src/Greph.php:54:new TextSearcher()
Інші корисні шаблони:
# 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
Повний синтаксис шаблонів див. у розділі Режими / Пошук AST.
Ваш перший перезапис
Додайте -r, щоб перетворити пошук AST на перезапис:
# 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
Під час перезапису форматування поза збігом зберігається: замінюється лише знайдений вузол, а навколишні пробіли, відступи й коментарі залишаються без змін. Сам знайдений вузол генерується заново за шаблоном, тому його форматування нормалізується, а коментар усередині нього може зникнути. Докладніше див. у розділі Режими / Перезапис.
PHP API
Статичний фасад Greph\Greph надає ті самі операції, що й 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";
}
Повний набір можливостей описано в API.
Індексований пошук
Для повторюваних завдань корисні прогріті індекси. Створіть індекс один раз, а потім виконуйте багато запитів:
# 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
За замовчуванням індекси зберігаються в .greph-index, .greph-ast-index і .greph-ast-cache у кореневому каталозі проєкту.
Для дерев файлів, що активно змінюються, виберіть профіль життєвого циклу, а не вважайте всі прогріті індекси однаковими:
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
Типовий підхід такий:
- стабільну базову версію зберігайте як
static - активні зміни зберігайте як накладки
opportunistic-refresh - перевіряйте застарілу поведінку за допомогою
stats --dry-refresh
Пошук у кількох прогрітих індексах
Ви можете шукати в кількох прогрітих індексах однією командою:
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
Іменовані набори індексів
Якщо ви часто це робите, опишіть структуру в .greph-index-set.json і використовуйте підкоманди наборів замість повторення прапорців:
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)' .
Трасування планувальника
Щоб побачити, як прогрітий пошук звужує коло кандидатів, додайте --trace-plan:
vendor/bin/greph-index search --trace-plan -F "function" .
vendor/bin/greph-index ast-index search --trace-plan 'new $CLASS()' .
Повний опис прогрітого процесу див. у розділах Індексований / Текст і Індексований / AST.
Обгортки сумісності
Якщо ваші інструменти чи агенти вже працюють із ripgrep або ast-grep, просто додайте обгортки:
vendor/bin/rg --json -F "function" src
vendor/bin/sg --pattern 'new $CLASS()' src --lang php
Обидві обгортки використовують той самий рушій, а їхню відповідність вихідним бінарним файлам перевірено пробами. Опис перевірених можливостей наведено в розділах Сумісність / rg і Сумісність / sg, а також у згенерованій матриці можливостей.
Конфігурація
Greph враховує дві домовленості щодо файлів на диску:
.gitignore: враховується за замовчуванням. Передайте--no-ignore, щоб вимкнути..grephignore: той самий синтаксис, що й у.gitignore, застосовується додатково. Корисно для виключень, специфічних для інструмента, які не потрібно додавати до системи контролю версій.
За замовчуванням каталоги індексів .greph-index, .greph-ast-index і .greph-ast-cache створюються у вибраному кореневому каталозі. Перевизначте їх за допомогою --index-dir у будь-якій підкоманді greph-index або скористайтеся .greph-index-set.json для повторюваних структур із кількома індексами.