Vai al contenuto

Walker di file

Ogni modalità Greph (testo, AST, riscrittura, testo indicizzato, AST indicizzato, AST memorizzato in cache, wrapper rg, wrapper sg) inizia esplorando l’albero dei file e generando un Greph\Walker\FileList. Il walker è condiviso, quindi flag e comportamenti sono gli stessi ovunque.

Comportamento predefinito

Configurazione predefinita del walker:

  • Esplora ricorsivamente tutte le directory nelle percorsi richiesti.
  • Rispetta le regole di .gitignore e .grephignore a ogni livello, incluse le eccezioni e le negazioni annidate.
  • Esclude la directory .git.
  • Esclude file e directory nascosti, ovvero quelli che iniziano con ..
  • Esclude i file binari, rilevati dalla presenza di byte nulli nei primi 512 byte del file.
  • Esclude i file più grandi di 10 MiB.
  • Non segue i link simbolici.

Flag di override

Flag Effetto
--no-ignore Ignora le regole di .gitignore e .grephignore
--hidden Include file e directory nascosti
--type NAME Include solo i file che corrispondono all’alias di tipo specificato
--type-not NAME Esclude i file che corrispondono all’alias di tipo specificato
--glob GLOB Include solo i file il cui percorso corrisponde a GLOB. Ripetibile.

Per l’uso programmatico, le stesse opzioni sono disponibili tramite 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'],
));

Alias dei tipi di file

Greph include un piccolo insieme di tipi di file con nome. Ogni alias corrisponde a un elenco di estensioni:

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

L’elenco completo si trova in Greph\Walker\FileTypeFilter::TYPE_MAP.

Semantica di .gitignore

Greph implementa la corrispondenza con gitignore in PHP puro. La semantica è allineata a git check-ignore:

  • I pattern vengono valutati rispetto alla directory in cui si trovano.
  • I file .gitignore annidati sovrascrivono le regole delle directory genitrici.
  • La negazione (!pattern) reinclude un percorso escluso in precedenza.
  • / finale limita il pattern alle directory.
  • / iniziale ancora un pattern alla directory di .gitignore.
  • ** corrisponde a un numero qualsiasi di segmenti del percorso.

.grephignore usa la stessa sintassi ed è sovrapposto a .gitignore. È il posto giusto per le esclusioni specifiche degli strumenti che non volete inserire nel controllo delle versioni.

L’implementazione si trova in Greph\Walker\GitignoreFilter.

Rilevamento dei file binari

Il walker controlla la presenza di byte nulli nei primi 512 byte di ogni file. Se ne trova, il file viene considerato binario ed escluso. Questo intercetta il caso comune in cui un repository contiene immagini, archivi o artefatti compilati in una directory indicizzata.

Per cercare comunque nei file binari, impostate skipBinaryFiles: false sull’oggetto Options pertinente. Al momento CLI non espone un flag per questa opzione; usate la facade.

Per impostazione predefinita, i link simbolici non vengono seguiti. Impostate followSymlinks: true (oppure passate -L / --follow al wrapper rg) per seguirli. Il walker tiene traccia delle directory visitate, così i cicli nei link simbolici non causano ricorsioni infinite.

Dimensione massima dei file

I file più grandi di maxFileSizeBytes (10 MiB per impostazione predefinita) vengono esclusi. In questo modo si evita che una scansione carichi accidentalmente in memoria un file di log da 1 GB. Se dovete elaborare file più grandi, potete aumentare il limite sull’oggetto Options.

Perché usare un walker personalizzato

Greph potrebbe basarsi su glob() o RecursiveDirectoryIterator, ma nessuno dei due implementa la semantica di gitignore, riconosce .grephignore o si integra facilmente con il pool di worker. Scrivere il walker una sola volta e condividerlo tra le modalità significa anche applicare esattamente gli stessi filtri a ciascuna modalità, un requisito fondamentale per la strategia di test basata sull’oracolo: l’unico modo per confrontare con grep, ripgrep e ast-grep è esaminare lo stesso insieme di file di questi strumenti.