Skip to content

Commit 0aa2243

Browse files
authored
Merge branch 'main' into public-module
2 parents 769c6de + d98547e commit 0aa2243

File tree

7 files changed

+306
-16
lines changed

7 files changed

+306
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ END_UNRELEASED_TEMPLATE
7272
* (py_wheel) py_wheel always creates zip64-capable wheel zips
7373
* (providers) (experimental) {obj}`PyInfo.venv_symlinks` replaces
7474
`PyInfo.site_packages_symlinks`
75-
(gazelle) Export `parser.Module` as a public struct.
75+
* (gazelle) Export `parser.Module` as a public struct.
76+
* (deps) Updating setuptools to patch CVE-2025-47273.
7677

7778
{#v0-0-0-fixed}
7879
### Fixed

python/private/pypi/deps.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ _RULE_DEPS = [
7676
),
7777
(
7878
"pypi__setuptools",
79-
"https://files.pythonhosted.org/packages/de/88/70c5767a0e43eb4451c2200f07d042a4bcd7639276003a9c54a68cfcc1f8/setuptools-70.0.0-py3-none-any.whl",
80-
"54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4",
79+
"https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl",
80+
"c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561",
8181
),
8282
(
8383
"pypi__tomli",

sphinxdocs/docs/index.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,29 @@ documentation. It comes with:
1111
While it is primarily oriented towards docgen for Starlark code, the core of it
1212
is agnostic as to what is being documented.
1313

14+
### Optimization
15+
16+
Normally, Sphinx keeps various cache files to improve incremental building.
17+
Unfortunately, programs performing their own caching don't interact well
18+
with Bazel's model of precisely declaring and strictly enforcing what are
19+
inputs, what are outputs, and what files are available when running a program.
20+
The net effect is programs don't have a prior invocation's cache files
21+
available.
22+
23+
There are two mechanisms available to make some cache available to Sphinx under
24+
Bazel:
25+
26+
* Disable sandboxing, which allows some files from prior invocations to be
27+
visible to subsequent invocations. This can be done multiple ways:
28+
* Set `tags = ["no-sandbox"]` on the `sphinx_docs` target
29+
* `--modify_execution_info=SphinxBuildDocs=+no-sandbox` (Bazel flag)
30+
* `--strategy=SphinxBuildDocs=local` (Bazel flag)
31+
* Use persistent workers (enabled by default) by setting
32+
`allow_persistent_workers=True` on the `sphinx_docs` target. Note that other
33+
Bazel flags can disable using workers even if an action supports it. Setting
34+
`--strategy=SphinxBuildDocs=dynamic,worker,local,sandbox` should tell Bazel
35+
to use workers if possible, otherwise fallback to non-worker invocations.
36+
1437

1538
```{toctree}
1639
:hidden:

sphinxdocs/private/sphinx.bzl

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ def sphinx_docs(
103103
strip_prefix = "",
104104
extra_opts = [],
105105
tools = [],
106+
allow_persistent_workers = True,
106107
**kwargs):
107108
"""Generate docs using Sphinx.
108109
@@ -142,6 +143,9 @@ def sphinx_docs(
142143
tools: {type}`list[label]` Additional tools that are used by Sphinx and its plugins.
143144
This just makes the tools available during Sphinx execution. To locate
144145
them, use {obj}`extra_opts` and `$(location)`.
146+
allow_persistent_workers: {type}`bool` (experimental) If true, allow
147+
using persistent workers for running Sphinx, if Bazel decides to do so.
148+
This can improve incremental building of docs.
145149
**kwargs: {type}`dict` Common attributes to pass onto rules.
146150
"""
147151
add_tag(kwargs, "@rules_python//sphinxdocs:sphinx_docs")
@@ -165,6 +169,7 @@ def sphinx_docs(
165169
source_tree = internal_name + "/_sources",
166170
extra_opts = extra_opts,
167171
tools = tools,
172+
allow_persistent_workers = allow_persistent_workers,
168173
**kwargs
169174
)
170175

@@ -209,6 +214,7 @@ def _sphinx_docs_impl(ctx):
209214
source_path = source_dir_path,
210215
output_prefix = paths.join(ctx.label.name, "_build"),
211216
inputs = inputs,
217+
allow_persistent_workers = ctx.attr.allow_persistent_workers,
212218
)
213219
outputs[format] = output_dir
214220
per_format_args[format] = args_env
@@ -229,6 +235,10 @@ def _sphinx_docs_impl(ctx):
229235
_sphinx_docs = rule(
230236
implementation = _sphinx_docs_impl,
231237
attrs = {
238+
"allow_persistent_workers": attr.bool(
239+
doc = "(experimental) Whether to invoke Sphinx as a persistent worker.",
240+
default = False,
241+
),
232242
"extra_opts": attr.string_list(
233243
doc = "Additional options to pass onto Sphinx. These are added after " +
234244
"other options, but before the source/output args.",
@@ -254,28 +264,45 @@ _sphinx_docs = rule(
254264
},
255265
)
256266

257-
def _run_sphinx(ctx, format, source_path, inputs, output_prefix):
267+
def _run_sphinx(ctx, format, source_path, inputs, output_prefix, allow_persistent_workers):
258268
output_dir = ctx.actions.declare_directory(paths.join(output_prefix, format))
259269

260270
run_args = [] # Copy of the args to forward along to debug runner
261271
args = ctx.actions.args() # Args passed to the action
262272

273+
# An args file is required for persistent workers, but we don't know if
274+
# the action will use worker mode or not (settings we can't see may
275+
# force non-worker mode). For consistency, always use a params file.
276+
args.use_param_file("@%s", use_always = True)
277+
args.set_param_file_format("multiline")
278+
279+
# NOTE: sphinx_build.py relies on the first two args being the srcdir and
280+
# outputdir, in that order.
281+
args.add(source_path)
282+
args.add(output_dir.path)
283+
263284
args.add("--show-traceback") # Full tracebacks on error
264285
run_args.append("--show-traceback")
265-
args.add("--builder", format)
266-
run_args.extend(("--builder", format))
286+
args.add(format, format = "--builder=%s")
287+
run_args.append("--builder={}".format(format))
267288

268289
if ctx.attr._quiet_flag[BuildSettingInfo].value:
269290
# Not added to run_args because run_args is for debugging
270291
args.add("--quiet") # Suppress stdout informational text
271292

272293
# Build in parallel, if possible
273294
# Don't add to run_args: parallel building breaks interactive debugging
274-
args.add("--jobs", "auto")
275-
args.add("--fresh-env") # Don't try to use cache files. Bazel can't make use of them.
276-
run_args.append("--fresh-env")
277-
args.add("--write-all") # Write all files; don't try to detect "changed" files
278-
run_args.append("--write-all")
295+
args.add("--jobs=auto")
296+
297+
# Put the doctree dir outside of the output directory.
298+
# This allows it to be reused between invocations when possible; Bazel
299+
# clears the output directory every action invocation.
300+
# * For workers, they can fully re-use it.
301+
# * For non-workers, it can be reused when sandboxing is disabled via
302+
# the `no-sandbox` tag or execution requirement.
303+
#
304+
# We also use a non-dot prefixed name so it shows up more visibly.
305+
args.add(paths.join(output_dir.path + "_doctrees"), format = "--doctree-dir=%s")
279306

280307
for opt in ctx.attr.extra_opts:
281308
expanded = ctx.expand_location(opt)
@@ -287,9 +314,6 @@ def _run_sphinx(ctx, format, source_path, inputs, output_prefix):
287314
for define in extra_defines:
288315
run_args.extend(("--define", define))
289316

290-
args.add(source_path)
291-
args.add(output_dir.path)
292-
293317
env = dict([
294318
v.split("=", 1)
295319
for v in ctx.attr._extra_env_flag[_FlagInfo].value
@@ -299,6 +323,14 @@ def _run_sphinx(ctx, format, source_path, inputs, output_prefix):
299323
for tool in ctx.attr.tools:
300324
tools.append(tool[DefaultInfo].files_to_run)
301325

326+
# NOTE: Command line flags or RBE capabilities may override the execution
327+
# requirements and disable workers. Thus, we can't assume that these
328+
# exec requirements will actually be respected.
329+
execution_requirements = {}
330+
if allow_persistent_workers:
331+
execution_requirements["supports-workers"] = "1"
332+
execution_requirements["requires-worker-protocol"] = "json"
333+
302334
ctx.actions.run(
303335
executable = ctx.executable.sphinx,
304336
arguments = [args],
@@ -308,6 +340,7 @@ def _run_sphinx(ctx, format, source_path, inputs, output_prefix):
308340
mnemonic = "SphinxBuildDocs",
309341
progress_message = "Sphinx building {} for %{{label}}".format(format),
310342
env = env,
343+
execution_requirements = execution_requirements,
311344
)
312345
return output_dir, struct(args = run_args, env = env)
313346

0 commit comments

Comments
 (0)