Archivo de bloqueo de Bazel

Informar un problema Ver fuente

La función del archivo de bloqueo en Bazel permite registrar versiones o dependencias específicas de paquetes o bibliotecas de software que requiere un proyecto. Para ello, almacena el resultado de la resolución del módulo y la evaluación de la extensión. El archivo de bloqueo promueve compilaciones reproducibles, lo que garantiza entornos de desarrollo coherentes. Además, mejora la eficiencia de la compilación, ya que permite que Bazel omita el proceso de resolución cuando no haya cambios en las dependencias del proyecto. Además, el archivo de bloqueo mejora la estabilidad, ya que evita actualizaciones inesperadas o cambios rotundos en las bibliotecas externas, lo que reduce el riesgo de introducir errores.

Generación de archivos de bloqueo

El archivo de bloqueo se genera en la raíz del lugar de trabajo con el nombre MODULE.bazel.lock. Se crea o actualiza durante el proceso de compilación, específicamente después de la resolución del módulo y la evaluación de la extensión. El archivo de bloqueo captura el estado actual del proyecto, lo que incluye el archivo MÓDULO, las marcas, las anulaciones y otra información relevante. Es importante destacar que solo incluye dependencias que se incluyen en la invocación actual de la compilación.

Cuando se producen cambios en el proyecto que afectan sus dependencias, el archivo de bloqueo se actualiza automáticamente para reflejar el estado nuevo. Esto garantiza que el archivo de bloqueo se mantenga enfocado en el conjunto específico de dependencias requeridas para la compilación actual, lo que proporciona una representación precisa de las dependencias resueltas del proyecto.

Uso del archivo de bloqueo

El archivo de bloqueo se puede controlar con la marca --lockfile_mode para personalizar el comportamiento de Bazel cuando el estado del proyecto difiere del archivo de bloqueo. Los modos disponibles son los siguientes:

  • update (predeterminado): Si el estado del proyecto coincide con el archivo de bloqueo, el resultado de la resolución se muestra inmediatamente desde el archivo de bloqueo. De lo contrario, se ejecuta la resolución, y el archivo de bloqueo se actualiza para reflejar el estado actual.
  • error: Si el estado del proyecto coincide con el archivo de bloqueo, el resultado de la resolución se muestra desde este. De lo contrario, Bazel muestra un error que indica las variaciones entre el proyecto y el archivo de bloqueo. Este modo es particularmente útil cuando quieres asegurarte de que las dependencias de tu proyecto permanezcan sin cambios y que las diferencias se traten como error.
  • off: El archivo de bloqueo no está verificado.

Beneficios del archivo de bloqueo

El archivo de bloqueo ofrece varios beneficios y se puede usar de varias maneras:

  • Compilaciones reproducibles. Mediante la captura de las versiones o dependencias específicas de las bibliotecas de software, el archivo de bloqueo garantiza que las compilaciones sean reproducibles en diferentes entornos y con el tiempo. Los desarrolladores pueden confiar en resultados coherentes y predecibles cuando compilan sus proyectos.

  • Omisión eficiente de la resolución El archivo de bloqueo le permite a Bazel omitir el proceso de resolución si no hay cambios en las dependencias del proyecto desde la última compilación. Esto mejora significativamente la eficiencia de la compilación, especialmente en situaciones en las que la resolución puede llevar mucho tiempo.

  • Estabilidad y reducción de riesgos. El archivo de bloqueo ayuda a mantener la estabilidad evitando actualizaciones inesperadas o cambios rotundos en las bibliotecas externas. Cuando bloqueas las dependencias en versiones específicas, se reduce el riesgo de introducir errores debido a actualizaciones incompatibles o no probadas.

Contenido del archivo de bloqueo

El archivo de bloqueo contiene toda la información necesaria para determinar si cambió el estado del proyecto. También incluye el resultado de compilar el proyecto en el estado actual. El archivo de bloqueo consta de dos partes principales:

  1. Entradas de la resolución del módulo, como moduleFileHash, flags y localOverrideHashes, así como la salida de la resolución, que es moduleDepGraph.
  2. Para cada extensión del módulo, el archivo de bloqueo incluye las entradas que lo afectan, representadas por transitiveDigest, y el resultado de la ejecución de esa extensión, denominado generatedRepoSpecs.

