
# Failu pārlūks

Katrs Greph režīms (teksts, AST, pārrakstīšana, indeksēts teksts, indeksēts AST, kešots AST, `rg` apvalks, `sg` apvalks) sākas ar failu koka pārlūkošanu un rezultāta `Greph\Walker\FileList` izveidi. Pārlūks ir kopīgs, tāpēc visur tiek lietoti vieni un tie paši karogi un darbības principi.

## Noklusējuma darbība

Pēc noklusējuma pārlūks:

- Rekursīvi pārlūko visus direktorijus zem norādītajiem ceļiem.
- Katrā līmenī ievēro `.gitignore` un `.grephignore` noteikumus, tostarp ligzdotos pārrakstīšanas noteikumus un noliegumus.
- Izlaiž direktoriju `.git`.
- Izlaiž slēptos failus un direktorijus (visus, kuru nosaukums sākas ar `.`).
- Izlaiž bināros failus (tos nosaka pēc nulles baitiem faila pirmajos 512 baitos).
- Izlaiž failus, kas lielāki par 10 MiB.
- Neseko simboliskajām saitēm.

## Ignorēšanas noteikumu ignorēšanas karogi

| Karogs | Iedarbība |
|---|---|
| `--no-ignore` | Pārstāj ievērot `.gitignore` un `.grephignore` |
| `--hidden` | Iekļauj slēptos failus un direktorijus |
| `--type NAME` | Iekļauj tikai failus, kas atbilst nosauktajam tipu aliasam |
| `--type-not NAME` | Izslēdz failus, kas atbilst nosauktajam tipu aliasam |
| `--glob GLOB` | Iekļauj tikai failus, kuru ceļi atbilst GLOB. Atkārtojams. |

Tās pašas opcijas programmiskai lietošanai ir pieejamas, izmantojot `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'],
));
```

## Failu tipu aliasi

Greph ietver nelielu nosaukto failu tipu kopu. Katrs aliases atbilst paplašinājumu sarakstam:

| Aliass | Paplašinājumi |
|---|---|
| `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` |

Pilns saraksts ir pieejams failā `Greph\Walker\FileTypeFilter::TYPE_MAP`.

## .gitignore semantika

Greph īsteno gitignore atbilstības noteikšanu tīrā PHP valodā. Semantika atbilst `git check-ignore`:

- Paraugi tiek izvērtēti attiecībā pret direktoriju, kurā tie atrodas.
- Ligzdoti `.gitignore` faili pārraksta vecākdirektoriju noteikumus.
- Noliegums (`!pattern`) no jauna iekļauj iepriekš izslēgtu ceļu.
- Beigu `/` ierobežo paraugu tikai ar direktorijiem.
- Sākuma `/` piesaista paraugu direktorijam, kurā atrodas `.gitignore`.
- `**` atbilst jebkuram ceļa segmentu skaitam.

`.grephignore` izmanto to pašu sintaksi un ir papildu slānis virs `.gitignore`. Šeit norādiet rīkam specifiskos izņēmumus, kurus nevēlaties iekļaut versiju kontrolē.

Implementācija atrodas mapē `Greph\Walker\GitignoreFilter`.

## Bināro failu noteikšana

Pārlūks pārbauda katra faila pirmos 512 baitus, meklējot nulles baitus. Ja tādi ir, fails tiek uzskatīts par bināru un izlaists. Tādējādi tiek noteikts biežākais gadījums, kad repozitorijā indeksētā direktorijā ir attēli, arhīvi vai kompilēti artefakti.

Lai meklētu arī binārajos failos, iestatiet `skipBinaryFiles: false` attiecīgajam objektam `Options`. CLI pašlaik šādu karogu nepiedāvā; izmantojiet fasādi.

## Simboliskās saites

Pēc noklusējuma simboliskajām saitēm neseko. Lai tām sekotu, iestatiet `followSymlinks: true` (vai padodiet `-L` / `--follow` apvalkam `rg`). Pārlūks uzskaita apmeklētos direktorijus, lai simbolisko saišu cikli neizraisītu bezgalīgu rekursiju.

## Maksimālais faila lielums

Faili, kas lielāki par `maxFileSizeBytes` (pēc noklusējuma 10 MiB), tiek izlaisti. Tas neļauj skenēšanas laikā nejauši ielādēt atmiņā 1 GB žurnālfailu. Ja jāapstrādā lielākas ievades, mainiet ierobežojumu objektam `Options`.

## Kāpēc vajadzīgs pielāgots pārlūks

Greph varētu izmantot `glob()` vai `RecursiveDirectoryIterator`, taču neviens no tiem neīsteno gitignore semantiku, neviens neatpazīst `.grephignore`, un neviens nav ērti savietojams ar darbinieku pūlu. Vienreiz izveidojot pārlūku un koplietojot to visos režīmos, tiek nodrošināts, ka visur tiek lietoti tieši vieni un tie paši filtrēšanas noteikumi. Tas ir svarīgi orākulā balstītajā testēšanas stratēģijā: salīdzināt ar `grep`, `ripgrep` un `ast-grep` var tikai tad, ja tiek pārlūkota tā pati failu kopa, ko izmanto šie rīki.
