Treci la conținut

Parcurgător de fișiere

Fiecare mod Greph (text, AST, rescriere, text indexat, AST indexat, AST memorat în cache, wrapper-ul rg, wrapper-ul sg) începe prin parcurgerea arborelui de fișiere și generarea unui Greph\Walker\FileList. Parcurgătorul este partajat, astfel că aceleași flaguri și comportamente se aplică peste tot.

Comportamentul implicit

Implicit, parcurgătorul:

  • Parcurge recursiv fiecare director din căile solicitate.
  • Respectă regulile .gitignore și .grephignore la fiecare nivel, inclusiv suprascrierile și negările imbricate.
  • Omite directorul .git.
  • Omite fișierele și directoarele ascunse (cele al căror nume începe cu .).
  • Omite fișierele binare (detectate prin octeți nuli în primii 512 octeți ai fișierului).
  • Omite fișierele mai mari de 10 MiB.
  • Nu urmează legăturile simbolice.

Flaguri de suprascriere

Flag Efect
--no-ignore Nu mai respectă .gitignore și .grephignore
--hidden Include fișierele și directoarele ascunse
--type NAME Include doar fișierele care corespund aliasului de tip numit
--type-not NAME Exclude fișierele care corespund aliasului de tip numit
--glob GLOB Include doar fișierele ale căror căi corespund cu GLOB. Poate fi repetat.

Aceleași opțiuni sunt expuse prin Greph\Walker\WalkOptions pentru utilizare programatică.

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

Aliasuri pentru tipuri de fișiere

Greph include un set restrâns de tipuri de fișiere denumite. Fiecare alias corespunde unei liste de extensii:

Alias Extensii
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

Lista completă se află în Greph\Walker\FileTypeFilter::TYPE_MAP.

Semantica .gitignore

Greph implementează potrivirea gitignore în PHP pur. Semantica este aliniată cu git check-ignore:

  • Tiparele sunt evaluate în raport cu directorul în care se află.
  • Fișierele .gitignore imbricate suprascriu regulile părinte.
  • Negarea (!pattern) reinclude o cale exclusă anterior.
  • / la final restricționează un tipar la directoare.
  • / la început ancorează un tipar în directorul fișierului .gitignore.
  • ** corespunde oricărui număr de segmente de cale.

.grephignore folosește aceeași sintaxă și se suprapune peste .gitignore. Acesta este locul potrivit pentru excluderi specifice instrumentului pe care nu doriți să le includeți în controlul versiunilor.

Implementarea se află în Greph\Walker\GitignoreFilter.

Detectarea fișierelor binare

Parcurgătorul verifică primii 512 octeți din fiecare fișier pentru octeți nuli. Dacă găsește vreunul, fișierul este tratat ca binar și omis. Astfel este detectat cazul obișnuit în care un depozit conține imagini, arhive sau artefacte compilate într-un director indexat.

Pentru a căuta și în fișierele binare, setați skipBinaryFiles: false în obiectul Options relevant. CLI nu expune momentan un flag pentru acest lucru; folosiți fațada.

Legăturile simbolice nu sunt urmate implicit. Setați followSymlinks: true (sau transmiteți -L / --follow wrapper-ului rg) pentru a le urma. Parcurgătorul ține evidența directoarelor vizitate, astfel încât buclele de legături simbolice să nu provoace recursie infinită.

Dimensiunea maximă a fișierului

Fișierele mai mari de maxFileSizeBytes (implicit 10 MiB) sunt omise. Astfel, scanările nu încarcă accidental în memorie un fișier jurnal de 1 GB. Suprascrieți limita în obiectul Options când trebuie să procesați intrări mai mari.

De ce un parcurgător personalizat

Greph ar putea folosi glob() sau RecursiveDirectoryIterator, dar niciuna nu implementează semantica gitignore, niciuna nu înțelege .grephignore și niciuna nu se integrează bine cu pool-ul de workeri. Scrierea parcurgătorului o singură dată și partajarea lui între moduri înseamnă, de asemenea, că fiecare mod aplică exact aceleași reguli de filtrare, ceea ce este esențial pentru strategia de testare bazată pe oracle: singura modalitate de a compara cu grep, ripgrep și ast-grep este să parcurgem același set de fișiere ca acele instrumente.