Bazel Component Specification

Purpose

This validator enforces consistency between the implemented Bazel SW architecture and the targetted architecture in PlantUML component diagram.

It shall make sure that the same architectural elements exist on both sides and are related in the same way.

What is Validated

architectural_design.static may list more than one PlantUML file (e.g. a boundary overview diagram plus one or more detail diagrams); these are merged into a single component diagram model before this validator runs, so the checks below operate on that merged view regardless of how many static files contributed to it. See the architectural_design rule reference for the cross-file merge rules.

All comparisons are case-insensitive: both Bazel entity keys and PlantUML names are normalized to lowercase before matching, so a Bazel entity Component_X matches a PlantUML entity COMPONENT_X. The PlantUML name is the last segment of the entity id; an as alias is a local key for relations and does not take part in matching. On the Bazel side, each unit/component entry carries a design_name (the design_name attribute passed to the unit/component macro, defaulting to the target’s short name) which is used as the entity key, also lowercased. Parent names are lowercased the same way when resolving parent-child relationships.

Dependable Element Consistency

Every PlantUML package <<SEooC>> must have a corresponding Bazel dependable_element target, and vice versa. (Requirement: Tools.BazelComponentDependableElementConsistency)

dependable_element(
  name = "safety_software_seooc_example",
  components = [":component_example"],
)
package safety_software_seooc_example <<SEooC>> {
}

Component Consistency

Every PlantUML <<component>> must have a corresponding Bazel component target under the same parent dependable element, and vice versa. (Requirement: Tools.BazelComponentComponentConsistency)

component(
  name = "component_example",
  components = [
    "//bazel/rules/rules_score/examples/seooc/unit_1:unit_1",
    "//bazel/rules/rules_score/examples/seooc/unit_2:unit_2",
  ],
)
package safety_software_seooc_example <<SEooC>> {
    component component_example <<component>> {
    }
}

Unit Consistency

Every PlantUML <<unit>> must have a corresponding Bazel unit target under the same parent component, and vice versa. (Requirement: Tools.BazelComponentUnitConsistency)

unit(
  name = "unit_1",
)

unit(
  name = "unit_2",
)
component component_example <<component>> {
    component unit_1 <<unit>>
    component unit_2 <<unit>>
}

Parent Context

In the common case, components nested directly under the dependable element use the dependable element name as parent. More deeply nested components use their immediate enclosing component name as parent. (Requirements: Tools.BazelComponentNameCaseInsensitive, Tools.BazelComponentParentContext)

Bazel Label Format Validation

Every Bazel label must define a target name. A label such as @//pkg: (a colon with nothing following it) has no target name and is rejected with a [Design] error before any entity matching happens – this check runs independently of design_name, so a malformed label is still rejected even though design_name is the actual match key.

Duplicate Entity Detection

The validator detects when two entities of the same kind normalize to the same key (same lowercased name under the same parent):

  • In Bazel: if two different Bazel targets (e.g. under different packages) would both map to the same dependable-element, component, or unit key, a [Design] error is reported naming both Bazel labels.

  • In the PlantUML diagram: entity IDs are matched case-insensitively, so two entities such as MyDE and myDE collide. A [Design] error is reported showing both source file locations, even if their stereotypes differ.

Parent Reference Validity

Every PlantUML entity’s parent_id (if present) must resolve to another entity defined in the same component diagram. An entity referencing an undefined parent is rejected with a [Design] error naming the missing parent ID.

Non-Empty Composition

Every Bazel dependable_element and component target must decompose into at least one nested component or unit. A target with an empty components attribute (and, for components, no nested unit) is reported even if the PlantUML diagram agrees and shows the same element as empty – the set-difference checks above only compare presence between Bazel and PlantUML, so a childless entry that matches on both sides would otherwise go unnoticed. (Requirement: Tools.BazelComponentNonEmptyComposition)

# Flagged: component_example has no nested unit() or component().
component(
  name = "component_example",
  components = [],
)

Failure Cases

Failure case

Validation rule

Missing dependable element in PlantUML

Dependable Element Consistency

Extra dependable element in PlantUML

Dependable Element Consistency

Missing component in PlantUML

Component Consistency

Extra component in PlantUML

Component Consistency

Missing unit in PlantUML

Unit Consistency

Extra unit in PlantUML

Unit Consistency

Invalid Bazel label (no target name after :)

Bazel Label Format Validation

Duplicate Bazel entity key (same name/parent from different labels)

Duplicate Entity Detection

Duplicate PlantUML entity ID (case-insensitive collision)

Duplicate Entity Detection

PlantUML entity references an undefined parent

Parent Reference Validity

Empty dependable element in Bazel build graph

Non-Empty Composition

Empty component in Bazel build graph

Non-Empty Composition

PlantUML Stereotype Reference

The validator identifies elements by their stereotype, not by the PlantUML keyword. Both package and component keywords are accepted for each role, but the stereotype must match exactly: a Bazel component target will not match a PlantUML entity marked <<SEooC>>, even though both use compatible keywords.

Stereotype

Valid PlantUML keywords

Meaning

Bazel rule

<<SEooC>>

package, component

Safety Element out of Context boundary

dependable_element

<<component>>

component, package

Architectural component

component

<<unit>>

component, package

Leaf implementation unit

unit

Port declarations and interface bindings (portin/portout, -(/)-) are not validated by this validator; they are checked by the internal/public API and sequence validators instead.

Debug Output

The validator emits debug output containing:

  • all diagram entities

  • filtered entity counts

  • all normalized PlantUML keys

  • all normalized Bazel keys