Skip to content

Commit bf9b8f6

Browse files
Switch to bazel rule to filter extra opt parameters
Also remove some debug log messages and replace usage of static string by switching to bazel variable equivalent.
1 parent 4fc8519 commit bf9b8f6

5 files changed

Lines changed: 168 additions & 135 deletions

File tree

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
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+
"""Rule for resolving filtered execpaths at analysis time.
14+
This replaces the old string-encoding approach where filter_execpath() was a
15+
macro-time helper that encoded parameters into a delimited string for later
16+
processing inside the sphinx_module rule implementation.
17+
Now, filter_execpath is a proper Bazel rule that resolves the path at analysis
18+
time and provides the result via FilteredExecpathInfo.
19+
"""
20+
load("//bazel/rules/rules_score:providers.bzl", "FilteredExecpathInfo")
21+
def _filter_execpath_impl(ctx):
22+
"""Implementation of the filter_execpath rule.
23+
Iterates over the output files of the target, finds the one matching
24+
filter_pattern, and computes the resolved path suffix after /bin/.
25+
"""
26+
target = ctx.attr.target
27+
filter_pattern = ctx.attr.filter_pattern
28+
flag = ctx.attr.flag
29+
# Get all output files from the target
30+
files = target[DefaultInfo].files.to_list()
31+
# Filter for the path matching the filter pattern
32+
matched_file = None
33+
for f in files:
34+
if filter_pattern in f.path:
35+
matched_file = f
36+
break
37+
if not matched_file:
38+
all_paths = [f.path for f in files]
39+
fail("filter_execpath: no path matching '{}' found in outputs of {}. Available paths: {}".format(
40+
filter_pattern,
41+
target.label,
42+
", ".join(all_paths),
43+
))
44+
# Strip the Bazel bin directory prefix from the matched path to get the path
45+
# relative to the output base. Since _relocate() in sphinx_module symlinks
46+
# source files under <source_prefix>/<original_path>, the relocated file lives
47+
# at <source_dir>/<suffix_part> where source_dir is the Sphinx source directory.
48+
# Breathe resolves breathe_projects paths relative to source_dir (app.srcdir),
49+
# so we must return just the suffix_part.
50+
matched_path = matched_file.path
51+
bin_dir_prefix = ctx.bin_dir.path + "/"
52+
if matched_path.startswith(bin_dir_prefix):
53+
suffix_part = matched_path[len(bin_dir_prefix):]
54+
else:
55+
suffix_part = matched_path
56+
resolved_arg = flag + "=" + suffix_part
57+
return [
58+
DefaultInfo(files = depset([matched_file])),
59+
FilteredExecpathInfo(
60+
flag = flag,
61+
resolved_path = suffix_part,
62+
arg = resolved_arg,
63+
matched_file = matched_file,
64+
),
65+
]
66+
_filter_execpath_rule = rule(
67+
implementation = _filter_execpath_impl,
68+
attrs = {
69+
"flag": attr.string(
70+
mandatory = True,
71+
doc = "The Sphinx -D flag prefix (e.g. '-Dbreathe_projects.com').",
72+
),
73+
"target": attr.label(
74+
mandatory = True,
75+
allow_files = True,
76+
doc = "The Bazel target whose output files to search.",
77+
),
78+
"filter_pattern": attr.string(
79+
mandatory = True,
80+
doc = "Substring to match when filtering the target's output file paths (e.g. 'doxygen_build/xml').",
81+
),
82+
},
83+
doc = """Resolve and filter an execpath from a target's outputs at analysis time.
84+
This rule finds the output file from `target` whose path contains
85+
`filter_pattern`, strips the Bazel bin directory prefix, and provides
86+
the result as a FilteredExecpathInfo for consumption by sphinx_module.
87+
Example usage in BUILD:
88+
load("@score_tooling//bazel/rules/rules_score:rules_score.bzl", "filter_execpath", "sphinx_module")
89+
filter_execpath(
90+
name = "breathe_doxygen_xml",
91+
flag = "-Dbreathe_projects.doxygen_build",
92+
target = "//docs/sphinx:doxygen_xml",
93+
filter_pattern = "doxygen_build/xml",
94+
)
95+
sphinx_module(
96+
name = "sphinx_doc",
97+
extra_opts_targets = [":breathe_doxygen_xml"],
98+
extra_opts = ["-Dbreathe_default_project=doxygen_build"],
99+
...
100+
)
101+
""",
102+
)
103+
def filter_execpath(name, flag, target, filter_pattern, **kwargs):
104+
"""Resolve and filter an execpath from a target's outputs at analysis time.
105+
This is a macro wrapper around the _filter_execpath_rule.
106+
Args:
107+
name: Name for this target.
108+
flag: The Sphinx -D flag prefix (e.g. "-Dbreathe_projects.doxygen_build").
109+
target: The Bazel label whose output files to search.
110+
filter_pattern: Substring to match when filtering the target's output file paths.
111+
**kwargs: Additional keyword arguments passed to the underlying rule (e.g. visibility).
112+
"""
113+
_filter_execpath_rule(
114+
name = name,
115+
flag = flag,
116+
target = target,
117+
filter_pattern = filter_pattern,
118+
**kwargs
119+
)

0 commit comments

Comments
 (0)