Say when a run finished and when a failure happened
`fluksio status` listed recent runs and recent failures with no time on them, so a red line said nothing about whether it was from a minute ago or last week. Both carry an age now, spelled the way a duration is, and the runs listing gained one too. The fields were already on the wire. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019Hra4ndWMCLU5F3KjUuVAc
This commit is contained in:
@@ -19,6 +19,7 @@ import sys
|
||||
import time
|
||||
from collections.abc import Callable, Iterable, Iterator
|
||||
from contextlib import contextmanager, nullcontext
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@@ -804,7 +805,8 @@ def _status_screen(client: Client) -> Any:
|
||||
)
|
||||
+ Text(
|
||||
f"{str(row.get('flow', '')):<16}"
|
||||
f"{(row.get('duration_ms') or 0) / 1000:7.1f}s",
|
||||
f"{(row.get('duration_ms') or 0) / 1000:7.1f}s"
|
||||
f" {_ago(row.get('finished_at') or row.get('created_at')):>9}",
|
||||
style="dim",
|
||||
)
|
||||
)
|
||||
@@ -816,6 +818,7 @@ def _status_screen(client: Client) -> Any:
|
||||
)
|
||||
parts.append(
|
||||
Text(f" {where} ", style="red")
|
||||
+ Text(f"{_ago(event.get('ts')):>9} ", style="dim")
|
||||
+ Text(str(event.get("detail", ""))[:100], style="dim")
|
||||
)
|
||||
return Group(*parts)
|
||||
@@ -857,9 +860,9 @@ def cmd_status(args: argparse.Namespace) -> int:
|
||||
#: value is read.
|
||||
PARAMS_WIDTH = 80
|
||||
|
||||
#: What the columns before the inputs take: the id, status, flow, duration and
|
||||
#: stamp, with their spacing.
|
||||
LISTING_WIDTH = 84
|
||||
#: What the columns before the inputs take: the id, status, flow, duration,
|
||||
#: age and stamp, with their spacing.
|
||||
LISTING_WIDTH = 95
|
||||
|
||||
|
||||
def _declared(client: Client, flows: Iterable[str]) -> dict[str, dict[str, Any]]:
|
||||
@@ -883,6 +886,28 @@ def _declared(client: Client, flows: Iterable[str]) -> dict[str, dict[str, Any]]
|
||||
return known
|
||||
|
||||
|
||||
def _ago(stamp: Any) -> str:
|
||||
"""How long ago something happened, in the notation the screens use.
|
||||
|
||||
A duration and an age read together, so they are spelled the same way:
|
||||
seconds, then minutes, hours, days.
|
||||
"""
|
||||
if not stamp:
|
||||
return ""
|
||||
try:
|
||||
then = datetime.fromisoformat(str(stamp))
|
||||
except ValueError:
|
||||
return ""
|
||||
if then.tzinfo is None:
|
||||
# Everything the engine records is UTC; only some spellings say so.
|
||||
then = then.replace(tzinfo=UTC)
|
||||
seconds = max((datetime.now(UTC) - then).total_seconds(), 0)
|
||||
for span, unit in ((86400, "d"), (3600, "h"), (60, "min")):
|
||||
if seconds >= span:
|
||||
return f"{seconds / span:.0f}{unit} ago"
|
||||
return f"{seconds:.0f}s ago"
|
||||
|
||||
|
||||
def _stamp(row: dict[str, Any]) -> str:
|
||||
"""What code a run ran: the commit, whether it was dirty, and the digest.
|
||||
|
||||
@@ -925,7 +950,8 @@ def cmd_runs(args: argparse.Namespace) -> int:
|
||||
params = params[: room - 3] + "..."
|
||||
_say(
|
||||
f"{row['id']} {_status(row['status'], 9)} {row['flow']:<16} "
|
||||
f"{row['duration_ms'] / 1000:7.1f}s {_stamp(row):<22} {params}"
|
||||
f"{row['duration_ms'] / 1000:7.1f}s {_ago(row.get('created_at')):>9} "
|
||||
f"{_stamp(row):<22} {params}"
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user