diff --git a/.github/guid-index.json b/.github/guid-index.json index bf081cf5..ef0bda2d 100644 --- a/.github/guid-index.json +++ b/.github/guid-index.json @@ -3075,7 +3075,7 @@ "path": "scripts/assemble_todo.py", "guid": "af7ef324-6c69-411e-b1a9-98c9ba2b31e3", "title": "assemble todo", - "version": "1.1.0", + "version": "1.2.0", "header_path": "scripts/assemble_todo.py", "path_mismatch": false }, diff --git a/changelog.d/20260719-assembler-width-stable.md b/changelog.d/20260719-assembler-width-stable.md new file mode 100644 index 00000000..4180d9b6 --- /dev/null +++ b/changelog.d/20260719-assembler-width-stable.md @@ -0,0 +1,15 @@ +### Fixed + +#### `assemble_todo.py` is now formatted identically at any ruff line-length + +`ruff format` is not idempotent across line-lengths: a file formatted at 80 +columns gets its short lines rejoined at 88. The assembler is copied verbatim +into repos that have no `ruff.toml` of their own, where ruff falls back to its +88-column default — so `ruff format --check` failed there even though the file +was correctly formatted for this repo. + +Every multi-line construct now carries a magic trailing comma (which pins it +exploded at any width), and the two constructs that could not take one were +reshaped to fit under 79 columns. Verified byte-identical output at widths 79, +80, 88, 100, 120 and 200, and the file passes `ruff check`/`ruff format --check` +under both this repo's config and a bare `--isolated` default. diff --git a/scripts/assemble_todo.py b/scripts/assemble_todo.py index ca48fd40..edfc7d17 100755 --- a/scripts/assemble_todo.py +++ b/scripts/assemble_todo.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # file: scripts/assemble_todo.py -# version: 1.1.0 +# version: 1.2.0 # guid: af7ef324-6c69-411e-b1a9-98c9ba2b31e3 # last-edited: 2026-07-19 @@ -50,10 +50,12 @@ HTML_COMMENT = re.compile(r"", re.DOTALL) VERSION_HEADER = re.compile( - r"^()$", re.M + r"^()$", + re.M, ) LAST_EDITED_HEADER = re.compile( - r"^()$", re.M + r"^()$", + re.M, ) @@ -81,9 +83,8 @@ def find_fragments(fragment_dir: Path) -> list[Path]: """ if not fragment_dir.is_dir(): return [] - return sorted( - path for path in fragment_dir.glob("*.md") if path.name != "README.md" - ) + candidates = fragment_dir.glob("*.md") + return sorted(p for p in candidates if p.name != "README.md") def fragment_body(path: Path) -> str: @@ -121,7 +122,9 @@ def _bump(match: re.Match[str]) -> str: print("warning: no '' header to bump.") text, count = LAST_EDITED_HEADER.subn( - lambda m: f"{m.group(1)}{today}{m.group(3)}", text, count=1 + lambda m: f"{m.group(1)}{today}{m.group(3)}", + text, + count=1, ) if not count: print("warning: no '' header to refresh.") @@ -136,12 +139,13 @@ def insert_at_marker(text: str, marker: str, addition: str) -> str: scriv uses for release sections. """ marker_line = re.compile( - rf"^([ \t]*[ \t]*)$", re.M + rf"^([ \t]*[ \t]*)$", + re.M, ) match = marker_line.search(text) if not match: raise AssemblyError( - f"Output file has no '' marker; refusing to guess where tasks belong." + f"No '' marker in the output file; refusing to guess where tasks belong.", ) return text[: match.end()] + f"\n\n{addition}" + text[match.end() :]