Skip to content

Commit aa61bde

Browse files
redsun82Copilot
andcommitted
Just: size batches for the argument a command hands on, not the line it is on
A single argument is capped far below the whole command line, at 128KB against 2MB on Linux, and a command that passes its arguments on through a shell arrives as one of them. Sizing batches by the line alone let a large enough tree build one argument over that cap, which fails as an `execv` error from whatever did the handing on, naming neither this file nor the files it was given. Also says how an exclusion is matched, as it is against the path the walk built rather than the one on the command line, and the natural way to name a directory only matches when the walk starts above it. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent b7d9351 commit aa61bde

2 files changed

Lines changed: 13 additions & 3 deletions

File tree

‎misc/just/format.just‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ _bazel_formatter := "bazel run --noshow_progress --ui_event_filters=,+error,+fai
2525
#
2626
# Both lists are comma-separated, so a root defining its own `_root_format` can name
2727
# several patterns in one variable. It has no need to repeat the ones here: the files
28-
# they cover belong to this repository, which formats them itself.
28+
# they cover belong to this repository, which formats them itself. Exclusions match the
29+
# path as walked rather than as spelled on the command line, so one naming a directory
30+
# has to cover both the path it is reached by and the path it is walked from.
2931
#
3032
# As with the QL formatter, buildifier only names what it rewrote if it also accounts for
3133
# every file it did not, so that accounting is dropped. It counts the warnings it could

‎misc/just/run_on_files.py‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,31 @@ def batch_limit():
2626
along with some slack. This is worth doing rather than assuming the tightest of the
2727
two: `ARG_MAX` is 2MB on Linux, which turns the couple of thousand QL files of a
2828
language into a single invocation rather than several.
29+
30+
A single argument is capped far lower than the whole line, at 128KB on Linux, and a
31+
command that hands its arguments on through a shell arrives as one of them. Batches
32+
are kept below that too, as the resulting failure is reported by whatever did the
33+
handing on rather than by anything naming this file.
2934
"""
3035
if sys.platform == "win32":
3136
return 30000
37+
single_argument = 100000
3238
try:
3339
arg_max = os.sysconf("SC_ARG_MAX")
3440
except (ValueError, OSError):
3541
return 30000
3642
environment = sum(len(name) + len(value) + 2 for name, value in os.environ.items())
37-
return max(4096, arg_max - environment - 4096)
43+
return max(4096, min(arg_max - environment - 4096, single_argument))
3844

3945

4046
def files_under(paths, patterns, excludes=(), absolute=False, within=None):
4147
"""Collect the files matching one of the patterns at or below each path.
4248
4349
Patterns are matched against the file name, as bazel files are identified by name
4450
rather than by extension. Exclusions are matched against the whole path instead,
45-
which is how a directory of generated files is left alone.
51+
which is how a directory of generated files is left alone. That path is the one the
52+
walk built, so an exclusion has to allow for how the paths it is given are spelled:
53+
`*/<directory>/*` does not match what is walked from `<directory>` itself.
4654
4755
A `within` directory bounds the result to the files below it, for a command that
4856
answers for one project and may be handed a path reaching outside it.

0 commit comments

Comments
 (0)