Saltar al contenido
becwright

Guías

Escribir checks

El contrato del check, los checks incluidos y cómo escribir el tuyo en cualquier lenguaje.

Última actualización

Un check es la parte ejecutable de una BEC — el programita que de verdad inspecciona tus archivos y dice pasa o falla.

La mayoría de las veces no escribes código. Si tu regla es “este texto no debe aparecer” (una palabra prohibida, un debugger olvidado, una función vetada), usa el check incluido forbid y listo — salta a El camino más rápido. Escribir tu propio check (el resto de esta página) es solo para casos que forbid no puede expresar.

¿Qué contrato debe seguir un check?

  • Entrada: la lista de archivos a chequear, una ruta por línea, por stdin.
  • Salida: imprime las violaciones por stdout (becwright las muestra bajo “Found in:”).
  • Código de salida: 0 = pasa, no-cero = falla.
  • Directorio de trabajo: la raíz del repo, así las rutas de stdin resuelven directo.

Glosario rápido: stdin/stdout son los canales de entrada/salida estándar por los que un programa lee y escribe. El código de salida es el número que devuelve un programa al terminar — 0 significa “todo bien”, cualquier otro significa “encontré un problema”. Esa es toda la interfaz: entran archivos, salen los problemas, y sale con 0 o no-cero.

El camino más rápido: forbid

Para “este regex no debe aparecer” no necesitas escribir código — usa el check genérico incluido:

- id: no-debugger-js
  paths: ["**/*.js", "**/*.ts"]
  check: "becwright run forbid --pattern '\\bdebugger\\b'"
  severity: blocking

forbid acepta --pattern REGEX, --ignore-case y --message TEXT.

Checks incluidos

CheckDetectaLenguaje
forbidcualquier regex que pases (--pattern)cualquiera
requireun regex (--pattern) que debe estar (inverso de forbid)cualquiera
max_linesarchivos con más de --max líneascualquiera
filenamenombres de archivo que matchean --forbid o no matchean --requirecualquiera
hardcoded_secretsclaves AWS, claves privadas, password = "..."cualquiera
dangerous_evaleval() / exec()cualquiera
conflict_markersmarcadores de conflicto de merge olvidados (<<<<<<<)cualquiera
no_token_in_logstokens/credenciales en llamadas de logPython
debug_remnantsbreakpoint(), pdb.set_trace(), import pdbPython
wildcard_importsfrom x import *Python
redundant_commentscomentarios que repiten lo obvio del código (heurístico)Python

Un check propio (cualquier lenguaje)

Cualquier ejecutable que siga el contrato funciona. Ejemplo en Node, marcando TODO:

#!/usr/bin/env node
const fs = require('fs');
const files = fs.readFileSync(0, 'utf8').split('\n').filter(Boolean);
let bad = false;
for (const f of files) {
  fs.readFileSync(f, 'utf8').split('\n').forEach((line, i) => {
    if (line.includes('TODO')) { console.log(`  ${f}:${i + 1}`); bad = true; }
  });
}
process.exit(bad ? 1 : 0);
- id: no-todo
  paths: ["**/*.js"]
  check: "node .bec/checks/no_todo.js"
  severity: warning

Un check incluido en Python sigue el mismo esqueleto — ver src/becwright/checks/dangerous_eval.py.

¿Cómo se ignora un falso positivo?

Un falso positivo —un patrón que aparece como texto, no como violación real— se puede suprimir con un marcador becwright: ignore en un comentario de esa línea, en cualquier lenguaje:

result = eval(expr)  # becwright: ignore
console.log(x);  // becwright: ignore

El marcador exime a la línea de todos los checks incluidos.

La salvedad de la auto-referencia

Un check de texto/regex no puede correr sobre su propio fuente: un check que prohíbe la cadena eval( matcheará la mismísima línea de su código que define ese patrón. Cuando el check de una regla escanearía su propio archivo, acota paths para excluirlo — p.ej. usa src/becwright/*.py (solo el nivel superior) en vez de src/becwright/**/*.py para saltar el directorio checks/. Para líneas individuales, el marcador becwright: ignore de arriba es más simple.