Skip to content

Commit 0a1baf6

Browse files
SebSparrowHawkcastler
authored andcommitted
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 79f904e commit 0a1baf6

5 files changed

Lines changed: 167 additions & 114 deletions

File tree

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

0 commit comments

Comments
 (0)