Skip to content

Commit e1514af

Browse files
committed
lobster_bazel: bazel plugin for lobster
1 parent 82ee68d commit e1514af

23 files changed

Lines changed: 1636 additions & 2 deletions

BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ copyright_checker(
2929
"starpls",
3030
"tools",
3131
"plantuml",
32+
"lobster_bazel",
3233

3334
# Add other directories/files you want to check
3435
],

MODULE.bazel

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ module(
2121
# Core Dependencies
2222
###############################################################################
2323
bazel_dep(name = "rules_cc", version = "0.2.14")
24-
bazel_dep(name = "rules_python", version = "1.4.1")
24+
bazel_dep(name = "rules_python", version = "1.8.3")
2525
bazel_dep(name = "aspect_rules_py", version = "1.4.0")
2626
bazel_dep(name = "platforms", version = "1.0.0")
2727
bazel_dep(name = "aspect_rules_lint", version = "1.5.3")
@@ -30,9 +30,10 @@ bazel_dep(name = "rules_java", version = "8.15.1")
3030
bazel_dep(name = "rules_rust", version = "0.61.0")
3131
bazel_dep(name = "rules_multitool", version = "1.9.0")
3232
bazel_dep(name = "score_rust_policies", version = "0.0.2")
33-
bazel_dep(name = "bazel_skylib", version = "1.7.1")
33+
bazel_dep(name = "bazel_skylib", version = "1.8.2")
3434
bazel_dep(name = "buildifier_prebuilt", version = "8.2.0.2")
3535
bazel_dep(name = "flatbuffers", version = "25.9.23")
36+
bazel_dep(name = "rules_go", version = "0.60.0")
3637

3738
###############################################################################
3839
# CC Toolchain
@@ -151,6 +152,15 @@ pip.parse(
151152
)
152153
use_repo(pip, "pip_tooling")
153154

155+
pip.parse(
156+
envsubst = ["PIP_INDEX_URL"],
157+
extra_pip_args = ["--index-url=${PIP_INDEX_URL:-https://pypi.org/simple/}"],
158+
hub_name = "pip_lobster_bazel",
159+
python_version = PYTHON_VERSION,
160+
requirements_lock = "//lobster_bazel:requirements.txt",
161+
)
162+
use_repo(pip, "pip_lobster_bazel")
163+
154164
###############################################################################
155165
# Multitool Hub (for ruff, pyright, actionlint, etc.)
156166
###############################################################################

lobster_bazel/BUILD

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
#
4+
# See the NOTICE file(s) distributed with this work for additional
5+
# information regarding copyright ownership.
6+
#
7+
# This program and the accompanying materials are made available under the
8+
# terms of the Apache License Version 2.0 which is available at
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# SPDX-License-Identifier: Apache-2.0
12+
# *******************************************************************************
13+
load("@rules_python//python:defs.bzl", "py_binary", "py_library")
14+
15+
py_binary(
16+
name = "lobster-bazel",
17+
srcs = [
18+
"parse_source_files.py",
19+
],
20+
main = "parse_source_files.py",
21+
visibility = [
22+
"//visibility:public",
23+
],
24+
deps = [
25+
"@pip_lobster_bazel//bmw_lobster",
26+
],
27+
)
28+
29+
exports_files([
30+
"requirements.in",
31+
"requirements.txt",
32+
])

lobster_bazel/README.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Tracing to Source Files (Bazel / Source Code Linker)
2+
3+
## Overview
4+
5+
`lobster-bazel` scans source files for inline tracing tags and produces a
6+
`.lobster` file in the `lobster-imp-trace` format. It is designed for use in
7+
Bazel-based projects where the build system can provide lists of source files to
8+
scan, but the tool itself is not Bazel-specific and can be used with any build
9+
system that can produce file-list inputs.
10+
11+
Supported file types (automatically detected by extension):
12+
13+
| Extension | Language | Comment sign |
14+
|----------------------|-----------|--------------|
15+
| `.c`, `.cc`, `.cpp`, `.cxx`, `.h`, `.hh`, `.hpp`, `.hxx` | C/C++ | `//` |
16+
| `.rs` | Rust | `//` |
17+
| `.py` | Python | `#` |
18+
| `.bzl` | Starlark | `#` |
19+
| `.trlc`, `.rsl` | TRLC | `#` |
20+
21+
Files with unsupported extensions are silently skipped; the run continues and
22+
reports the number of items extracted from the remaining files.
23+
24+
## Adding tracing tags to source files
25+
26+
Add a single-line comment **at the start of the line** with the tracing tag
27+
attribute and the requirement ID:
28+
29+
```python
30+
# Python example
31+
def process():
32+
# req-traceability: COMP_REQ_001
33+
pass
34+
```
35+
36+
```cpp
37+
// C++ example
38+
void process() {
39+
// req-traceability: COMP_REQ_001
40+
}
41+
```
42+
43+
```rust
44+
// Rust example
45+
fn process() {
46+
// req-traceability: COMP_REQ_001
47+
}
48+
```
49+
50+
> **Note:** The tag pattern must appear at the start of the (stripped) line.
51+
> Inline comments at the end of a code statement are intentionally **not**
52+
> matched to avoid false positives.
53+
54+
The tag attribute (e.g. `req-traceability`) is configurable via `--tag`.
55+
The default tag used by the `lobster_linker` Bazel rule is `lobster-trace`.
56+
57+
## Creating lobster files
58+
59+
The tool reads **file-list files** as positional arguments. Each file-list file
60+
contains one source file path per line. This design integrates naturally with
61+
Bazel's `$(locations ...)` expansion or any tool that can dump a list of files.
62+
63+
```sh
64+
$ lobster-bazel --output impl.lobster \
65+
--tag req-traceability \
66+
source_files.txt
67+
```
68+
69+
Where `source_files.txt` contains:
70+
71+
```
72+
src/module_a.py
73+
src/module_b.rs
74+
include/module_c.hpp
75+
```
76+
77+
Multiple file-list files and multiple `--tag` values are supported:
78+
79+
```sh
80+
$ lobster-bazel --output impl.lobster \
81+
--tag req-traceability \
82+
--tag req-Id \
83+
sources_a.txt sources_b.txt
84+
```
85+
86+
An optional `--namespace` argument controls the namespace prefix for the
87+
generated tags (default: `source`):
88+
89+
```sh
90+
$ lobster-bazel --output impl.lobster \
91+
--tag req-traceability \
92+
--namespace impl \
93+
source_files.txt
94+
```
95+
96+
### Error behaviour
97+
98+
- **Unsupported file extension**: the file is skipped with a warning; the run
99+
continues.
100+
- **Unreadable or missing source file**: an error is logged and the file is
101+
skipped; the run continues and exits with code 0.
102+
- **Unreadable file-list file**: a fatal error is logged and the tool exits
103+
with code 1.
104+
105+
## Bazel integration
106+
107+
When using Bazel, use the `lobster_linker` rule from `lobster.bzl`:
108+
109+
```starlark
110+
load("@lobster//:lobster.bzl", "lobster_linker", "lobster_test")
111+
112+
lobster_linker(
113+
name = "impl_trace",
114+
srcs = [
115+
"//src:my_library",
116+
"//src:my_binary",
117+
],
118+
tracing_tags = ["req-traceability"],
119+
)
120+
```
121+
122+
The `lobster_linker` rule automatically collects all source files from the
123+
listed targets and passes them to `lobster-bazel`. The output is exposed as a
124+
`LobsterProvider` so it can be consumed by `lobster_test`.
125+
126+
The `subrule_lobster_linker` subrule is also exported for composing the linker
127+
into other custom Bazel rules:
128+
129+
```starlark
130+
load("@lobster//:lobster.bzl", "subrule_lobster_linker")
131+
```

lobster_bazel/lobster_bazel.bzl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
#
4+
# See the NOTICE file(s) distributed with this work for additional
5+
# information regarding copyright ownership.
6+
#
7+
# This program and the accompanying materials are made available under the
8+
# terms of the Apache License Version 2.0 which is available at
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# SPDX-License-Identifier: Apache-2.0
12+
# *******************************************************************************
13+
load("//lobster_bazel/private:lobster_linker.bzl", _lobster_linker = "lobster_linker", _subrule_lobster_linker = "subrule_lobster_linker")
14+
15+
# Re-export LobsterProvider so it can be loaded from this file
16+
def lobster_linker(**kwargs):
17+
_lobster_linker(**kwargs)
18+
19+
subrule_lobster_linker = _subrule_lobster_linker

0 commit comments

Comments
 (0)