Two things the sweep could not see

A block that renders to nothing still counted toward the separator, so
`config restore --dry-run` opened with a blank line it did not have — the plan
is a listing under an outcome that says everything it has to say in the exit
status. The separator now counts what was drawn.

And the device inventory declared `port` and `address` in its rows and never in
its columns, so both fell out of the document: a caller had to parse the target
for a colon to find out which transport it was holding.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jean-Pierre MartineauandClaude Opus 5 committed 2026-09-08 03:59:26 -04:00
1 parent e3ae668f4a
commit 5215a1b76c
3 files changed
+33 -3

No files matched your search

+4
View File
@@ -153,6 +153,10 @@ def _listing(devices: list, known: dict, remembered: object, active_target: str
columns=(
fields.word("target", "TARGET"),
fields.word("transport", "TRANSPORT"),
# The two halves `target` is one of, kept apart for a caller that has to know
# which transport it is holding without parsing the target for a colon.
fields.hidden("port"),
fields.hidden("address"),
fields.name("label", "NAME"),
fields.name("hardware", "HARDWARE"),
fields.word("meshcore", "MESHCORE"),
+11 -3
View File
@@ -100,14 +100,22 @@ class PlainRenderer(Renderer):
self.console = console
def render(self, report: Report | None) -> None:
"""Draw each block in order, one blank line between them."""
for index, block in enumerate(report or ()):
"""Draw each block in order, one blank line between them.
The separator is counted off what was *drawn* rather than off the block index: a
block can render to nothing (a listing with no rows, an acknowledgement whose plain
answer is its exit status), and a blank line above the first visible block would be
a line of output the command did not have.
"""
drawn_any = False
for block in report or ():
drawn = self._block(block)
if drawn is None:
continue
if index:
if drawn_any:
self.console.print(script.blank())
self.console.print(drawn)
drawn_any = True
def _block(self, block: Block) -> Any:
"""The renderable for one block, or ``None`` where it prints nothing."""
+18
View File
@@ -270,6 +270,24 @@ def test_a_block_drawn_only_for_a_person_never_reaches_the_document() -> None:
assert _json(facts, summary) == {"packets": 2}
def test_a_block_that_prints_nothing_leaves_no_blank_line_where_it_stood() -> None:
"""The separator is counted off what was drawn, not off the block index.
``config restore --dry-run`` states its outcome silently and its plan as a listing, and
counting positions instead opened the command with an empty line — output it did not
have, in whatever was reading it.
"""
silent = Facts(
key="restore", fields=(fields.flag("dry_run", "dry_run"),), values={}, shape=SILENT
)
plan = Listing(
key="operations",
columns=(fields.word("operation", "OPERATION"),),
rows=[{"operation": "set"}],
)
assert _plain(silent, plan).splitlines()[0] == "OPERATION"
# -- the document's own rules ----------------------------------------------------------