Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
common --registry=https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/
common --registry=https://bcr.bazel.build

build --java_language_version=17
build --tool_java_language_version=17
build --java_runtime_version=remotejdk_17
build --tool_java_runtime_version=remotejdk_17
14 changes: 11 additions & 3 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ bazel_dep(name = "rules_java", version = "8.15.1")
bazel_dep(name = "rules_rust", version = "0.61.0")
bazel_dep(name = "rules_multitool", version = "1.9.0")
bazel_dep(name = "score_rust_policies", version = "0.0.2")

bazel_dep(name = "bazel_skylib", version = "1.7.1", dev_dependency = True)

bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "buildifier_prebuilt", version = "8.2.0.2")

###############################################################################
Expand Down Expand Up @@ -95,3 +93,13 @@ multitool.hub(
lockfile = "tools/yamlfmt.lock.json",
)
use_repo(multitool, "yamlfmt_hub")

bazel_dep(name = "score_docs_as_code", version = "2.2.0")
git_override(
module_name = "score_docs_as_code",
commit = "718388bd5e0f10debd97a131d238ad4d758ddd1e",
remote = "https://github.com/eclipse-score/docs-as-code.git",
)

bazel_dep(name = "score_platform", version = "0.5.0")
bazel_dep(name = "score_process", version = "1.3.2")
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,15 @@ bazel run //:rust_coverage -- --min-line-coverage 80

## Upgrading from separate MODULES

If you are still using separate module imports and want to upgrade to the new version.
If you are still using separate module imports and want to upgrade to the new version.
Here are two examples to showcase how to do this.

```
load("@score_python_basics//:defs.bzl", "score_py_pytest") => load("@score_tooling//:defs.bzl", "score_py_pytest")
load("@score_cr_checker//:cr_checker.bzl", "copyright_checker") => load("@score_tooling//:defs.bzl", "copyright_checker")
```
All things inside of 'tooling' can now be imported from `@score_tooling//:defs.bzl`.

All things inside of 'tooling' can now be imported from `@score_tooling//:defs.bzl`.
The available import targets are:

- score_virtualenv
Expand All @@ -78,6 +79,7 @@ The available import targets are:
- rust_coverage_report

