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 solo se puede usar en el archivo WORKSPACE
y que habilita la operación no hermética en la fase de carga de Bazel. Cada regla de repositorio externo crea su propio espacio de trabajo, con sus propios archivos y artefactos BUILD
. 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.
Una regla de repositorio personalizada se puede usar como una regla de repositorio nativa. Tiene un atributo name
obligatorio, y se puede hacer referencia a cada destino presente en sus archivos de compilación como @<name>//package:target
, donde <name>
es el valor del atributo name
.
La regla se carga cuando la compilas de forma explícita o si es una dependencia de la compilación. En este caso, Bazel ejecutará su función implementation
. En esta función, se 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 del 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 (al igual que 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 para las reglas de repositorio nativas local_repository
y new_local_repository
.
Si un nombre de atributo comienza con _
, es privado y los usuarios no pueden establecerlo.
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 devuelve None
para indicar que la regla es reproducible con los parámetros especificados o un diccionario con un conjunto de parámetros para esa regla que la convertirían en una regla reproducible que genera el mismo repositorio. Por ejemplo, para una regla que hace un seguimiento de un repositorio de Git, esto significaría devolver 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 (buscar un archivo binario, ejecutar un archivo binario, 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
, cualquier cambio en una dependencia del gráfico de dependencias (incluido el propio archivo WORKSPACE
) provocará la 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 resuelva la dependencia. Para evitar reinicios innecesarios (que son costosos, ya que es posible que se deba repetir el acceso a la red), se recuperan previamente los argumentos de etiquetas, siempre que todos los argumentos de etiquetas se puedan resolver en un archivo existente. Ten en cuenta que resolver una ruta de acceso a partir de una cadena o una etiqueta que se construyó solo durante la ejecución de la función aún podría causar un reinicio.
Por último, en el caso de los repositorios que no son de local
, solo un cambio en las siguientes dependencias podría provocar un reinicio:
- Archivos
.bzl
necesarios para definir la regla del repositorio. - Declaración de la regla del repositorio en el archivo
WORKSPACE
- Valor de cualquier variable de entorno declarada con el atributo
environ
de la funciónrepository_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 use y al que haga referencia una etiqueta (por ejemplo,
//mypkg:label.txt
y nomypkg/label.txt
).
Cómo forzar la recuperación de repositorios externos
A veces, un repositorio externo puede quedar desactualizado sin que se modifique su definición o sus dependencias. Por ejemplo, un repositorio que recupera fuentes podría seguir una rama específica de un repositorio de terceros, y hay nuevas confirmaciones disponibles en esa rama. En este caso, puedes pedirle a Bazel que vuelva a recuperar todos los repositorios externos de forma incondicional llamando a bazel sync
.
Además, algunas reglas inspeccionan la máquina local y podrían quedar obsoletas si se actualizó. Aquí puedes pedirle a Bazel que solo vuelva a recuperar los repositorios externos en los que la definición de repository_rule
tenga establecido el atributo configure
, usa bazel sync --configure
.
Ejemplos
Cadena de herramientas de C++ configurada automáticamente: Utiliza una regla de repositorio para crear automáticamente los archivos de configuración de C++ para Bazel buscando el compilador de C++ local, el entorno y las marcas que admite el compilador de C++.
Go repositories usa varios
repository_rule
para definir la lista de dependencias necesarias para usar las reglas de Go.rules_jvm_external crea un repositorio externo llamado
@maven
de forma predeterminada que genera destinos de compilación para cada artefacto de Maven en el árbol de dependencias transitivas.