@@ -113,6 +113,18 @@ def _score_html_impl(ctx):
113113 Phase 2: Generate HTML with external needs and merge all dependency HTML
114114 """
115115
116+ run_args = [] # Copy of the args to forward along to debug runner
117+ args = ctx .actions .args () # Args passed to the action
118+
119+ # Expand location references in extra_opts and collect as sphinx arguments.
120+ # targets must include all labels referenced via $(location ...) / $(execpaths ...).
121+ extra_opts_targets = ctx .attr .srcs + ctx .attr .docs_library_deps
122+ 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 )
127+
116128 # Collect all transitive dependencies with deduplication
117129 modules = []
118130 sphinx_toolchain = ctx .toolchains ["//bazel/rules/rules_score:toolchain_type" ].sphinxinfo
@@ -138,18 +150,6 @@ def _score_html_impl(ctx):
138150 content = json .encode_indent (needs_external_needs , indent = " " ),
139151 )
140152
141- # Read template and substitute PROJECT_NAME
142- config_file = ctx .actions .declare_file (ctx .label .name + "/conf.py" )
143- template = sphinx_toolchain .conf_template .files .to_list ()[0 ]
144-
145- ctx .actions .expand_template (
146- template = template ,
147- output = config_file ,
148- substitutions = {
149- "{PROJECT_NAME}" : ctx .label .name .replace ("_" , " " ).title (),
150- },
151- )
152-
153153 source_prefix = ctx .label .name
154154 sphinx_source_files = []
155155
@@ -182,13 +182,6 @@ def _score_html_impl(ctx):
182182 new_path = entry .prefix + original .short_path .removeprefix (entry .strip_prefix )
183183 _relocate (original , new_path )
184184
185- needs_external_needs_json = ctx .actions .declare_file (ctx .label .name + "/needs_external_needs.json" )
186-
187- ctx .actions .write (
188- output = needs_external_needs_json ,
189- content = json .encode_indent (needs_external_needs , indent = " " ),
190- )
191-
192185 config_file = _create_config_py (ctx )
193186
194187 # Sphinx only accepts a single directory to read its doc sources from.
@@ -219,7 +212,7 @@ def _score_html_impl(ctx):
219212 ctx .actions .run (
220213 inputs = html_inputs ,
221214 outputs = [sphinx_html_output ],
222- arguments = html_args ,
215+ arguments = html_args + [ args ] ,
223216 progress_message = "Building HTML: %s" % ctx .label .name ,
224217 executable = sphinx_toolchain .sphinx .files_to_run .executable ,
225218 tools = [
@@ -287,6 +280,10 @@ _score_html = rule(
287280 allow_files = True ,
288281 doc = "Submodule symbols.needs targets for this module." ,
289282 ),
283+ 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." ,
286+ ),
290287 ),
291288 toolchains = ["//bazel/rules/rules_score:toolchain_type" ],
292289)
@@ -303,6 +300,7 @@ def sphinx_module(
303300 docs_library_deps = [],
304301 sphinx = Label ("//bazel/rules/rules_score:score_build" ),
305302 strip_prefix = "" ,
303+ extra_opts = [],
306304 testonly = False ,
307305 visibility = ["//visibility:public" ]):
308306 """Build a Sphinx module with transitive HTML dependencies.
@@ -323,6 +321,9 @@ def sphinx_module(
323321 source files. e.g., given `//sphinxdocs/docs:foo.md`, stripping `docs/` makes
324322 Sphinx see `foo.md` in its generated source directory. If not
325323 specified, then {any}`native.package_name` is used.
324+ extra_opts: {type}`list[str]` Additional options to pass onto Sphinx building.
325+ On each provided option, a location expansion is performed.
326+ See {any}`ctx.expand_location`.
326327 visibility: Bazel visibility
327328 """
328329 _score_needs (
@@ -341,6 +342,7 @@ def sphinx_module(
341342 deps = deps ,
342343 docs_library_deps = docs_library_deps ,
343344 needs = [d + "_needs" for d in deps ],
345+ extra_opts = extra_opts ,
344346 testonly = testonly ,
345347 visibility = visibility ,
346348 )
0 commit comments