## Format the tooling repository
```bash

```bash
bazel run //:format.fix
```
51 changes: 51 additions & 0 deletions bazel/rules/rules_score/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
load(
"//bazel/rules/rules_score:rules_score.bzl",
"sphinx_module",
)

exports_files([
"templates/conf.template.py",
"templates/seooc_index.template.rst",
])

# HTML merge tool
py_binary(
name = "sphinx_html_merge",
srcs = ["src/sphinx_html_merge.py"],
main = "src/sphinx_html_merge.py",
visibility = ["//visibility:public"],
)

# Sphinx build binary with all required dependencies
py_binary(
name = "score_build",
srcs = ["src/sphinx_wrapper.py"],
data = [],
env = {
"SOURCE_DIRECTORY": "",
"DATA": "",
"ACTION": "check",
},
main = "src/sphinx_wrapper.py",
visibility = ["//visibility:public"],
deps = [
"@score_docs_as_code//src:plantuml_for_python",
"@score_docs_as_code//src/extensions/score_sphinx_bundle",
],
)

sphinx_module(
name = "rules_score_doc",
srcs = glob(
[
"docs/**/*.rst",
"docs/**/*.puml",
],
allow_empty = True,
),
index = "docs/index.rst",
visibility = ["//visibility:public"],
deps = [
"@score_process//:score_process_module",
],
)
258 changes: 258 additions & 0 deletions bazel/rules/rules_score/docs/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
SCORE Rules for Bazel
=====================

This package provides Bazel build rules for defining and building SCORE documentation modules with integrated Sphinx-based HTML generation.

.. contents:: Table of Contents
:depth: 2
:local:


Overview
--------

The ``rules_score`` package provides Bazel rules for structuring and documenting safety-critical software following S-CORE process guidelines:

**Documentation Rule:**

- ``sphinx_module``: Generic rule for building Sphinx HTML documentation with dependency support

**Artifact Rules:**

- ``feature_requirements``: High-level feature specifications
- ``component_requirements``: Component-level requirements
- ``assumptions_of_use``: Safety-relevant operating conditions
- ``architectural_design``: Software architecture documentation
- ``safety_analysis``: Detailed safety analysis (FMEA, FTA)
- ``dependability_analysis``: Comprehensive safety analysis results

**Structural Rules:**

- ``unit``: Smallest testable software element (design + implementation + tests)
- ``component``: Collection of units providing specific functionality
- ``dependable_element``: Complete Safety Element out of Context (SEooC) with full documentation

All rules support cross-module dependencies for automatic sphinx-needs integration and HTML merging.


sphinx_module
-------------

Builds Sphinx-based HTML documentation from RST source files with support for dependencies and cross-referencing.

.. code-block:: python

sphinx_module(
name = "my_docs",
srcs = glob(["docs/**/*.rst"]),
index = "docs/index.rst",
deps = ["@external_module//:docs"],
)

**Key Parameters:**

- ``srcs``: RST/MD source files
- ``index``: Main index.rst file
- ``deps``: Other sphinx_module or dependable_element targets for cross-referencing
- ``sphinx``: Sphinx build binary (default: ``//bazel/rules/rules_score:score_build``)

**Output:** ``<name>/html/`` with merged dependency documentation


Artifact Rules
--------------

Artifact rules define S-CORE process work products. All provide ``SphinxSourcesInfo`` for documentation generation.

**feature_requirements**

.. code-block:: python

feature_requirements(
name = "features",
srcs = ["docs/features.rst"],
)

**component_requirements**

.. code-block:: python

component_requirements(
name = "requirements",
srcs = ["docs/requirements.rst"],
feature_requirement = [":features"],
)

**assumptions_of_use**

.. code-block:: python

assumptions_of_use(
name = "aous",
srcs = ["docs/assumptions.rst"],
)

**architectural_design**

.. code-block:: python

architectural_design(
name = "architecture",
static = ["docs/static_arch.rst"],
dynamic = ["docs/dynamic_arch.rst"],
)

**safety_analysis**

.. code-block:: python

safety_analysis(
name = "safety",
controlmeasures = ["docs/controls.rst"],
failuremodes = ["docs/failures.rst"],
fta = ["docs/fta.rst"],
arch_design = ":architecture",
)

**dependability_analysis**

.. code-block:: python

dependability_analysis(
name = "analysis",
arch_design = ":architecture",
dfa = ["docs/dfa.rst"],
safety_analysis = [":safety"],
)


Structural Rules
----------------

**unit**

Define the smallest testable software element.

.. code-block:: python

unit(
name = "my_unit",
unit_design = [":architecture"],
implementation = ["//src:lib"],
tests = ["//tests:unit_test"],
)

**component**

Define a collection of units.

.. code-block:: python

component(
name = "my_component",
component_requirements = [":requirements"],
units = [":my_unit"],
implementation = ["//src:binary"],
tests = ["//tests:integration_test"],
)

**dependable_element**

Define a complete SEooC with automatic documentation generation.

.. code-block:: python

dependable_element(
name = "my_seooc",
description = "My safety-critical component",
assumptions_of_use = [":aous"],
requirements = [":requirements"],
architectural_design = [":architecture"],
dependability_analysis = [":analysis"],
components = [":my_component"],
tests = ["//tests:system_test"],
deps = ["@platform//:platform_module"],
)

**Generated Targets:**

- ``<name>``: Sphinx module with HTML documentation
- ``<name>_needs``: Sphinx-needs JSON for cross-referencing
- ``<name>_index``: Generated index.rst with artifact structure


Dependency Management
---------------------

Use ``deps`` for cross-module references. HTML is automatically merged:

.. code-block:: text

<name>/html/
├── index.html # Main documentation
├── _static/
├── dependency1/ # Merged dependency
└── dependency2/


Complete Example
----------------

.. code-block:: python

load("//bazel/rules/rules_score:rules_score.bzl",
"architectural_design", "assumptions_of_use",
"component", "component_requirements",
"dependability_analysis", "dependable_element",
"feature_requirements", "safety_analysis", "unit")

# Artifacts
feature_requirements(name = "features", srcs = ["docs/features.rst"])
component_requirements(name = "reqs", srcs = ["docs/reqs.rst"],
feature_requirement = [":features"])
assumptions_of_use(name = "aous", srcs = ["docs/aous.rst"])
architectural_design(name = "arch", static = ["docs/arch.rst"],
dynamic = ["docs/dynamic.rst"])
safety_analysis(name = "safety", arch_design = ":arch")
dependability_analysis(name = "analysis", arch_design = ":arch",
dfa = ["docs/dfa.rst"],
safety_analysis = [":safety"])

# Implementation
cc_library(name = "kvs_lib", srcs = ["kvs.cpp"], hdrs = ["kvs.h"])
cc_test(name = "kvs_test", srcs = ["kvs_test.cpp"], deps = [":kvs_lib"])

# Structure
unit(name = "kvs_unit", unit_design = [":arch"],
implementation = [":kvs_lib"], tests = [":kvs_test"])
component(name = "kvs_component", requirements = [":reqs"],
units = [":kvs_unit"], implementation = [":kvs_lib"], tests = [])

# SEooC
dependable_element(
name = "persistency_kvs",
description = "Key-Value Store for persistent data storage",
assumptions_of_use = [":aous"],
requirements = [":reqs"],
architectural_design = [":arch"],
dependability_analysis = [":analysis"],
components = [":kvs_component"],
tests = [],
deps = ["@score_process//:score_process_module"],
)

Build:

.. code-block:: bash

bazel build //:persistency_kvs
# Output: bazel-bin/persistency_kvs/html/

Reference Implementation
------------------------

See complete examples in the test BUILD file:

.. literalinclude:: ../test/BUILD
:language: python
:caption: test/BUILD
Empty file.
Loading