Skip to content

Commit 0d1461d

Browse files
Filter breathe xml input folder
... from existing folders of doxgen build target.
1 parent 2b9412f commit 0d1461d

4 files changed

Lines changed: 88 additions & 13 deletions

File tree

bazel/rules/rules_score/private/sphinx_module.bzl

Lines changed: 83 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,39 @@ load("@rules_python//sphinxdocs:sphinx_docs_library.bzl", "sphinx_docs_library")
1919
load("@rules_python//sphinxdocs/private:sphinx_docs_library_info.bzl", "SphinxDocsLibraryInfo")
2020
load("//bazel/rules/rules_score:providers.bzl", "SphinxModuleInfo", "SphinxNeedsInfo")
2121

22+
# Delimiter used to encode filter_execpath parameters into a single extra_opts string.
23+
_FILTER_EXECPATH_DELIM = "@@FILTER_EXECPATH@@"
24+
25+
def filter_execpath(flag, label, filter_pattern):
26+
"""Construct an extra_opts entry that filters execpaths and rewrites them with the relocated target prefix.
27+
28+
When used in extra_opts of sphinx_module, the rule implementation will:
29+
1. Expand $(execpaths <label>) to get all output paths
30+
2. Filter for the path containing <filter_pattern>
31+
3. Rewrite the path to include the target's relocated prefix
32+
(e.g. bazel-out/.../bin/<package>/<name>/<original_path>)
33+
34+
Example usage in BUILD:
35+
load("@score_tooling//bazel/rules/rules_score:rules_score.bzl", "filter_execpath", "sphinx_module")
36+
37+
sphinx_module(
38+
name = "sphinx_doc",
39+
extra_opts = [
40+
filter_execpath("-Dbreathe_projects.com", "//docs/sphinx:doxygen_xml", "doxygen_build/xml"),
41+
],
42+
...
43+
)
44+
45+
Args:
46+
flag: The Sphinx -D flag prefix (e.g. "-Dbreathe_projects.com")
47+
label: The Bazel label whose execpaths to expand (e.g. "//docs/sphinx:doxygen_xml")
48+
filter_pattern: Substring to match when filtering the execpaths (e.g. "doxygen_build/xml")
49+
50+
Returns:
51+
A specially formatted string that the sphinx_module rule will process.
52+
"""
53+
return _FILTER_EXECPATH_DELIM.join([flag, str(label), filter_pattern])
54+
2255
def _create_config_py(ctx):
2356
"""Get or generate the conf.py configuration file.
2457
@@ -119,11 +152,55 @@ def _score_html_impl(ctx):
119152
# Expand location references in extra_opts and collect as sphinx arguments.
120153
# targets must include all labels referenced via $(location ...) / $(execpaths ...).
121154
extra_opts_targets = ctx.attr.srcs + ctx.attr.docs_library_deps
155+
source_prefix = ctx.label.name
156+
122157
for opt in ctx.attr.extra_opts:
123-
expanded = ctx.expand_location(opt, targets = extra_opts_targets)
124-
print("???????? expanded opts location: ", expanded)
125-
args.add(expanded)
126-
run_args.append(expanded)
158+
if _FILTER_EXECPATH_DELIM in opt:
159+
# Process filter_execpath() encoded strings:
160+
# Format: flag@@FILTER_EXECPATH@@label@@FILTER_EXECPATH@@filter_pattern
161+
parts = opt.split(_FILTER_EXECPATH_DELIM)
162+
flag = parts[0]
163+
label_str = parts[1]
164+
filter_pattern = parts[2]
165+
166+
# Expand execpaths for the referenced label
167+
expanded = ctx.expand_location("$(execpaths " + label_str + ")", targets = extra_opts_targets)
168+
expanded_paths = expanded.split(" ")
169+
170+
# Filter for the path matching the filter pattern
171+
matched_path = None
172+
for p in expanded_paths:
173+
if filter_pattern in p:
174+
matched_path = p
175+
break
176+
177+
if not matched_path:
178+
fail("filter_execpath: no path matching '{}' found in execpaths of {}. Paths: {}".format(
179+
filter_pattern,
180+
label_str,
181+
expanded,
182+
))
183+
184+
# Extract the path suffix after "/bin/" — this is the original path relative
185+
# to the output base. Since _relocate() symlinks source files under
186+
# <source_prefix>/<original_path>, the relocated file lives at
187+
# <source_dir>/<suffix_part> where source_dir is the Sphinx source directory.
188+
# Breathe resolves breathe_projects paths relative to source_dir (app.srcdir),
189+
# so we must return just the suffix_part.
190+
bin_marker = "/bin/"
191+
bin_idx = matched_path.find(bin_marker)
192+
if bin_idx >= 0:
193+
suffix_part = matched_path[bin_idx + len(bin_marker):]
194+
else:
195+
suffix_part = matched_path
196+
197+
expanded_opt = flag + "=" + suffix_part
198+
else:
199+
# Standard extra_opts: expand locations and pass through
200+
expanded_opt = ctx.expand_location(opt, targets = extra_opts_targets)
201+
202+
args.add(expanded_opt)
203+
run_args.append(expanded_opt)
127204

128205
# Collect all transitive dependencies with deduplication
129206
modules = []
@@ -150,7 +227,6 @@ def _score_html_impl(ctx):
150227
content = json.encode_indent(needs_external_needs, indent = " "),
151228
)
152229

153-
source_prefix = ctx.label.name
154230
sphinx_source_files = []
155231

156232
# Materialize a file under the `_sources` dir
@@ -281,8 +357,8 @@ _score_html = rule(
281357
doc = "Submodule symbols.needs targets for this module.",
282358
),
283359
extra_opts = attr.string_list(
284-
doc = "Additional options to pass onto Sphinx. These are added after " +
285-
"other options, but before the source/output args.",
360+
doc = "Additional options to pass onto Sphinx. These are added after " +
361+
"other options, but before the source/output args.",
286362
),
287363
),
288364
toolchains = ["//bazel/rules/rules_score:toolchain_type"],

bazel/rules/rules_score/rules_score.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ load(
4848
)
4949
load(
5050
"//bazel/rules/rules_score/private:sphinx_module.bzl",
51+
_filter_execpath = "filter_execpath",
5152
_sphinx_module = "sphinx_module",
5253
)
5354
load(
@@ -65,6 +66,7 @@ component_requirements = _component_requirements
6566
dependability_analysis = _dependability_analysis
6667
feature_requirements = _feature_requirements
6768
fmea = _fmea
69+
filter_execpath = _filter_execpath
6870
sphinx_module = _sphinx_module
6971
unit = _unit
7072
unit_design = _unit_design

bazel/rules/rules_score/src/sphinx_html_merge.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,6 @@ def main():
178178
help="Dependency HTML directory in format NAME:PATH",
179179
)
180180

181-
parser.add_argument(
182-
"-Dbreathe_projects",
183-
help="Override Breathe projects mapping (e.g., -Dbreathe_projects='{\"com\": \"path/to/xml\"}')",
184-
)
185-
186181
args = parser.parse_args()
187182

188183
# Parse dependencies

bazel/rules/rules_score/src/sphinx_wrapper.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ def validate_arguments(args: argparse.Namespace) -> None:
110110
raise ValueError(f"Index file does not exist: {args.index_file}")
111111

112112

113-
def build_sphinx_arguments(args: argparse.Namespace, extra_args: List[str] = None) -> List[str]:
113+
def build_sphinx_arguments(
114+
args: argparse.Namespace, extra_args: List[str] = None
115+
) -> List[str]:
114116
"""
115117
Build the argument list for Sphinx.
116118

0 commit comments

Comments
 (0)