
# Περιηγητής αρχείων

Κάθε λειτουργία Greph (κείμενο, AST, επανεγγραφή, ευρετηριασμένο κείμενο, ευρετηριασμένο AST, αποθηκευμένο AST, περίβλημα `rg`, περίβλημα `sg`) ξεκινά με περιήγηση στο δέντρο αρχείων και δημιουργία ενός `Greph\Walker\FileList`. Ο περιηγητής είναι κοινός, επομένως οι ίδιες σημαίες και συμπεριφορές ισχύουν παντού.

## Προεπιλεγμένη συμπεριφορά

Από προεπιλογή, ο περιηγητής:

- Περιηγείται αναδρομικά σε κάθε κατάλογο κάτω από τις ζητούμενες διαδρομές.
- Τηρεί τους κανόνες των `.gitignore` και `.grephignore` σε κάθε επίπεδο, συμπεριλαμβανομένων των ένθετων παρακάμψεων και αρνήσεων.
- Παραλείπει τον κατάλογο `.git`.
- Παραλείπει κρυφά αρχεία και καταλόγους (οτιδήποτε αρχίζει με `.`).
- Παραλείπει δυαδικά αρχεία (εντοπίζονται από μηδενικά byte στα πρώτα 512 byte του αρχείου).
- Παραλείπει αρχεία μεγαλύτερα από 10 MiB.
- Δεν ακολουθεί συμβολικούς συνδέσμους.

## Σημαίες παράκαμψης

| Σημαία | Επίδραση |
|---|---|
| `--no-ignore` | Παύει να τηρεί τα `.gitignore` και `.grephignore` |
| `--hidden` | Συμπεριλαμβάνει κρυφά αρχεία και καταλόγους |
| `--type NAME` | Συμπεριλαμβάνει μόνο αρχεία που ταιριάζουν με το καθορισμένο ψευδώνυμο τύπου |
| `--type-not NAME` | Εξαιρεί αρχεία που ταιριάζουν με το καθορισμένο ψευδώνυμο τύπου |
| `--glob GLOB` | Συμπεριλαμβάνει μόνο αρχεία των οποίων οι διαδρομές ταιριάζουν με το GLOB. Επαναλαμβάνεται. |

Οι ίδιες επιλογές διατίθενται μέσω του `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'],
));
```

## Ψευδώνυμα τύπων αρχείων

Το Greph περιλαμβάνει ένα μικρό σύνολο ονομασμένων τύπων αρχείων. Κάθε ψευδώνυμο αντιστοιχεί σε μια λίστα επεκτάσεων:

| Ψευδώνυμο | Επεκτάσεις |
|---|---|
| `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` |

Η πλήρης λίστα βρίσκεται στο `Greph\Walker\FileTypeFilter::TYPE_MAP`.

## Σημασιολογία του .gitignore

Το Greph υλοποιεί αντιστοίχιση gitignore αποκλειστικά σε PHP. Η σημασιολογία είναι ευθυγραμμισμένη με το `git check-ignore`:

- Τα μοτίβα αξιολογούνται σε σχέση με τον κατάλογο στον οποίο βρίσκονται.
- Τα ένθετα αρχεία `.gitignore` υπερισχύουν των κανόνων του γονικού καταλόγου.
- Η άρνηση (`!pattern`) επανεντάσσει μια διαδρομή που είχε προηγουμένως εξαιρεθεί.
- Το τελικό `/` περιορίζει ένα μοτίβο στους καταλόγους.
- Το αρχικό `/` αγκυρώνει ένα μοτίβο στον κατάλογο του `.gitignore`.
- Το `**` αντιστοιχεί σε οποιονδήποτε αριθμό τμημάτων διαδρομής.

Το `.grephignore` χρησιμοποιεί την ίδια σύνταξη και βασίζεται στο `.gitignore`. Είναι το κατάλληλο μέρος για εξαιρέσεις ειδικές για το εργαλείο, τις οποίες δεν θέλετε να συμπεριλάβετε στον έλεγχο εκδόσεων.

Η υλοποίηση βρίσκεται στο `Greph\Walker\GitignoreFilter`.

## Εντοπισμός δυαδικών αρχείων

Ο περιηγητής ελέγχει τα πρώτα 512 byte κάθε αρχείου για μηδενικά byte. Αν βρεθούν, το αρχείο θεωρείται δυαδικό και παραλείπεται. Έτσι εντοπίζεται η συνήθης περίπτωση όπου ένα αποθετήριο περιέχει εικόνες, αρχεία αρχειοθέτησης ή μεταγλωττισμένα τεχνουργήματα μέσα σε κατάλογο με ευρετήριο.

Για να αναζητήσετε ούτως ή άλλως σε δυαδικά αρχεία, ορίστε το `skipBinaryFiles: false` στο σχετικό αντικείμενο `Options`. Το CLI δεν διαθέτει προς το παρόν σημαία για αυτό· χρησιμοποιήστε το facade.

## Συμβολικοί σύνδεσμοι

Από προεπιλογή, οι συμβολικοί σύνδεσμοι δεν ακολουθούνται. Ορίστε το `followSymlinks: true` (ή περάστε τα `-L` / `--follow` στο περίβλημα `rg`) για να ακολουθούνται. Ο περιηγητής καταγράφει τους καταλόγους που έχει επισκεφθεί, ώστε οι βρόχοι συμβολικών συνδέσμων να μην προκαλούν άπειρη αναδρομή.

## Μέγιστο μέγεθος αρχείου

Τα αρχεία μεγαλύτερα από `maxFileSizeBytes` (προεπιλογή: 10 MiB) παραλείπονται. Έτσι οι σαρώσεις προστατεύονται από την τυχαία φόρτωση ενός αρχείου καταγραφής 1 GB στη μνήμη. Παρακάμψτε το όριο στο αντικείμενο `Options` όταν χρειάζεται να καλύψετε μεγαλύτερες εισόδους.

## Γιατί χρησιμοποιείται προσαρμοσμένος περιηγητής

Το Greph θα μπορούσε να βασιστεί στο `glob()` ή στο `RecursiveDirectoryIterator`, αλλά κανένα από τα δύο δεν υλοποιεί τη σημασιολογία gitignore, δεν κατανοεί το `.grephignore` και δεν ενσωματώνεται ομαλά στην ομάδα εργαζομένων. Η συγγραφή ενός περιηγητή που χρησιμοποιείται από όλες τις λειτουργίες σημαίνει επίσης ότι όλες εφαρμόζουν ακριβώς τους ίδιους κανόνες φιλτραρίσματος, κάτι κρίσιμο για τη στρατηγική δοκιμών με oracle: ο μόνος τρόπος σύγκρισης με τα `grep`, `ripgrep` και `ast-grep` είναι να περιηγηθούμε στο ίδιο σύνολο αρχείων με αυτά τα εργαλεία.
