Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ def assumed_system_requirements(
deps: Optional list of requirement targets whose TRLC records are needed
for cross-reference parsing. These targets must provide
TrlcProviderInfo. Typically empty for top-level system requirements.
spec: Optional TRLC specification target providing RSL type definitions.
Defaults to the S-CORE requirements model
spec: TRLC specification target(s) providing RSL type definitions.
Accepts a single label or a list of labels; all are merged into the
spec passed to TRLC. Defaults to the S-CORE requirements model
(``@score_tooling//bazel/rules/rules_score/trlc/config:score_requirements_model``).
Override this when using a custom requirements model.
lobster_config: Optional Lobster extraction config label. Defaults to the
Expand Down
6 changes: 3 additions & 3 deletions bazel/rules/rules_score/private/component_requirements.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ def component_requirements(
deps: Optional list of requirement targets (e.g. assumed_system_requirements,
feature_requirements) whose TRLC records are needed for cross-reference
parsing. These targets must provide TrlcProviderInfo.
spec: Optional TRLC specification target providing RSL type definitions.
Defaults to the S-CORE requirements model
spec: TRLC specification target(s) providing RSL type definitions.
Accepts a single label or a list of labels; all are merged into the
spec passed to TRLC. Defaults to the S-CORE requirements model
(``@score_tooling//bazel/rules/rules_score/trlc/config:score_requirements_model``).
Override this when using a custom requirements model.
lobster_config: Optional Lobster extraction config label. Defaults to the
S-CORE component requirement config.
visibility: Bazel visibility specification for the generated targets.
Expand Down
6 changes: 3 additions & 3 deletions bazel/rules/rules_score/private/feature_requirements.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ def feature_requirements(
deps: Optional list of requirement targets (e.g. assumed_system_requirements)
whose TRLC records are needed for cross-reference parsing. These
targets must provide TrlcProviderInfo.
spec: Optional TRLC specification target providing RSL type definitions.
Defaults to the S-CORE requirements model
spec: TRLC specification target(s) providing RSL type definitions.
Accepts a single label or a list of labels; all are merged into the
spec passed to TRLC. Defaults to the S-CORE requirements model
(``@score_tooling//bazel/rules/rules_score/trlc/config:score_requirements_model``).
Override this when using a custom requirements model.
lobster_config: Optional Lobster extraction config label. Defaults to the
S-CORE feature requirement config.
visibility: Bazel visibility specification for the generated targets.
Expand Down
19 changes: 13 additions & 6 deletions bazel/rules/rules_score/private/requirements.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ load("@trlc//:trlc.bzl", "TrlcProviderInfo", "subrule_trlc_image_stage")
load("//bazel/rules/rules_score:providers.bzl", "AssumedSystemRequirementsInfo", "AssumptionsOfUseInfo", "ComponentRequirementsInfo", "FeatureRequirementsInfo", "SphinxSourcesInfo")
load("//bazel/rules/rules_score/private:rst_to_trlc.bzl", "rst_to_trlc")

_DEFAULT_SPEC = Label("//bazel/rules/rules_score/trlc/config:score_requirements_model")

# ============================================================================
# Private Rule Implementation
# ============================================================================
Expand All @@ -50,7 +52,7 @@ def _requirements_impl(ctx):
transitive_reqs.append(trlc_info.reqs)
transitive_reqs.append(trlc_info.deps)

own_spec_files = ctx.attr.spec[DefaultInfo].files
own_spec_files = depset(transitive = [t[DefaultInfo].files for t in ctx.attr.spec])
spec_depset = depset(transitive = [own_spec_files] + transitive_spec)
deps_depset = depset(transitive = transitive_reqs)

Expand Down Expand Up @@ -167,9 +169,9 @@ _score_requirements_rule = rule(
mandatory = True,
doc = "Lobster YAML configuration file for traceability extraction.",
),
"spec": attr.label(
default = Label("//bazel/rules/rules_score/trlc/config:score_requirements_model"),
doc = "TRLC specification target providing the RSL files that define the requirement types. Defaults to the S-CORE requirements model.",
"spec": attr.label_list(
default = [_DEFAULT_SPEC],
doc = "TRLC specification targets providing the RSL files that define the requirement types. The S-CORE requirements model is always included; this adds zero or more additional spec targets on top of it. Populated by the score_requirements_rule macro, which performs the merge.",
),
"image_srcs": attr.label_list(
allow_files = [".svg", ".png", ".puml"],
Expand All @@ -192,7 +194,7 @@ def score_requirements_rule(
req_kind,
lobster_config,
deps = [],
spec = Label("//bazel/rules/rules_score/trlc/config:score_requirements_model"),
spec = [],
ref_package = "",
**kwargs):
"""Macro wrapper around _score_requirements_rule with RST support.
Expand All @@ -207,6 +209,9 @@ def score_requirements_rule(
listed in the underlying rule's ``srcs``.

Args:
spec: Additional TRLC specification target(s) (single label or list)
to merge in on top of the S-CORE requirements model, which is
always included automatically -- do not re-list it here.
ref_package: TRLC package prefix used for derived_from cross-references
when converting RST sources (e.g. "AssumedSystemRequirements" for
feature requirements that derive from ASR).
Expand All @@ -216,6 +221,8 @@ def score_requirements_rule(
conversion), in the same order. Useful for callers that need to run
trlc_requirements_test against the same source set.
"""
extra_spec = spec if type(spec) == type([]) else [spec]
merged_spec = [_DEFAULT_SPEC] + [s for s in extra_spec if s != _DEFAULT_SPEC]
trlc_srcs = []
extra_deps = []
resolved_srcs = []
Expand All @@ -242,7 +249,7 @@ def score_requirements_rule(
deps = deps + extra_deps,
req_kind = req_kind,
lobster_config = lobster_config,
spec = spec,
spec = merged_spec,
**kwargs
)

Expand Down
72 changes: 68 additions & 4 deletions bazel/rules/rules_score/test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

load("@pip_tooling_test//:requirements.bzl", "requirement")
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
load("@rules_python//python:defs.bzl", "py_test")
load("@rules_shell//shell:sh_test.bzl", "sh_test")
load(
"@score_tooling//bazel/rules/rules_score:rules_score.bzl",
"architectural_design",
Expand All @@ -30,7 +32,7 @@ load(
)
load("@score_tooling//bazel/rules/rules_score:sphinx_toolchain.bzl", "score_sphinx_toolchain")
load("@score_tooling//cpp/libclang:libclang_toolchain.bzl", "libclang_toolchain")
load("@trlc//:trlc.bzl", "trlc_requirements", "trlc_requirements_test")
load("@trlc//:trlc.bzl", "trlc_requirements", "trlc_requirements_test", "trlc_specification")
load(
":html_generation_test.bzl",
"auto_config_generation_test",
Expand All @@ -48,9 +50,11 @@ load(
"lobster_config_test_suite",
)
load(
":requirements_image_test.bzl",
"image_srcs_sphinx_sources_test",
"requirements_image_test_suite",
":requirements_multi_spec_test.bzl",
"asr_multi_spec_provider_test",
"comp_req_multi_spec_provider_test",
"feat_req_multi_spec_provider_test",
"requirements_multi_spec_test_suite",
)
load(
":requirements_rst_test.bzl",
Expand Down Expand Up @@ -1369,6 +1373,65 @@ aous_rst_sphinx_test(

requirements_rst_test_suite(name = "requirements_rst_tests")

# ============================================================================
# Multi-spec Requirements Tests
# ============================================================================

trlc_specification(
name = "extra_spec_fixture",
srcs = ["fixtures/multi_spec/extra_model.rsl"],
)

assumed_system_requirements(
name = "asr_multi_spec",
srcs = ["fixtures/rst_requirements/assumed_system_requirements.rst"],
spec = [":extra_spec_fixture"],
)

feature_requirements(
name = "feat_req_multi_spec",
srcs = ["fixtures/rst_requirements/feature_requirements.rst"],
ref_package = "AssumedSystemRequirements",
spec = [":extra_spec_fixture"],
deps = [":asr_multi_spec"],
)

component_requirements(
name = "comp_req_multi_spec",
srcs = ["fixtures/rst_requirements/component_requirements.rst"],
ref_package = "FeatureRequirements",
spec = [":extra_spec_fixture"],
deps = [
":asr_multi_spec",
":feat_req_multi_spec",
],
)

asr_multi_spec_provider_test(
name = "asr_multi_spec_provider_test",
target_under_test = ":asr_multi_spec",
)

feat_req_multi_spec_provider_test(
name = "feat_req_multi_spec_provider_test",
target_under_test = ":feat_req_multi_spec",
)

comp_req_multi_spec_provider_test(
name = "comp_req_multi_spec_provider_test",
target_under_test = ":comp_req_multi_spec",
)

# Integration target: TRLC file using types from both specs; trlc --verify
# runs on build, confirming both RSL files are reachable at parse time.
assumed_system_requirements(
name = "asr_multi_spec_inttest",
srcs = ["fixtures/multi_spec/multi_spec.trlc"],
spec = [":extra_spec_fixture"],
)

requirements_multi_spec_test_suite(name = "requirements_multi_spec_tests")

# ============================================================================
# lobster_config.bzl unit tests (format_lobster_sources / format_lobster_block)
# ============================================================================
Expand Down Expand Up @@ -1464,6 +1527,7 @@ test_suite(
name = "all_tests",
tests = [
":lobster_config_tests",
":requirements_multi_spec_tests",
":requirements_rst_tests",
":seooc_tests",
":sphinx_module_tests",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/********************************************************************************
* Copyright (c) 2026 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

// Project-specific model extension (fixture for multi-spec tests).
// Uses a distinct package name — TRLC does not allow two RSL files with the
// same package declaration.
package ProjectReq

type ProjectNote "A project-specific note for internal tracking." {
description "Note content."
String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/********************************************************************************
* Copyright (c) 2026 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

// Integration fixture: uses AssumedSystemReq (base model) and ProjectNote
// (extra model) in one file to verify that both RSL files are reachable when
// spec is passed as a list.
package MultiSpecIntTest

import ScoreReq
import ProjectReq

ScoreReq.AssumedSystemReq asr_multi_spec_inttest_001 {
description = "The system shall support multi-spec requirements models."
safety = ScoreReq.Asil.B
version = 1
rationale = "Validates that the base spec types are accessible when spec is a list."
}

ProjectReq.ProjectNote note_multi_spec_inttest_001 {
description = "Validates that a type from the extra spec is accessible alongside the base model."
}
28 changes: 28 additions & 0 deletions bazel/rules/rules_score/test/fixtures/spec_extras/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

load("@score_tooling//bazel/rules/rules_score:rules_score.bzl", "component_requirements")
load("@trlc//:trlc.bzl", "trlc_specification")

package(default_visibility = ["//visibility:public"])

trlc_specification(
name = "extra_spec",
srcs = ["extra_model.rsl"],
)

component_requirements(
name = "spec_extras_comp_req",
srcs = ["project_requirements.trlc"],
spec_extras = [":extra_spec"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/********************************************************************************
* Copyright (c) 2026 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

package ExtraModel
import ScoreReq

type ProjectSpecificReq extends ScoreReq.CompReq {
project_id "Project identifier" String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/********************************************************************************
* Copyright (c) 2026 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

package TestFixtures

import ExtraModel
import ScoreReq

ScoreReq.AssumedSystemReq ASR_TEST_001 {
description = "Input system-level requirement for spec_extras test"
rationale = "Needed to satisfy derived_from constraints"
safety = ScoreReq.Asil.B
version = 1
}

ExtraModel.ProjectSpecificReq PROJ_REQ_001 {
description = "Requirement using a type from spec_extras."
safety = ScoreReq.Asil.B
derived_from = [ASR_TEST_001@1]
version = 1
project_id = "TEST"
}
Loading
Loading