Перейти до вмісту

Обхід файлової системи

Кожен режим Greph (text, AST, rewrite, indexed text, indexed AST, cached 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.

PHP
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 можна, лише обходячи той самий набір файлів, що й ці інструменти.