Reglas del repositorio

Informar un problema Ver fuente Por la noche · 7.4 de Google Cloud. 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

Un repositorio externo es una regla que solo se puede usar en el archivo WORKSPACE y 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. Pueden usarse para depender de terceros (como las bibliotecas empaquetadas de Maven), pero también para generar archivos BUILD específica 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 de la misma manera que una regla de repositorio nativo. Tiene un atributo name obligatorio, y cada destino presente en sus archivos de compilación se puede denominar @<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

Los atributos son argumentos de reglas que se pasan como un diccionario al argumento de la regla attrs. Los atributos y sus tipos se definen cuando defines una regla del repositorio. Un ejemplo en el que se definen los atributos url y sha256 como strings:

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

Para acceder a un atributo dentro de la función de implementación, use repository_ctx.attr.<attribute_name>

def _impl(repository_ctx):
    url = repository_ctx.attr.url
    checksum = repository_ctx.attr.sha256

Todos los repository_rule tienen atributos definidos de forma implícita (al igual que la compilación reglas). Los dos atributos implícitos son name (al igual que ocurre con las reglas de compilación) 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 es reproducible dados los parámetros especificados, o bien un diccionario con un conjunto de parámetros para esa regla que la convertiría en una reproducible que genera el mismo repositorio. Por ejemplo, para una regla que realiza un seguimiento de un repositorio de git, eso significaría 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 los valores de los atributos y a las funciones no herméticas (encontrar un objeto binario, ejecutarlo, crear un archivo en el repositorio o descargar un archivo de Internet). Consulta la biblioteca para obtener más información. 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?

La función de implementación de un repositorio se ejecuta cuando Bazel necesita un objetivo de ese repositorio, por ejemplo, cuando otro objetivo (en otro repositorio) depende de él o si se menciona en la línea de comandos. El de implementación cree el repositorio en el archivo en un sistema de archivos. Esto se denomina “recuperar” el repositorio.

A diferencia de los objetivos normales, los repositorios no se vuelven a recuperar necesariamente cuando cambia algo que haría que el repositorio fuera diferente. Esto se debe a que hay elementos en los que Bazel no puede detectar cambios o que causarían demasiada sobrecarga en cada compilación (por ejemplo, elementos que se recuperan de la red). Por lo tanto, los repositorios se vuelven a recuperar solo si uno de los los siguientes cambios:

  • Son los parámetros que se pasan a la declaración del repositorio en el archivo WORKSPACE.
  • El código Starlark que comprende la implementación del repositorio
  • El valor de cualquier variable de entorno que se pase a la de repository_ctx getenv() o se declaró con el atributo environ de la repository_rule Los valores de estas variables de entorno se pueden configurar de forma fija en la línea de comandos con la marca --repo_env.
  • El contenido de cualquier archivo que se pase a read(), execute() y otros similares métodos de repository_ctx a los que hace referencia una etiqueta (por ejemplo, //mypkg:label.txt, pero no mypkg/label.txt)
  • Cuando se ejecuta bazel sync.

Hay dos parámetros de repository_rule que controlan cuándo se crean se vuelven a recuperar:

  • Si se establece la marca configure, el repositorio solo se vuelve a recuperar el bazel sync cuando se le pasa el parámetro --configure (si el no está establecido, este comando no hará que se vuelva a recuperar)
  • Si se establece la marca local, además de los casos anteriores, el repositorio también también se vuelve a recuperar cuando se reinicia el servidor de Bazel o cuando cualquier archivo que afecte cambia la declaración del repositorio (p.ej., el archivo WORKSPACE o un archivo carga), sin importar si los cambios generaron un cambio en la del repositorio o su código.

    En estos casos, no se vuelven a recuperar los repositorios no locales. Esto se debe a que se supone que estos repositorios se comunican con la red o están costoso.

Cómo reiniciar la función de implementación

La función de implementación se puede reiniciar mientras se recupera un repositorio si falta una dependencia que solicita. En ese caso, se detendrá la ejecución de la función de implementación, se resolverá la dependencia faltante y se volverá a ejecutar la función 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), los argumentos de etiqueta se precargan, siempre que todos los argumentos de etiqueta 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 aún podría causar un reinicio.

Cómo forzar la actualizació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 puede seguir una rama en particular de un repositorio de terceros, y las confirmaciones nuevas están 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 estar desactualizado si la máquina local se actualizó. Aquí puedes pedirle a Bazel que solo recuperar los repositorios externos en los que repository_rule definición tiene establecido el atributo configure, usa bazel sync --configure.

Ejemplos

  • Cadena de herramientas configurada automáticamente para C++: Usa 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++.

  • Repositorios de Go 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 Maven en el árbol de dependencias transitivo.