
# Parcours de fichiers

Chaque mode Greph (texte, AST, réécriture, texte indexé, AST indexé, AST en cache, wrapper `rg`, wrapper `sg`) commence par parcourir l’arborescence de fichiers et produire un `Greph\Walker\FileList`. Le parcours est partagé, de sorte que les mêmes options et comportements s’appliquent partout.

## Comportement par défaut

Par défaut, le parcours :

- Parcourt récursivement tous les répertoires sous les chemins demandés.
- Respecte les règles `.gitignore` et `.grephignore` à chaque niveau, y compris les dérogations imbriquées et les exclusions annulées.
- Ignore le répertoire `.git`.
- Ignore les fichiers et répertoires masqués (tout nom commençant par `.`).
- Ignore les fichiers binaires (détectés par des octets nuls dans les 512 premiers octets du fichier).
- Ignore les fichiers de plus de 10 MiB.
- Ne suit pas les liens symboliques.

## Options de dérogation

| Option | Effet |
|---|---|
| `--no-ignore` | Cesser de respecter `.gitignore` et `.grephignore` |
| `--hidden` | Inclure les fichiers et répertoires masqués |
| `--type NAME` | Inclure uniquement les fichiers correspondant à l’alias de type indiqué |
| `--type-not NAME` | Exclure les fichiers correspondant à l’alias de type indiqué |
| `--glob GLOB` | Inclure uniquement les fichiers dont le chemin correspond à GLOB. Répétable. |

Les mêmes options sont disponibles via `Greph\Walker\WalkOptions` pour une utilisation programmatique.

```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 de types de fichiers

Greph fournit un petit ensemble de types de fichiers nommés. Chaque alias correspond à une liste d’extensions :

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

La liste complète se trouve dans `Greph\Walker\FileTypeFilter::TYPE_MAP`.

## Sémantique de .gitignore

Greph implémente la correspondance gitignore en pur PHP. La sémantique est conforme à `git check-ignore` :

- Les motifs sont évalués par rapport au répertoire où ils se trouvent.
- Les fichiers `.gitignore` imbriqués remplacent les règles des répertoires parents.
- Une négation (`!pattern`) réinclut un chemin précédemment exclu.
- Le `/` final limite un motif aux répertoires.
- Le `/` initial ancre un motif au répertoire du `.gitignore`.
- `**` correspond à un nombre quelconque de segments de chemin.

`.grephignore` utilise la même syntaxe et s’ajoute à `.gitignore`. C’est l’endroit adapté pour les exclusions propres à l’outil que vous ne souhaitez pas inclure dans le contrôle de version.

L’implémentation se trouve dans `Greph\Walker\GitignoreFilter`.

## Détection des fichiers binaires

Le parcours vérifie la présence d’octets nuls dans les 512 premiers octets de chaque fichier. Si de tels octets sont présents, le fichier est considéré comme binaire et ignoré. Cela couvre le cas courant où un dépôt contient des images, des archives ou des artefacts compilés dans un répertoire indexé.

Pour rechercher aussi dans les fichiers binaires, définissez `skipBinaryFiles: false` sur l’objet `Options` concerné. Le CLI ne permet pas actuellement de définir cette option ; utilisez la façade.

## Liens symboliques

Par défaut, les liens symboliques ne sont pas suivis. Définissez `followSymlinks: true` (ou transmettez `-L` / `--follow` au wrapper `rg`) pour les suivre. Le parcours mémorise les répertoires visités afin d’éviter toute récursion infinie en cas de boucle de liens symboliques.

## Taille maximale des fichiers

Les fichiers de plus de `maxFileSizeBytes` (10 MiB par défaut) sont ignorés. Cela évite que les analyses chargent par inadvertance un fichier journal de 1 GB en mémoire. Modifiez la limite sur l’objet `Options` pour traiter des fichiers plus volumineux.

## Pourquoi créer un parcours personnalisé

Greph pourrait s’appuyer sur `glob()` ou `RecursiveDirectoryIterator`, mais aucun des deux ne prend en charge la sémantique gitignore, ne comprend `.grephignore` ni ne s’intègre correctement au pool de travailleurs. Le fait d’écrire le parcours une seule fois et de le partager entre les modes garantit aussi que chaque mode applique exactement les mêmes règles de filtrage, ce qui est essentiel à la stratégie de tests pilotés par oracle : pour comparer avec `grep`, `ripgrep` et `ast-grep`, il faut parcourir le même ensemble de fichiers que ces outils.
