files: group by (directory, stem), not stem alone

group_files_by_stem mixed marauder/s3.bin and other/s3.bin into one
FileGroup because it ignored directory.  Unique (directory, stem) then
kept only one of them, so flasher search missed a firmware file.

run_command_streaming awaits the stdout reader instead of cancelling it
when the process exits, so the last lines are not lost on a fast CI run.
This commit is contained in:
Roland 2026-09-19 04:02:17 -06:00
parent 754cda2d49
commit e2c5c6e0b3
No known key found for this signature in database
GPG key ID: 1BA620CE6C9A4680
4 changed files with 21 additions and 12 deletions

View file

@ -299,7 +299,8 @@ async def run_command(cmd: tuple[str | pathlib.Path, ...], cwd: pathlib.Path | s
await proc.wait()
if reader_task:
reader_task.cancel()
# Drain remaining stdout. Cancelling here races the last lines on a fast process
# (CI often loses "line three" because wait() returns before the reader finishes).
try:
await reader_task
except (CancelledError, asyncio.CancelledError):

View file

@ -2382,23 +2382,24 @@ def chunks_by_stem(it: List[Union[pathlib.Path, str, int]], size: int) -> Genera
from wrolpi.files.lib import split_path_stem_and_suffix
it = sorted(it.copy())
index = size
last_stem = None
last_key = None
while it:
if index >= len(it):
# Ran out of items, yield what is left.
yield it
return
path = it[index]
path = pathlib.Path(path)
stem, _ = split_path_stem_and_suffix(path)
if last_stem and stem != last_stem:
# Found a break in the path names, yield and reset.
key = (str(path.parent), stem)
if last_key and key != last_key:
# Found a break in directory or stem, yield and reset.
chunk, it = it[:index], it[index:]
index = size
last_stem = None
last_key = None
yield chunk
continue
# Didn't find a name change, try again.
last_stem = stem
last_key = key
index += 1

View file

@ -1500,16 +1500,16 @@ def group_files_by_stem(files: List[pathlib.Path], pre_sorted: bool = False) ->
files = sorted(files) if not pre_sorted else files.copy()
file = files.pop(0)
group = [file, ]
prev_stem, _ = split_path_stem_and_suffix(file)
prev_dir, prev_stem = file.parent, split_path_stem_and_suffix(file)[0]
for file in files:
stem, suffix = split_path_stem_and_suffix(file)
if stem == prev_stem:
stem, _ = split_path_stem_and_suffix(file)
if stem == prev_stem and file.parent == prev_dir:
group.append(file)
continue
# Stem has changed, group is finished.
# Directory or stem changed, group is finished.
yield group
group = [file, ]
prev_stem = stem
prev_dir, prev_stem = file.parent, stem
yield group

View file

@ -930,6 +930,13 @@ def test_group_files_by_stem(make_files_structure, test_directory):
test_directory / 'foo.txt'],
]
make_files_structure(['dir_a/s3.bin', 'dir_b/s3.bin'])
same_stem = [test_directory / 'dir_a/s3.bin', test_directory / 'dir_b/s3.bin']
assert list(lib.group_files_by_stem(same_stem)) == [
[test_directory / 'dir_a/s3.bin'],
[test_directory / 'dir_b/s3.bin'],
]
def test_get_primary_file(test_directory, video_file, srt_file3, example_epub, example_mobi, example_pdf,
singlefile_contents_factory, make_files_structure):