Skip to content

Commit 4ea999e

Browse files
feat(cli): add ConversionReport to ResultReporter bridge
Implements add_from_conversion_report() method that maps: - report.operation → resource ConsequenceType - UPDATED → ConsequenceType.UPDATE - UNSUPPORTED → ConsequenceType.SKIP - UNCHANGED → ConsequenceType.UNCHANGED
1 parent 8e6efc0 commit 4ea999e

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

hatch/cli/cli_utils.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,64 @@ def add(
324324
)
325325
self._consequences.append(consequence)
326326

327+
def add_from_conversion_report(self, report: "ConversionReport") -> None:
328+
"""Convert ConversionReport field operations to nested consequences.
329+
330+
Maps ConversionReport data to the unified consequence model:
331+
- report.operation → resource ConsequenceType
332+
- field_op "UPDATED" → ConsequenceType.UPDATE
333+
- field_op "UNSUPPORTED" → ConsequenceType.SKIP
334+
- field_op "UNCHANGED" → ConsequenceType.UNCHANGED
335+
336+
Reference: R06 §3.5 (06-dependency_analysis_v0.md)
337+
Reference: R04 §1.2 (04-reporting_infrastructure_coexistence_v0.md)
338+
339+
Args:
340+
report: ConversionReport with field operations to convert
341+
342+
Invariants:
343+
- All field operations become children of resource consequence
344+
- UNSUPPORTED fields include "(unsupported by host)" suffix
345+
"""
346+
# Import here to avoid circular dependency
347+
from hatch.mcp_host_config.reporting import ConversionReport
348+
349+
# Map report.operation to resource ConsequenceType
350+
operation_map = {
351+
"create": ConsequenceType.CONFIGURE,
352+
"update": ConsequenceType.CONFIGURE,
353+
"delete": ConsequenceType.REMOVE,
354+
"migrate": ConsequenceType.CONFIGURE,
355+
}
356+
resource_type = operation_map.get(report.operation, ConsequenceType.CONFIGURE)
357+
358+
# Build resource message
359+
resource_message = f"Server '{report.server_name}' on '{report.target_host.value}'"
360+
361+
# Map field operations to child consequences
362+
field_op_map = {
363+
"UPDATED": ConsequenceType.UPDATE,
364+
"UNSUPPORTED": ConsequenceType.SKIP,
365+
"UNCHANGED": ConsequenceType.UNCHANGED,
366+
}
367+
368+
children = []
369+
for field_op in report.field_operations:
370+
child_type = field_op_map.get(field_op.operation, ConsequenceType.UPDATE)
371+
372+
# Format field message based on operation type
373+
if field_op.operation == "UPDATED":
374+
child_message = f"{field_op.field_name}: {repr(field_op.old_value)}{repr(field_op.new_value)}"
375+
elif field_op.operation == "UNSUPPORTED":
376+
child_message = f"{field_op.field_name}: (unsupported by host)"
377+
else: # UNCHANGED
378+
child_message = f"{field_op.field_name}: {repr(field_op.new_value)}"
379+
380+
children.append(Consequence(type=child_type, message=child_message))
381+
382+
# Add the resource consequence with children
383+
self.add(resource_type, resource_message, children=children)
384+
327385
def _format_consequence(
328386
self,
329387
consequence: Consequence,

0 commit comments

Comments
 (0)