From 5c8441137ad4e4b565646ca36bc847d265cefce9 Mon Sep 17 00:00:00 2001 From: Austin Gregg-Smith Date: Sun, 9 Aug 2026 07:55:55 +0100 Subject: [PATCH 01/13] Emit an env-gated timing summary at the end of every dl command DEVLAUNCH_TIMING=1 makes main() end with a dl-timing total line on stderr; unset means no output and no recording. Ticket #140 slice 1. --- devlaunch/dl.py | 8 ++- devlaunch/timing.py | 116 ++++++++++++++++++++++++++++++++++++++++++++ test/test_timing.py | 36 ++++++++++++++ 3 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 devlaunch/timing.py create mode 100644 test/test_timing.py diff --git a/devlaunch/dl.py b/devlaunch/dl.py index 991cd159..d65b1482 100644 --- a/devlaunch/dl.py +++ b/devlaunch/dl.py @@ -36,7 +36,7 @@ from urllib.parse import urlparse from urllib.request import url2pathname -from . import devpod_ssh, disk_usage, gh_auth, tools, tty_session, workspace_state +from . import devpod_ssh, disk_usage, gh_auth, timing, tools, tty_session, workspace_state from .completion import install_completions from .workspace_id import TARGET_LENGTH, WorkspaceId, slug, source_workspace_id, validate_ref_name from .worktree.config import get_worktree_config @@ -2361,6 +2361,10 @@ def main(argv: Optional[List[str]] = None) -> int: # a caller that drives main() twice (a test, a shell wrapper) must not have # the first command's view of devpod answer the second command's questions. invalidate_workspace_list_cache() + # Timing is per-command, like the workspace-list snapshot: begin() here so + # a second main() in the same process starts a fresh summary, emit() in the + # finally so the summary lands on stderr however the command ended. + timing.begin() try: return _run_cli(argv) except MissingBinary as e: @@ -2369,6 +2373,8 @@ def main(argv: Optional[List[str]] = None) -> int: except UnreadableWorkspaceList as e: print(f"error: {e}", file=sys.stderr) return UNREADABLE_WORKSPACE_LIST_EXIT_CODE + finally: + timing.emit() def _run_cli(argv: Optional[List[str]] = None) -> int: diff --git a/devlaunch/timing.py b/devlaunch/timing.py new file mode 100644 index 00000000..7085d994 --- /dev/null +++ b/devlaunch/timing.py @@ -0,0 +1,116 @@ +"""Env-gated wall-clock timing for dl's subprocess round trips. + +Set ``DEVLAUNCH_TIMING=1`` and every dl process ends with one summary on +stderr: one ``dl-timing: