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
1 change: 1 addition & 0 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ copyright_checker(
"starpls",
"tools",
"plantuml",
"lobster_bazel",

# Add other directories/files you want to check
],
Expand Down
9 changes: 9 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,15 @@ pip.parse(
)
use_repo(pip, "pip_tooling")

pip.parse(
envsubst = ["PIP_INDEX_URL"],
extra_pip_args = ["--index-url=${PIP_INDEX_URL:-https://pypi.org/simple/}"],
hub_name = "pip_lobster_bazel",
python_version = PYTHON_VERSION,
requirements_lock = "//lobster_bazel:requirements.txt",
)
use_repo(pip, "pip_lobster_bazel")

###############################################################################
# Multitool Hub (for ruff, pyright, actionlint, etc.)
###############################################################################
Expand Down
32 changes: 32 additions & 0 deletions lobster_bazel/BUILD
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
# *******************************************************************************
load("@rules_python//python:defs.bzl", "py_binary", "py_library")

py_binary(
name = "lobster-bazel",
srcs = [
"parse_source_files.py",
],
main = "parse_source_files.py",
visibility = [
"//visibility:public",
],
deps = [
"@pip_lobster_bazel//bmw_lobster",
],
)

exports_files([
"requirements.in",
"requirements.txt",
])
131 changes: 131 additions & 0 deletions lobster_bazel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Tracing to Source Files (Bazel / Source Code Linker)

## Overview

`lobster-bazel` scans source files for inline tracing tags and produces a
`.lobster` file in the `lobster-imp-trace` format. It is designed for use in
Bazel-based projects where the build system can provide lists of source files to
scan, but the tool itself is not Bazel-specific and can be used with any build
system that can produce file-list inputs.

Supported file types (automatically detected by extension):

| Extension | Language | Comment sign |
|----------------------|-----------|--------------|
| `.c`, `.cc`, `.cpp`, `.cxx`, `.h`, `.hh`, `.hpp`, `.hxx` | C/C++ | `//` |
| `.rs` | Rust | `//` |
| `.py` | Python | `#` |
| `.bzl` | Starlark | `#` |
| `.trlc`, `.rsl` | TRLC | `#` |

Files with unsupported extensions are silently skipped; the run continues and
reports the number of items extracted from the remaining files.

## Adding tracing tags to source files

Add a single-line comment **at the start of the line** with the tracing tag
attribute and the requirement ID:

```python
# Python example
def process():
# req-traceability: COMP_REQ_001
pass
```

```cpp
// C++ example
void process() {
// req-traceability: COMP_REQ_001
}
```

```rust
// Rust example
fn process() {
// req-traceability: COMP_REQ_001
}
```

> **Note:** The tag pattern must appear at the start of the (stripped) line.
> Inline comments at the end of a code statement are intentionally **not**
> matched to avoid false positives.

The tag attribute (e.g. `req-traceability`) is configurable via `--tag`.
The default tag used by the `lobster_linker` Bazel rule is `lobster-trace`.

## Creating lobster files

The tool reads **file-list files** as positional arguments. Each file-list file
contains one source file path per line. This design integrates naturally with
Bazel's `$(locations ...)` expansion or any tool that can dump a list of files.

```sh
$ lobster-bazel --output impl.lobster \
--tag req-traceability \
source_files.txt
```

Where `source_files.txt` contains:

```
src/module_a.py
src/module_b.rs
include/module_c.hpp
```

Multiple file-list files and multiple `--tag` values are supported:

```sh
$ lobster-bazel --output impl.lobster \
--tag req-traceability \
--tag req-Id \
sources_a.txt sources_b.txt
```

An optional `--namespace` argument controls the namespace prefix for the
generated tags (default: `source`):

```sh
$ lobster-bazel --output impl.lobster \
--tag req-traceability \
--namespace impl \
source_files.txt
```

### Error behaviour

- **Unsupported file extension**: the file is skipped with a warning; the run
continues.
- **Unreadable or missing source file**: an error is logged and the file is
skipped; the run continues and exits with code 0.
- **Unreadable file-list file**: a fatal error is logged and the tool exits
with code 1.

## Bazel integration

When using Bazel, use the `lobster_linker` rule from `lobster.bzl`:

```starlark
load("@lobster//:lobster.bzl", "lobster_linker", "lobster_test")

lobster_linker(
name = "impl_trace",
srcs = [
"//src:my_library",
"//src:my_binary",
],
tracing_tags = ["req-traceability"],
)
```

The `lobster_linker` rule automatically collects all source files from the
listed targets and passes them to `lobster-bazel`. The output is exposed as a
`LobsterProvider` so it can be consumed by `lobster_test`.

The `subrule_lobster_linker` subrule is also exported for composing the linker
into other custom Bazel rules:

```starlark
load("@lobster//:lobster.bzl", "subrule_lobster_linker")
```
19 changes: 19 additions & 0 deletions lobster_bazel/lobster_bazel.bzl
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
# *******************************************************************************
load("//lobster_bazel/private:lobster_linker.bzl", _lobster_linker = "lobster_linker", _subrule_lobster_linker = "subrule_lobster_linker")

# Re-export LobsterProvider so it can be loaded from this file
def lobster_linker(**kwargs):
_lobster_linker(**kwargs)

subrule_lobster_linker = _subrule_lobster_linker
Loading
Loading