Add ResultReport hook
This commit is contained in:
		| @@ -6,8 +6,6 @@ from typing import Any | |||||||
| from pydantic import BaseModel, ConfigDict, Field | from pydantic import BaseModel, ConfigDict, Field | ||||||
| from rich.console import Console | from rich.console import Console | ||||||
|  |  | ||||||
| console = Console(color_system="auto") |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class ExecutionContext(BaseModel): | class ExecutionContext(BaseModel): | ||||||
|     name: str |     name: str | ||||||
| @@ -23,6 +21,7 @@ class ExecutionContext(BaseModel): | |||||||
|     end_wall: datetime | None = None |     end_wall: datetime | None = None | ||||||
|  |  | ||||||
|     extra: dict[str, Any] = Field(default_factory=dict) |     extra: dict[str, Any] = Field(default_factory=dict) | ||||||
|  |     console: Console = Field(default_factory=lambda: Console(color_system="auto")) | ||||||
|  |  | ||||||
|     model_config = ConfigDict(arbitrary_types_allowed=True) |     model_config = ConfigDict(arbitrary_types_allowed=True) | ||||||
|  |  | ||||||
| @@ -75,7 +74,7 @@ class ExecutionContext(BaseModel): | |||||||
|             message.append(f"❌ Exception: {summary['exception']}") |             message.append(f"❌ Exception: {summary['exception']}") | ||||||
|         else: |         else: | ||||||
|             message.append(f"✅ Result: {summary['result']}") |             message.append(f"✅ Result: {summary['result']}") | ||||||
|         (logger or console.print)("".join(message)) |         (logger or self.console.print)("".join(message)) | ||||||
|  |  | ||||||
|     def to_log_line(self) -> str: |     def to_log_line(self) -> str: | ||||||
|         """Structured flat-line format for logging and metrics.""" |         """Structured flat-line format for logging and metrics.""" | ||||||
|   | |||||||
| @@ -791,11 +791,10 @@ class Falyx: | |||||||
|                 sys.exit(1) |                 sys.exit(1) | ||||||
|             self._set_retry_policy(command) |             self._set_retry_policy(command) | ||||||
|             try: |             try: | ||||||
|                 result = await self.headless(self.cli_args.name) |                 await self.headless(self.cli_args.name) | ||||||
|             except FalyxError as error: |             except FalyxError as error: | ||||||
|                 self.console.print(f"[{OneColors.DARK_RED}]❌ Error: {error}[/]") |                 self.console.print(f"[{OneColors.DARK_RED}]❌ Error: {error}[/]") | ||||||
|                 sys.exit(1) |                 sys.exit(1) | ||||||
|             self.console.print(f"[{OneColors.GREEN}]✅ Result:[/] {result}") |  | ||||||
|             sys.exit(0) |             sys.exit(0) | ||||||
|  |  | ||||||
|         if self.cli_args.command == "run-all": |         if self.cli_args.command == "run-all": | ||||||
| @@ -807,7 +806,7 @@ class Falyx: | |||||||
|                 self.console.print(f"[{OneColors.LIGHT_YELLOW}]⚠️ No commands found with tag: '{self.cli_args.tag}'[/]") |                 self.console.print(f"[{OneColors.LIGHT_YELLOW}]⚠️ No commands found with tag: '{self.cli_args.tag}'[/]") | ||||||
|                 sys.exit(1) |                 sys.exit(1) | ||||||
|  |  | ||||||
|             self.console.print(f"[bold cyan]🚀 Running all commands with tag:[/] {self.cli_args.tag}") |             self.console.print(f"[{OneColors.CYAN_b}]🚀 Running all commands with tag:[/] {self.cli_args.tag}") | ||||||
|             for cmd in matching: |             for cmd in matching: | ||||||
|                 self._set_retry_policy(cmd) |                 self._set_retry_policy(cmd) | ||||||
|                 await self.headless(cmd.key) |                 await self.headless(cmd.key) | ||||||
|   | |||||||
| @@ -3,9 +3,29 @@ import time | |||||||
|  |  | ||||||
| from falyx.context import ExecutionContext | from falyx.context import ExecutionContext | ||||||
| from falyx.exceptions import CircuitBreakerOpen | from falyx.exceptions import CircuitBreakerOpen | ||||||
|  | from falyx.themes.colors import OneColors | ||||||
| from falyx.utils import logger | from falyx.utils import logger | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ResultReporter: | ||||||
|  |     def __init__(self, formatter: callable = None): | ||||||
|  |         """ | ||||||
|  |         Optional result formatter. If not provided, uses repr(result). | ||||||
|  |         """ | ||||||
|  |         self.formatter = formatter or (lambda r: repr(r)) | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def __name__(self): | ||||||
|  |         return "ResultReporter" | ||||||
|  |  | ||||||
|  |     async def report(self, context: ExecutionContext): | ||||||
|  |         if context.result is not None: | ||||||
|  |             result_text = self.formatter(context.result) | ||||||
|  |             duration = f"{context.duration:.3f}s" if context.duration is not None else "n/a" | ||||||
|  |             context.console.print(f"[{OneColors.GREEN}]✅ '{context.name}' " | ||||||
|  |                   f"completed:[/] {result_text} in {duration}.") | ||||||
|  |  | ||||||
|  |  | ||||||
| class CircuitBreaker: | class CircuitBreaker: | ||||||
|     def __init__(self, max_failures=3, reset_timeout=10): |     def __init__(self, max_failures=3, reset_timeout=10): | ||||||
|         self.max_failures = max_failures |         self.max_failures = max_failures | ||||||
| @@ -41,4 +61,3 @@ class CircuitBreaker: | |||||||
|         self.failures = 0 |         self.failures = 0 | ||||||
|         self.open_until = None |         self.open_until = None | ||||||
|         logger.info("🔄 Circuit reset.") |         logger.info("🔄 Circuit reset.") | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| [tool.poetry] | [tool.poetry] | ||||||
| name = "falyx" | name = "falyx" | ||||||
| version = "0.1.2" | version = "0.1.4" | ||||||
| description = "Reliable and introspectable async CLI action framework." | description = "Reliable and introspectable async CLI action framework." | ||||||
| authors = ["Roland Thomas Jr <roland@rtj.dev>"] | authors = ["Roland Thomas Jr <roland@rtj.dev>"] | ||||||
| license = "MIT" | license = "MIT" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user