Saltar al contenido

Recorredor de archivos

Cada modo de Greph (texto, AST, reescritura, texto indexado, AST indexado, AST en caché, envoltorio rg, envoltorio sg) comienza recorriendo el árbol de archivos y generando un Greph\Walker\FileList. El recorrido es compartido, por lo que las mismas opciones y comportamientos se aplican en todas partes.

Comportamiento predeterminado

De forma predeterminada, el recorredor:

  • Recorre recursivamente todos los directorios dentro de las rutas solicitadas.
  • Respeta las reglas de .gitignore y .grephignore en todos los niveles, incluidas las anulaciones y negaciones anidadas.
  • Omite el directorio .git.
  • Omite los archivos y directorios ocultos (cualquier elemento cuyo nombre empiece por .).
  • Omite los archivos binarios (detectados por bytes nulos en los primeros 512 bytes del archivo).
  • Omite los archivos de más de 10 MiB.
  • No sigue enlaces simbólicos.

Opciones de anulación

Opción Efecto
--no-ignore Dejar de respetar .gitignore y .grephignore
--hidden Incluir archivos y directorios ocultos
--type NAME Incluir solo archivos que coincidan con el alias de tipo indicado
--type-not NAME Excluir los archivos que coincidan con el alias de tipo indicado
--glob GLOB Incluir solo archivos cuyas rutas coincidan con GLOB. Se puede repetir.

Las mismas opciones se exponen mediante Greph\Walker\WalkOptions para su uso programático.

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 tipos de archivo

Greph incluye un pequeño conjunto de tipos de archivo con nombre. Cada alias corresponde a una lista de extensiones:

Alias Extensiones
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 lista completa está en Greph\Walker\FileTypeFilter::TYPE_MAP.

Semántica de .gitignore

Greph implementa la coincidencia con gitignore en PHP puro. La semántica coincide con la de git check-ignore:

  • Los patrones se evalúan en relación con el directorio en el que se encuentran.
  • Los archivos .gitignore anidados anulan las reglas del directorio superior.
  • La negación (!pattern) vuelve a incluir una ruta excluida anteriormente.
  • El / final limita un patrón a los directorios.
  • El / inicial ancla un patrón al directorio de .gitignore.
  • ** coincide con cualquier número de segmentos de ruta.

.grephignore utiliza la misma sintaxis y se superpone a .gitignore. Es el lugar adecuado para exclusiones específicas de herramientas que no quiera incluir en el control de versiones.

La implementación está en Greph\Walker\GitignoreFilter.

Detección de binarios

El recorredor comprueba si hay bytes nulos en los primeros 512 bytes de cada archivo. Si encuentra alguno, trata el archivo como binario y lo omite. Esto detecta el caso habitual en que un repositorio contiene imágenes, archivos comprimidos o artefactos compilados dentro de un directorio indexado.

Para buscar también en archivos binarios, establezca skipBinaryFiles: false en el objeto Options correspondiente. Actualmente, CLI no ofrece una opción para ello; use la fachada.

De forma predeterminada, no se siguen los enlaces simbólicos. Establezca followSymlinks: true (o pase -L / --follow al envoltorio rg) para seguirlos. El recorredor registra los directorios visitados para evitar que los bucles de enlaces simbólicos causen una recursión infinita.

Tamaño máximo de archivo

Se omiten los archivos de más de maxFileSizeBytes (10 MiB de forma predeterminada). Esto evita que un archivo de registro de 1 GB se cargue accidentalmente en memoria durante un análisis. Cambie el límite en el objeto Options cuando necesite cubrir archivos de mayor tamaño.

Por qué usar un recorredor propio

Greph podría depender de glob() o RecursiveDirectoryIterator, pero ninguno implementa la semántica de gitignore, ninguno entiende .grephignore y ninguno se integra bien con el grupo de trabajadores. Escribir el recorredor una sola vez y compartirlo entre los modos también garantiza que todos apliquen exactamente las mismas reglas de filtrado, algo fundamental para la estrategia de pruebas guiada por un oráculo: la única forma de comparar con grep, ripgrep y ast-grep es recorrer el mismo conjunto de archivos que recorren esas herramientas.