A continuación, se muestra un ejemplo que muestra la estructura del archivo de bloqueo, junto con explicaciones para cada sección:

{
  "lockFileVersion": 1,
  "moduleFileHash": "b0f47b98a67ee15f9.......8dff8721c66b721e370",
  "flags": {
    "cmdRegistries": [
      "https://bcr.bazel.build/"
    ],
    "cmdModuleOverrides": {},
    "allowedYankedVersions": [],
    "envVarAllowedYankedVersions": "",
    "ignoreDevDependency": false,
    "directDependenciesMode": "WARNING",
    "compatibilityMode": "ERROR"
  },
  "localOverrideHashes": {
    "bazel_tools": "b5ae1fa37632140aff8.......15c6fe84a1231d6af9"
  },
  "moduleDepGraph": {
    "<root>": {
      "name": "",
      "version": "",
      "executionPlatformsToRegister": [],
      "toolchainsToRegister": [],
      "extensionUsages": [
        {
          "extensionBzlFile": "extension.bzl",
          "extensionName": "lockfile_ext"
        }
      ],
      ...
    }
  },
  "moduleExtensions": {
    "//:extension.bzl%lockfile_ext": {
      "transitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
      "generatedRepoSpecs": {
        "hello": {
          "bzlFile": "@@//:extension.bzl",
          ...
        }
      }
    }
  }
}

Hash de archivo de módulo

El moduleFileHash representa el hash del contenido del archivo MODULE.bazel. Si se produce algún cambio en este archivo, el valor de hash difiere.

Marcas

El objeto Flags almacena todas las marcas que pueden afectar el resultado de la resolución.

Hashes de anulación locales

Si el módulo raíz incluye local_path_overrides, esta sección almacena el hash del archivo MODULE.bazel en el repositorio local. Permite hacer un seguimiento de los cambios en esta dependencia.

Grafo de dependencia del módulo

El moduleDepGraph representa el resultado del proceso de resolución usando las entradas mencionadas anteriormente. Forma el gráfico de dependencias de todos los módulos necesarios para ejecutar el proyecto.

Extensiones de módulo

La sección moduleExtensions es un mapa que incluye solo las extensiones utilizadas en la invocación actual o anteriormente invocadas, y excluye las extensiones que ya no se usan. En otras palabras, si una extensión ya no se usa en el gráfico de dependencia, se quita del mapa moduleExtensions.

Cada entrada de este mapa corresponde a una extensión utilizada y se identifica por el archivo y el nombre que lo contienen. El valor correspondiente para cada entrada contiene la información relevante asociada con esa extensión:

  1. El transitiveDigest es el resumen de la implementación de la extensión y sus archivos .bzl transitivos.
  2. El generatedRepoSpecs es el resultado de ejecutar esa extensión con la entrada actual.

Un factor adicional que puede afectar los resultados de la extensión son sus usos. Aunque no se almacenan en el archivo de bloqueo, los usos se consideran cuando se compara el estado actual de la extensión con el del archivo de bloqueo.

Prácticas recomendadas

Para maximizar los beneficios de la función de archivo de bloqueo, considera las siguientes prácticas recomendadas:

  • Actualiza con regularidad el archivo de bloqueo para reflejar los cambios en las dependencias o la configuración del proyecto. Esto garantiza que las compilaciones posteriores se basen en el conjunto de dependencias más actualizado y preciso.

  • Incluye el archivo de bloqueo en el control de versión para facilitar la colaboración y asegurarte de que todos los miembros del equipo tengan acceso al mismo archivo de bloqueo, lo que promueve entornos de desarrollo coherentes en todo el proyecto.

Si sigues estas prácticas recomendadas, puedes usar de manera eficaz la función del archivo de bloqueo en Bazel, lo que genera flujos de trabajo de desarrollo de software más eficientes, confiables y colaborativos.