La especificación completa del protocolo de eventos de compilación se puede encontrar en su definición de búfer de protocolo. Sin embargo, puede ser útil desarrollar cierta intuición antes de consultar la especificación.
Considera un espacio de trabajo simple de Bazel que consta de dos secuencias de comandos de shell vacías
foo.sh y foo_test.sh y el siguiente archivo BUILD:
sh_library(
name = "foo_lib",
srcs = ["foo.sh"],
)
sh_test(
name = "foo_test",
srcs = ["foo_test.sh"],
deps = [":foo_lib"],
)
Cuando ejecutes bazel test ... en este proyecto, el gráfico de compilación de los eventos de compilación generados
se parecerá al siguiente gráfico. Las flechas indican la
relación superior y secundario mencionada anteriormente. Ten en cuenta que se omitieron algunos eventos de compilación y
la mayoría de los campos para mayor brevedad.

Figura 1: Gráfico de BEP
Inicialmente, se publica un evento BuildStarted. El evento nos informa que se
invocó la compilación a través del bazel test comando y anuncia eventos secundarios:
OptionsParsedWorkspaceStatusCommandLineUnstructuredCommandLineBuildMetadataBuildFinishedPatternExpandedProgress
Los primeros tres eventos proporcionan información sobre cómo se invocó Bazel.
El evento de compilación PatternExpanded proporciona información
sobre los destinos específicos a los que se expandió el patrón ...:
//foo:foo_lib y //foo:foo_test. Para ello, declara dos
TargetConfigured eventos como secundarios. Ten en cuenta que el evento TargetConfigured
declara el evento Configuration como un evento secundario, aunque Configuration
se publicó antes del evento TargetConfigured.
Además de la relación superior y secundario, los eventos también pueden hacer referencia entre sí
con sus identificadores de eventos de compilación. Por ejemplo, en el gráfico anterior, el
TargetComplete evento hace referencia al NamedSetOfFiles evento en su fileSets
campo.
Los eventos de compilación que hacen referencia a archivos no suelen incorporar los nombres
y las rutas de acceso de los archivos en el evento. En cambio, contienen el identificador de evento de compilación
de un NamedSetOfFiles evento, que luego contendrá los nombres y las rutas de acceso de los archivos reales. El evento NamedSetOfFiles permite que se informe un conjunto de archivos una vez y
que se haga referencia a él en muchos destinos. Esta estructura es necesaria porque, de lo contrario, en
algunos casos, el tamaño de salida del protocolo de eventos de compilación crecería de forma cuadrática con
la cantidad de archivos. Es posible que un evento NamedSetOfFiles tampoco tenga todos sus archivos
incorporados, sino que haga referencia a otros eventos NamedSetOfFiles a través de sus
identificadores de eventos de compilación.
A continuación, se muestra una instancia del evento TargetComplete para el //foo:foo_lib
destino del gráfico anterior, impresa en la representación JSON del búfer de protocolo.
El identificador de evento de compilación contiene el destino como una cadena opaca y hace referencia a
el evento Configuration con su identificador de evento de compilación. El evento no
anuncia ningún evento secundario. La carga útil contiene información sobre si el
destino se compiló correctamente, el conjunto de archivos de salida y el tipo de destino
compilado.
{
"id": {
"targetCompleted": {
"label": "//foo:foo_lib",
"configuration": {
"id": "544e39a7f0abdb3efdd29d675a48bc6a"
}
}
},
"completed": {
"success": true,
"outputGroup": [{
"name": "default",
"fileSets": [{
"id": "0"
}]
}],
"targetKind": "sh_library rule"
}
}
Resultados de aspectos en BEP
Las compilaciones comunes evalúan las acciones asociadas con los (target, configuration)
pares. Cuando se compila con los aspectos habilitados, Bazel
también evalúa los destinos asociados con las tuplas (target, configuration,
aspect), para cada destino afectado por un aspecto habilitado determinado.
Los resultados de la evaluación de los aspectos están disponibles en BEP a pesar de la ausencia de
tipos de eventos específicos de los aspectos. Para cada par (target, configuration) con un
aspecto aplicable, Bazel publica un evento TargetConfigured y
TargetComplete adicional que contiene el resultado de aplicar el aspecto al
destino. Por ejemplo, si //:foo_lib se compila con
--aspects=aspects/myaspect.bzl%custom_aspect, este evento también aparecerá en
el BEP:
{
"id": {
"targetCompleted": {
"label": "//foo:foo_lib",
"configuration": {
"id": "544e39a7f0abdb3efdd29d675a48bc6a"
},
"aspect": "aspects/myaspect.bzl%custom_aspect"
}
},
"completed": {
"success": true,
"outputGroup": [{
"name": "default",
"fileSets": [{
"id": "1"
}]
}]
}
}
Cómo consumir NamedSetOfFiles
Determinar los artefactos producidos por un destino (o aspecto) determinado es un caso de uso común
de BEP que se puede realizar de manera eficiente con cierta preparación. En esta sección
se analiza la estructura recursiva y compartida que ofrece el NamedSetOfFiles
evento, que coincide con la estructura de un Depset de Starlark.
Los consumidores deben tener cuidado para evitar algoritmos cuadráticos cuando procesan
NamedSetOfFiles eventos, ya que las compilaciones grandes pueden contener decenas de miles de
eventos de este tipo, lo que requiere cientos de millones de operaciones en un recorrido con
complejidad cuadrática.

Figura 2: Gráfico de BEP de NamedSetOfFiles
Un evento NamedSetOfFiles siempre aparece en la transmisión de BEP antes de un evento
TargetComplete o NamedSetOfFiles que haga referencia a él. Esta es la
inversa de la relación de eventos "superior-secundario", en la que todos los eventos, excepto el primero,
aparecen después de al menos un evento que lo anuncia. Un evento NamedSetOfFiles se
anuncia con un evento Progress sin semántica.
Dadas estas restricciones de ordenamiento y uso compartido, un consumidor típico debe almacenar en búfer todos los
NamedSetOfFiles eventos hasta que se agote la transmisión de BEP. En la siguiente transmisión de eventos JSON
y código de Python, se muestra cómo propagar un mapa de
destino o aspecto a artefactos compilados en el grupo de salida "predeterminado" y cómo
procesar las salidas para un subconjunto de destinos o aspectos compilados:
named_sets = {} # type: dict[str, NamedSetOfFiles]
outputs = {} # type: dict[str, dict[str, set[str]]]
for event in stream:
kind = event.id.WhichOneof("id")
if kind == "named_set":
named_sets[event.id.named_set.id] = event.named_set_of_files
elif kind == "target_completed":
tc = event.id.target_completed
target_id = (tc.label, tc.configuration.id, tc.aspect)
outputs[target_id] = {}
for group in event.completed.output_group:
outputs[target_id][group.name] = {fs.id for fs in group.file_sets}
for result_id in relevant_subset(outputs.keys()):
visit = outputs[result_id].get("default", [])
seen_sets = set(visit)
while visit:
set_name = visit.pop()
s = named_sets[set_name]
for f in s.files:
process_file(result_id, f)
for fs in s.file_sets:
if fs.id not in seen_sets:
visit.add(fs.id)
seen_sets.add(fs.id)