
# Penjelajah File

Setiap mode Greph (teks, AST, penulisan ulang, teks terindeks, AST terindeks, AST dalam cache, wrapper `rg`, wrapper `sg`) dimulai dengan menelusuri pohon file dan menghasilkan `Greph\Walker\FileList`. Walker digunakan bersama, sehingga flag dan perilaku yang sama berlaku di semua mode.

## Perilaku default

Secara default, walker:

- Menelusuri setiap direktori di bawah jalur yang diminta secara rekursif.
- Mengikuti aturan `.gitignore` dan `.grephignore` di setiap tingkat, termasuk penggantian aturan bersarang dan negasi.
- Melewati direktori `.git`.
- Melewati file dan direktori tersembunyi (apa pun yang diawali `.`).
- Melewati file biner (dideteksi dari byte null pada 512 byte pertama file).
- Melewati file yang lebih besar dari 10 MiB.
- Tidak mengikuti symlink.

## Flag penggantian

| Flag | Dampak |
|---|---|
| `--no-ignore` | Berhenti mengikuti `.gitignore` dan `.grephignore` |
| `--hidden` | Sertakan file dan direktori tersembunyi |
| `--type NAME` | Hanya sertakan file yang cocok dengan alias tipe yang disebutkan |
| `--type-not NAME` | Kecualikan file yang cocok dengan alias tipe yang disebutkan |
| `--glob GLOB` | Hanya sertakan file dengan jalur yang cocok dengan GLOB. Dapat diulang. |

Opsi yang sama tersedia melalui `Greph\Walker\WalkOptions` untuk penggunaan terprogram.

```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'],
));
```

## Alias tipe file

Greph menyertakan sekumpulan kecil tipe file bernama. Setiap alias mengarah ke daftar ekstensi:

| Alias | Ekstensi |
|---|---|
| `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` |

Daftar lengkapnya ada di `Greph\Walker\FileTypeFilter::TYPE_MAP`.

## Semantik .gitignore

Greph menerapkan pencocokan gitignore dengan PHP murni. Semantiknya selaras dengan `git check-ignore`:

- Pola dievaluasi relatif terhadap direktori tempat pola tersebut berada.
- File `.gitignore` bersarang menggantikan aturan induk.
- Negasi (`!pattern`) menyertakan kembali jalur yang sebelumnya dikecualikan.
- `/` di akhir membatasi pola hanya untuk direktori.
- `/` di awal mengaitkan pola dengan direktori tempat `.gitignore` berada.
- `**` cocok dengan berapa pun banyaknya segmen jalur.

`.grephignore` menggunakan sintaks yang sama dan dibangun di atas `.gitignore`. Tempat ini cocok untuk pengecualian khusus tool yang tidak ingin Anda masukkan ke kontrol versi.

Implementasinya berada di `Greph\Walker\GitignoreFilter`.

## Deteksi biner

Walker memeriksa 512 byte pertama setiap file untuk mencari byte null. Jika ditemukan, file dianggap biner dan dilewati. Cara ini menangani kasus umum saat repositori berisi gambar, arsip, atau artefak hasil kompilasi di dalam direktori yang diindeks.

Untuk tetap mencari di file biner, tetapkan `skipBinaryFiles: false` pada objek `Options` yang relevan. CLI saat ini tidak menyediakan flag untuk ini; gunakan facade.

## Symlink

Secara default, symlink tidak diikuti. Tetapkan `followSymlinks: true` (atau teruskan `-L` / `--follow` pada wrapper `rg`) untuk mengikutinya. Walker melacak direktori yang sudah dikunjungi agar loop symlink tidak menyebabkan rekursi tanpa akhir.

## Ukuran file maksimum

File yang lebih besar dari `maxFileSizeBytes` (default 10 MiB) akan dilewati. Ini mencegah pemindaian memuat file log 1 GB ke memori secara tidak sengaja. Ganti batasnya pada objek `Options` jika Anda perlu menangani input yang lebih besar.

## Alasan menggunakan walker khusus

Greph dapat mengandalkan `glob()` atau `RecursiveDirectoryIterator`, tetapi keduanya tidak menerapkan semantik gitignore, tidak memahami `.grephignore`, dan tidak terintegrasi dengan baik dengan pool pekerja. Menulis walker satu kali dan menggunakannya bersama di semua mode juga berarti setiap mode menerapkan aturan pemfilteran yang sama persis, yang sangat penting bagi strategi pengujian berbasis oracle: satu-satunya cara membandingkan dengan `grep`, `ripgrep`, dan `ast-grep` adalah menelusuri kumpulan file yang sama dengan yang ditelusuri tool tersebut.
