Reglas del repositorio

En esta página, se explica cómo crear reglas de repositorio y se proporcionan ejemplos para obtener más detalles.

Un repositorio externo es una regla que se puede usar solo en el archivo WORKSPACE y habilita una operación no hermética en la fase de carga de Bazel. Cada regla de repositorio externo crea su propio lugar de trabajo, con sus propios archivos BUILD y artefactos. Se pueden usar para depender de bibliotecas de terceros (como las bibliotecas empaquetadas de Maven), pero también para generar archivos BUILD específicos del host en el que se ejecuta Bazel.

Creación de reglas de repositorio

En un archivo .bzl, usa la función repository_rule para crear una regla de repositorio nueva y almacenarla en una variable global.

Se puede usar una regla de repositorio personalizada al igual que una regla de repositorio nativa. Tiene un atributo name obligatorio y cada destino presente en sus archivos de compilación puede denominarse @<name>//package:target, en el que <name> es el valor del atributo name.

La regla se carga cuando la compilas explícitamente o si es una dependencia de la compilación. En este caso, Bazel ejecutará su función implementation. Esta función describe cómo crear el repositorio, su contenido y los archivos BUILD.

Atributos

Un atributo es un argumento de regla, como url o sha256. Debes enumerar los atributos y sus tipos cuando definas una regla de repositorio.

local_repository = repository_rule(
    implementation=_impl,
    local=True,
    attrs={"path": attr.string(mandatory=True)})

Para acceder a un atributo, usa repository_ctx.attr.<attribute_name>.

Todos los repository_rule tienen atributos definidos de forma implícita (como las reglas de compilación). Los dos atributos implícitos son name (al igual que para las reglas de compilación) y repo_mapping. Se puede acceder al nombre de una regla de repositorio con repository_ctx.name. El significado de repo_mapping es el mismo que el de las reglas del repositorio nativo local_repository y new_local_repository.

Si el nombre de un atributo comienza con _, es privado y los usuarios no pueden configurarlo.

Función de implementación

Cada regla de repositorio requiere una función implementation. Contiene la lógica real de la regla y se ejecuta estrictamente en la fase de carga.

La función tiene exactamente un parámetro de entrada, repository_ctx. La función muestra None para indicar que la regla se puede reproducir según los parámetros especificados, o un dict con un conjunto de parámetros para esa regla que convertiría esa regla en una reproducible que genera el mismo repositorio. Por ejemplo, para una regla que realiza un seguimiento de un repositorio de Git que significa mostrar un identificador de confirmación específico en lugar de una rama flotante que se especificó originalmente.

El parámetro de entrada repository_ctx se puede usar para acceder a valores de atributos y funciones no herméticas (por ejemplo, para buscar o ejecutar un objeto binario, o bien para crear un archivo en el repositorio o descargar un archivo de Internet). Consulta la biblioteca para obtener más contexto. Ejemplo:

def _impl(repository_ctx):
  repository_ctx.symlink(repository_ctx.attr.path, "")

local_repository = repository_rule(
    implementation=_impl,
    ...)

¿Cuándo se ejecuta la función de implementación?

Si el repositorio se declara como local, el cambio en una dependencia en el gráfico de dependencias (incluido el archivo WORKSPACE) provocará una ejecución de la función de implementación.

La función de implementación se puede reiniciar si falta una dependencia que solicita. El comienzo de la función de implementación se volverá a ejecutar después de que se haya resuelto la dependencia. Para evitar reinicios innecesarios (que son costosos, ya que el acceso a la red podría tener que repetirse), los argumentos de las etiquetas se cargan previamente, siempre que todos los argumentos de las etiquetas se puedan resolver en un archivo existente. Ten en cuenta que resolver una ruta de acceso a partir de una string o una etiqueta que se construyó solo durante la ejecución de la función puede causar un reinicio.

Por último, para los repositorios que no sean local, solo un cambio en las siguientes dependencias puede causar un reinicio:

  • .bzl archivos necesarios para definir la regla del repositorio.
  • Declaración de la regla de repositorio en el archivo WORKSPACE.
  • Valor de cualquier variable de entorno declarada con el atributo environ de la función repository_rule. El valor de esas variables de entorno se puede aplicar desde la línea de comandos con la marca --action_env (pero esta marca invalidará todas las acciones de la compilación).
  • Contenido de cualquier archivo que una etiqueta usa y al que hace referencia (por ejemplo, //mypkg:label.txt en lugar de mypkg/label.txt)

Fuerza la recuperación de repositorios externos

A veces, un repositorio externo puede quedar desactualizado sin ningún cambio en su definición o dependencias. Por ejemplo, un repositorio que recupera fuentes podría seguir una rama específica de un repositorio de terceros, y las confirmaciones nuevas están disponibles en esa rama. En este caso, puedes pedirle a Bazel que recupere todos los repositorios externos de manera incondicional llamando a bazel sync.

Además, algunas reglas inspeccionan la máquina local y podrían quedar desactualizadas si esta se actualiza. Aquí, puedes pedirle a Bazel que vuelva a recuperar solo los repositorios externos en los que la definición de repository_rule tenga configurado el atributo configure. Usa bazel sync --configure.

Ejemplos

  • Cadena de herramientas configurada automáticamente de C++: Usa una regla de repositorio para crear automáticamente los archivos de configuración de C++ para Bazel mediante la búsqueda del compilador de C++ local, el entorno y las marcas que admite el compilador de C++.

  • Los repositorios de Go usan varios repository_rule para definir la lista de dependencias necesarias a fin de usar las reglas de Go.

  • rules_jvm_external crea un repositorio externo llamado @maven de forma predeterminada que genera objetivos de compilación para cada artefacto de Maven en el árbol de dependencias transitivas.