El archivo de bloqueo
Qué registra verbatra.lock.json, cómo se detecta el desfase, cómo se serializan las ejecuciones concurrentes y por qué debes confirmarlo.
Página traducida automáticamente
El archivo de bloqueo, verbatra.lock.json, existe para que una ejecución pueda saber qué ya se
tradujo y saltárselo: es la línea base contra la que hace diff cada ejecución, y es lo que hace a
verbatra incremental. Esta página cubre qué almacena, cómo cambia y qué pasa cuando está en
disputa, ausente o corrupto.
Qué registra
Para cada locale de destino, el archivo de bloqueo almacena un hash de contenido por clave
traducida, calculado a partir del valor de origen que produjo la traducción existente. No contiene
traducciones ni secretos: solo un campo version y hashes. El hash normaliza Unicode a NFC y los
finales de línea a LF, así que volver a guardar un archivo de origen con otra normalización o con
finales CRLF no marca nada como modificado.
Cómo se detecta el desfase
Cuando una ejecución hace diff de un locale de destino, una clave de origen ausente del destino es faltante. Para una clave que el destino sí tiene, el hash de origen actual se compara contra el hash que registró el bloqueo: una diferencia significa que el origen se desvió desde la última vez que se tradujo la clave, así que está modificada y se retraduce; una coincidencia significa que está sin cambios y nunca se envía al proveedor. Por eso una segunda ejecución sin ediciones en el origen no llama al proveedor para nada, y por eso las traducciones obsoletas no pueden esconderse detrás de una clave que simplemente existe. La canalización completa está en Cómo funciona.
Adoptar un proyecto existente
Apuntar verbatra a un repositorio cuyos archivos de locale ya contienen traducciones revisadas no las retraduce. En la primera ejecución no hay archivo de bloqueo, así que ninguna clave puede detectarse como obsoleta: una clave de origen que el archivo de destino ya tiene está sin cambios, nunca se envía al proveedor y conserva su valor existente. Solo son faltantes las claves que el archivo de destino no tiene, y solo esas se traducen. Si para un locale no se aceptó ninguna traducción, no se eliminó ninguna clave y no se generó ninguna forma, su archivo de destino existente no se reescribe en absoluto.
La ejecución sí registra el hash de origen actual para cada clave que el destino contiene, así que la primera ejecución es el propio paso de adopción: establece la línea base sin una sola llamada al proveedor, y a partir de la segunda ejecución las ediciones del origen aparecen como desfase de la forma habitual.
Que una clave se dé por adoptada lo decide su presencia, nunca su valor, y de ahí salen dos consecuencias que conviene conocer antes de esa primera ejecución:
- Un valor vacío o sin traducir cuenta como traducido. Un valor de destino que es una cadena vacía, o que sigue siendo el texto de origen sin traducir, es una clave que existe, así que está sin cambios y nunca se rellena. Las herramientas de scaffolding que precrean archivos de locale con cadenas vacías caen justo aquí. La solución es borrar la clave del archivo de destino: vaciar su valor no sirve, porque una cadena vacía sigue siendo una entrada. Una vez que la clave no está, la siguiente ejecución la ve como faltante y la traduce.
- Una traducción que ya estaba obsoleta queda registrada como actual. El bloqueo toma el hash de origen tal como está ahora, así que una traducción que ya se había desviado del origen antes de adoptar el proyecto queda dada por al día y no se vuelve a tocar. Corrige o borra esas claves antes de la primera ejecución.
La generación de plurales sigue la misma regla de adopción. Una forma plural que el archivo de
destino ya tiene y que verbatra no generó se conserva tal cual: ni se regenera ni se envía al
proveedor (una forma que el bloqueo ya registra sí se regenera cuando su origen cambia). Así que
puedes dejar generatePlurals activado mientras adoptas un proyecto que lleva formas plurales
escritas a mano; solo se sintetizan las formas que de verdad faltan en el destino.
Puedes verlo todo antes de gastar nada: verbatra diff lista por locale las claves faltantes y
modificadas exactas, verbatra check informa de lo mismo en forma de recuentos y
verbatra translate --dry-run te da el resumen completo de la ejecución. Ninguno de los tres llama
a un proveedor, escribe un archivo de locale ni escribe el bloqueo.
Cómo se actualiza
El bloqueo se actualiza por locale, y el cómo depende de qué se ejecutó:
- Una ejecución completa (translate, watch o una importación de libro) reemplaza en bloque las entradas de ese locale con el resultado autoritativo de la ejecución.
- Una acción de una sola clave (como una retraducción desde Studio) fusiona solo la entrada de esa clave, dejando intacta cada una de las demás claves registradas.
En ambos casos aplica una excepción: una clave retenida en esta ejecución (una comprobación de integridad fallida, una llamada al proveedor fallida o un origen con ICU inválido) conserva su hash anterior, para que la siguiente ejecución siga viéndola como pendiente de trabajo y la reintente en lugar de registrarla como hecha. Las claves huérfanas no reciben entrada. El archivo se serializa con las claves ordenadas, así que sus diffs se mantienen estables y revisables.
El bloqueo de escritura
Dos ejecuciones tocando el mismo locale a la vez (una segunda terminal, un job de CI, una acción de Studio) podrían, si no, hacer diff ambas contra una línea base obsoleta y pagar ambas la misma llamada al proveedor. Para evitarlo, cada escritura a un locale y a sus entradas del bloqueo ocurre bajo un bloqueo de escritura entre procesos limitado a ese único locale; un segundo escritor del mismo locale espera, luego relee el archivo de bloqueo fresco y hace diff contra una línea base que ya incluye el resultado del primer escritor. Locales distintos no se bloquean entre sí.
Cuando una ejecución traduce varios locales a la vez y se topa con un error de toda la ejecución (en la práctica, un archivo de bloqueo corrupto), deja de reclamar locales nuevos y espera a que terminen los que ya están en marcha, así que cada bloqueo que tomó la ejecución se libera antes de que el comando salga. Ningún locale se arranca después de que la ejecución ya haya fallado, y el fallo en sí no deja huérfano ningún bloqueo.
Si un bloqueo no se puede adquirir, la ejecución falla con LOCK_CONTENDED y nombra la ruta del
archivo de bloqueo (bajo el directorio .verbatra-local/, ignorado por git). Si no hay ningún
proceso de verbatra en marcha, ese archivo lo dejó atrás uno que fue matado: bórralo y reintenta.
Ausente o corrupto
Un archivo de bloqueo ausente no es un error: es una primera ejecución, y sin línea base nada puede
detectarse como obsoleto. Las claves de origen que el archivo de destino no tiene son faltantes y se
traducen; las que sí tiene están sin cambios y se dejan intactas, como se describe arriba en la
adopción. Un archivo de bloqueo presente pero imposible de parsear,
estructuralmente incorrecto, demasiado grande o con una versión no soportada hace fallar la
ejecución con LOCK_FILE_INVALID en lugar de sobrescribirse en silencio, para que puedas
inspeccionarlo o restaurarlo en vez de perder la línea base.
Confírmalo
Confirma verbatra.lock.json junto a tus archivos de locale. Es la línea base compartida contra la
que hacen diff tus compañeros y tu CI; mantenerlo en control de versiones es lo que hace que las
ejecuciones incrementales sean reproducibles entre máquinas. Nunca lo edites a mano.
Confirmar ambos es también lo que hace posible una reversión. Como el archivo de bloqueo registra hashes del origen y nada sobre los valores traducidos, si reviertes tus archivos de locale sin él seguirá afirmando que las traducciones revertidas están al día, y nada las retraducirá. Consulta Recuperación y reversión.
Edit on GitHub