diff --git a/falyx/context.py b/falyx/context.py index 16e3f07..bef9e6b 100644 --- a/falyx/context.py +++ b/falyx/context.py @@ -6,8 +6,6 @@ from typing import Any from pydantic import BaseModel, ConfigDict, Field from rich.console import Console -console = Console(color_system="auto") - class ExecutionContext(BaseModel): name: str @@ -23,6 +21,7 @@ class ExecutionContext(BaseModel): end_wall: datetime | None = None 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) @@ -75,7 +74,7 @@ class ExecutionContext(BaseModel): message.append(f"❌ Exception: {summary['exception']}") else: 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: """Structured flat-line format for logging and metrics.""" diff --git a/falyx/falyx.py b/falyx/falyx.py index 5323312..e66031b 100644 --- a/falyx/falyx.py +++ b/falyx/falyx.py @@ -791,11 +791,10 @@ class Falyx: sys.exit(1) self._set_retry_policy(command) try: - result = await self.headless(self.cli_args.name) + await self.headless(self.cli_args.name) except FalyxError as error: self.console.print(f"[{OneColors.DARK_RED}]❌ Error: {error}[/]") sys.exit(1) - self.console.print(f"[{OneColors.GREEN}]✅ Result:[/] {result}") sys.exit(0) 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}'[/]") 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: self._set_retry_policy(cmd) await self.headless(cmd.key) diff --git a/falyx/hooks.py b/falyx/hooks.py index db0c732..66773ef 100644 --- a/falyx/hooks.py +++ b/falyx/hooks.py @@ -3,9 +3,29 @@ import time from falyx.context import ExecutionContext from falyx.exceptions import CircuitBreakerOpen +from falyx.themes.colors import OneColors 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: def __init__(self, max_failures=3, reset_timeout=10): self.max_failures = max_failures @@ -41,4 +61,3 @@ class CircuitBreaker: self.failures = 0 self.open_until = None logger.info("🔄 Circuit reset.") - diff --git a/pyproject.toml b/pyproject.toml index d56e4c4..d7bb8ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "falyx" -version = "0.1.2" +version = "0.1.4" description = "Reliable and introspectable async CLI action framework." authors = ["Roland Thomas Jr "] license = "MIT"