Обходчик файлов
Каждый режим Greph (текст, AST, переписывание, индексированный текст, индексированный AST, кэшированный AST, оболочка rg, оболочка sg) начинает работу с обхода дерева файлов и создания Greph\Walker\FileList. Обходчик общий, поэтому везде действуют одни и те же флаги и правила.
Поведение по умолчанию
По умолчанию обходчик:
- Рекурсивно обходит все каталоги в заданных путях.
- Соблюдает правила
.gitignoreи.grephignoreна каждом уровне, включая вложенные переопределения и отрицания. - Пропускает каталог
.git. - Пропускает скрытые файлы и каталоги (имена которых начинаются с
.). - Пропускает бинарные файлы (определяет их по нулевым байтам в первых 512 байтах файла).
- Пропускает файлы размером более 10 MiB.
- Не переходит по символьным ссылкам.
Флаги переопределения
| Флаг | Действие |
|---|---|
--no-ignore |
Не учитывать правила .gitignore и .grephignore |
--hidden |
Включать скрытые файлы и каталоги |
--type NAME |
Включать только файлы, соответствующие указанному псевдониму типа |
--type-not NAME |
Исключать файлы, соответствующие указанному псевдониму типа |
--glob GLOB |
Включать только файлы, пути которых соответствуют GLOB. Можно повторять. |
Те же параметры доступны для программного использования через Greph\Walker\WalkOptions.
use Greph\Greph;
use Greph\Walker\FileTypeFilter;
use Greph\Walker\WalkOptions;
$files = Greph::walk('src', new WalkOptions(
respectIgnore: false,
includeHidden: true,
fileTypeFilter: new FileTypeFilter(['php']),
globPatterns: ['src/**/*.php'],
));
Псевдонимы типов файлов
Greph включает небольшой набор именованных типов файлов. Каждый псевдоним соответствует списку расширений:
| Псевдоним | Расширения |
|---|---|
css |
css, sass, scss |
html |
htm, html, phtml |
js |
cjs, js, mjs |
json |
json |
md |
markdown, md |
php |
inc, php, php3, php4, php5, php7, php8, phpt, phtml |
txt |
txt |
ts |
ts, tsx |
xml |
xml |
yaml |
yaml, yml |
Полный список находится в Greph\Walker\FileTypeFilter::TYPE_MAP.
Семантика .gitignore
Greph реализует сопоставление правил gitignore на чистом PHP. Семантика соответствует git check-ignore:
- Шаблоны оцениваются относительно каталога, в котором они находятся.
- Вложенные файлы
.gitignoreпереопределяют правила родительских каталогов. - Отрицание (
!pattern) снова включает путь, который ранее был исключен. - Завершающий
/ограничивает шаблон каталогами. - Начальный
/привязывает шаблон к каталогу, где находится.gitignore. **соответствует любому количеству сегментов пути.
.grephignore использует тот же синтаксис и дополняет .gitignore. Здесь удобно задавать исключения для конкретного инструмента, которые не должны попадать под контроль версий.
Реализация находится в Greph\Walker\GitignoreFilter.
Обнаружение бинарных файлов
Обходчик проверяет первые 512 байтов каждого файла на наличие нулевых байтов. Если они обнаружены, файл считается бинарным и пропускается. Это позволяет отсеивать распространенные случаи, когда в индексируемом каталоге репозитория находятся изображения, архивы или скомпилированные файлы.
Чтобы искать и в бинарных файлах, задайте skipBinaryFiles: false для соответствующего объекта Options. В CLI сейчас нельзя задать этот флаг; используйте фасад.
Символьные ссылки
По умолчанию обходчик не переходит по символьным ссылкам. Чтобы включить их обход, задайте followSymlinks: true или передайте -L / --follow в оболочку rg. Обходчик отслеживает посещенные каталоги, чтобы циклы символьных ссылок не приводили к бесконечной рекурсии.
Максимальный размер файла
Файлы размером более maxFileSizeBytes (по умолчанию 10 MiB) пропускаются. Это защищает сканирование от случайной загрузки в память файла журнала размером 1 GB. Если нужно обрабатывать файлы большего размера, измените ограничение в объекте Options.
Зачем нужен собственный обходчик
Greph мог бы использовать glob() или RecursiveDirectoryIterator, но ни один из них не реализует семантику gitignore, не учитывает .grephignore и не интегрируется с пулом рабочих процессов. Единый обходчик для всех режимов гарантирует, что каждый режим применяет одинаковые правила фильтрации. Это важно для стратегии тестирования на основе oracle: сравнение с grep, ripgrep и ast-grep возможно только при обходе того же набора файлов, что и у этих инструментов.