Walker plików
Każdy tryb Greph (tekstowy, AST, przepisywania, tekst z indeksem, AST z indeksem, AST z pamięci podręcznej, opakowanie rg, opakowanie sg) rozpoczyna się od przejścia po drzewie plików i utworzenia Greph\Walker\FileList. Walker jest współdzielony, więc te same flagi i zachowania obowiązują wszędzie.
Domyślne działanie
Domyślnie walker:
- Rekurencyjnie przechodzi przez każdy katalog w podanych ścieżkach.
- Respektuje reguły
.gitignorei.grephignorena każdym poziomie, w tym zagnieżdżone nadpisania i negacje. - Pomija katalog
.git. - Pomija ukryte pliki i katalogi (wszystko, co zaczyna się od
.). - Pomija pliki binarne (wykrywane na podstawie bajtów zerowych w pierwszych 512 bajtach pliku).
- Pomija pliki większe niż 10 MiB.
- Nie podąża za dowiązaniami symbolicznymi.
Flagi nadpisywania
| Flaga | Działanie |
|---|---|
--no-ignore |
Przestań respektować .gitignore i .grephignore |
--hidden |
Uwzględniaj ukryte pliki i katalogi |
--type NAME |
Uwzględniaj tylko pliki pasujące do nazwanego aliasu typu |
--type-not NAME |
Wykluczaj pliki pasujące do nazwanego aliasu typu |
--glob GLOB |
Uwzględniaj tylko pliki, których ścieżki pasują do GLOB. Można powtarzać. |
Te same opcje są dostępne przez Greph\Walker\WalkOptions do użytku programistycznego.
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'],
));
Aliasy typów plików
Greph zawiera niewielki zestaw nazwanych typów plików. Każdy alias odpowiada liście rozszerzeń:
| Alias | Rozszerzenia |
|---|---|
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 |
Pełna lista znajduje się w Greph\Walker\FileTypeFilter::TYPE_MAP.
Semantyka .gitignore
Greph implementuje dopasowywanie zgodne z gitignore w czystym PHP. Semantyka jest zgodna z git check-ignore:
- Wzorce są oceniane względem katalogu, w którym się znajdują.
- Zagnieżdżone pliki
.gitignorenadpisują reguły nadrzędne. - Negacja (
!pattern) ponownie uwzględnia wcześniej wykluczoną ścieżkę. - Końcowe
/ogranicza wzorzec do katalogów. - Początkowe
/zakotwicza wzorzec w katalogu pliku.gitignore. **dopasowuje dowolną liczbę segmentów ścieżki.
.grephignore używa tej samej składni i jest nakładany na .gitignore. To właściwe miejsce na wykluczenia specyficzne dla narzędzia, których nie chcesz umieszczać w kontroli wersji.
Implementacja znajduje się w Greph\Walker\GitignoreFilter.
Wykrywanie plików binarnych
Walker sprawdza pierwsze 512 bajtów każdego pliku pod kątem bajtów zerowych. Jeśli je znajdzie, uznaje plik za binarny i pomija go. Pozwala to wykryć typowe przypadki, gdy repozytorium zawiera obrazy, archiwa lub skompilowane artefakty w indeksowanym katalogu.
Aby mimo to wyszukiwać w plikach binarnych, ustaw skipBinaryFiles: false w odpowiednim obiekcie Options. CLI obecnie nie udostępnia flagi w tym celu; użyj fasady.
Dowiązania symboliczne
Domyślnie dowiązania symboliczne nie są śledzone. Ustaw followSymlinks: true (lub przekaż -L / --follow w opakowaniu rg), aby za nimi podążać. Walker śledzi odwiedzone katalogi, więc pętle dowiązań symbolicznych nie powodują nieskończonej rekurencji.
Maksymalny rozmiar pliku
Pliki większe niż maxFileSizeBytes (domyślnie 10 MiB) są pomijane. Chroni to skanowanie przed przypadkowym wczytaniem do pamięci pliku dziennika o rozmiarze 1 GB. Gdy trzeba uwzględnić większe pliki wejściowe, zmień limit w obiekcie Options.
Dlaczego własny walker
Greph mógłby korzystać z glob() lub RecursiveDirectoryIterator, ale żadne z tych rozwiązań nie implementuje semantyki gitignore, nie rozumie .grephignore ani nie integruje się dobrze z pulą procesów roboczych. Napisanie jednego walkera współdzielonego przez różne tryby oznacza też, że każdy tryb stosuje dokładnie te same reguły filtrowania, co ma kluczowe znaczenie dla strategii testów opartej na oracle: porównanie z grep, ripgrep i ast-grep jest możliwe tylko wtedy, gdy walker przechodzi przez ten sam zestaw plików co te narzędzia.