labnotes 0.0.97__tar.gz → 0.0.98__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {labnotes-0.0.97 → labnotes-0.0.98}/PKG-INFO +5 -5
- {labnotes-0.0.97 → labnotes-0.0.98}/README.md +4 -4
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/browse_app.py +1 -1
- labnotes-0.0.98/src/labnotes/tui/leave_prompt.py +28 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/run_app.py +22 -8
- {labnotes-0.0.97 → labnotes-0.0.98}/.gitignore +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/CHANGELOG.md +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/MIGRATIONS.md +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/pyproject.toml +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/__init__.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/__main__.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/asset_url.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/check_counts.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/cli.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/context.md +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/context_guide.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/count_groups.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/count_runs.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/create_app.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/create_experiment.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/create_note.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/__init__.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/control_run.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/daemon_app.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/daemon_client.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/daemon_running.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/daemon_server.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/describe_status.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/ensure_daemon.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/exit_when_idle.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/remote_start.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/run_daemon.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/run_logs.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/serve_daemon.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/socket_path.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/stop_runs.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/watch_daemon.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon/watch_status.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/daemon_command.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/data_html.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/default_config_text.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/default_counts.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/drain_watch.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/experiment_notes.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/experiment_runs.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/experiments.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/file_changes.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/format_duration.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/format_started.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/format_value.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/group_runs.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/init.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/invocation_started.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/is_positive_int.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/list_experiments.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/list_runs.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/load_config.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/load_experiment.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/load_run.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/log.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/log_path.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/models.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/modes.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/nests_runs.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/note_path.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/notebook_kernel.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/output_html.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/parse_run_view.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/print_rows.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/python_blocks.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/read_config.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/read_path.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/render_markdown.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/run_command.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/run_control.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/run_output.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/run_status.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/__init__.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/describe_event.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/execute_run.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/hold_folder.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/new_param_run_id.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/new_run_id.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/new_stamped_run_id.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/param_args.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/param_grid.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/param_run_name.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/plan_runs.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/prepare_experiment.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/read_experiment_config.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/run_experiment.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/run_folder.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/run_headless.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/runs_parent.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/shell_command.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/signal_tree.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/stop_then_kill.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/wait_for_tree.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/runner/write_run_json.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/save_conflict_copy.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/save_note.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/saved_outputs.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/serve_app.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/server.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/shared_params.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/sort_href.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/sql_quote.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/static/elapsed.js +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/static/experiment.js +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/static/labnotes.css +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/static/local-time.js +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/static/new-note.js +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/static/note-edit.js +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/static/note-editor.js +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/static/row-link.js +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/static/run-cell.js +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/static/run-output.js +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/static/view-toggle.js +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/summarize_config.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/__init__.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/experiment_rows.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/experiment_run_ids.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/file_prefix.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/file_text.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/iso_time.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/list_experiment_runs.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/note_text.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/open_tables.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/path_glob.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/path_pattern.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/read_experiment.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/read_file.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/read_log.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/read_run.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tables/summarize_experiments.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/templates/base.html +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/templates/editor_imports.html +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/templates/experiment.html +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/templates/index.html +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/templates/note.html +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/templates/run.html +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/__init__.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/browse_tui.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/dim.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/experiment_screen.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/experiments_screen.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/fill_table.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/format_elapsed.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/group_cells.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/invocation_columns.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/invocation_rows.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/reload_on_change.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/run_cells.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/run_output.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/run_screen.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/run_tui.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/runs_table.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/tui/stopped_title.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/wait_for_note.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/src/labnotes/watch_rows.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/testing-conventions.toml +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/tests/integration/conftest.py +0 -0
- {labnotes-0.0.97 → labnotes-0.0.98}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: labnotes
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.98
|
|
4
4
|
Summary: Browse experiment designs, notes, and run data from a folder.
|
|
5
5
|
Project-URL: Repository, https://github.com/thekevinscott/labnotes
|
|
6
6
|
Author-email: Kevin Scott <me@thekevinscott.com>
|
|
@@ -108,14 +108,14 @@ To exclude a run, add `"excluded": true` and an optional `"reason"` to its
|
|
|
108
108
|
replaces it; both show as columns in `runs`.
|
|
109
109
|
|
|
110
110
|
In a terminal, `run` shows a live table of runs (status and time) and stays
|
|
111
|
-
open when they finish;
|
|
111
|
+
open when they finish; Ctrl-C quits. Elsewhere, it prints a
|
|
112
112
|
line per event instead.
|
|
113
113
|
|
|
114
114
|
- `--concurrency N` runs N at a time (default 1).
|
|
115
115
|
- `-e PATH` reads another file instead of `experiment.toml`.
|
|
116
|
-
- Ctrl-C
|
|
117
|
-
|
|
118
|
-
|
|
116
|
+
- With runs going, Ctrl-C asks first. Enter (or a second Ctrl-C) leaves them
|
|
117
|
+
running. `s` stops the running scripts and records their end, then kills any
|
|
118
|
+
still going 5 seconds later. Escape goes back. SIGTERM stops them like `s`.
|
|
119
119
|
- A second `run` of the same experiment fails while the first holds the lock.
|
|
120
120
|
- It exits 0 even if runs fail; the summary line counts failures. If it can't
|
|
121
121
|
start or reach the daemon, it prints the cause on one line and exits 1.
|
|
@@ -84,14 +84,14 @@ To exclude a run, add `"excluded": true` and an optional `"reason"` to its
|
|
|
84
84
|
replaces it; both show as columns in `runs`.
|
|
85
85
|
|
|
86
86
|
In a terminal, `run` shows a live table of runs (status and time) and stays
|
|
87
|
-
open when they finish;
|
|
87
|
+
open when they finish; Ctrl-C quits. Elsewhere, it prints a
|
|
88
88
|
line per event instead.
|
|
89
89
|
|
|
90
90
|
- `--concurrency N` runs N at a time (default 1).
|
|
91
91
|
- `-e PATH` reads another file instead of `experiment.toml`.
|
|
92
|
-
- Ctrl-C
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
- With runs going, Ctrl-C asks first. Enter (or a second Ctrl-C) leaves them
|
|
93
|
+
running. `s` stops the running scripts and records their end, then kills any
|
|
94
|
+
still going 5 seconds later. Escape goes back. SIGTERM stops them like `s`.
|
|
95
95
|
- A second `run` of the same experiment fails while the first holds the lock.
|
|
96
96
|
- It exits 0 even if runs fail; the summary line counts failures. If it can't
|
|
97
97
|
start or reach the daemon, it prints the cause on one line and exits 1.
|
|
@@ -8,7 +8,7 @@ from labnotes.tui.experiments_screen import ExperimentsScreen
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class BrowseApp(App[BaseException | None]):
|
|
11
|
-
BINDINGS = [Binding("
|
|
11
|
+
BINDINGS = [Binding("ctrl+c", "quit", "Quit")]
|
|
12
12
|
|
|
13
13
|
def __init__(self, config: LabnotesConfig, name: str | None) -> None:
|
|
14
14
|
super().__init__()
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from textual.app import ComposeResult
|
|
2
|
+
from textual.binding import Binding
|
|
3
|
+
from textual.screen import ModalScreen
|
|
4
|
+
from textual.widgets import Static
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class LeavePrompt(ModalScreen[str | None]):
|
|
8
|
+
CSS = """
|
|
9
|
+
LeavePrompt { align: center middle; }
|
|
10
|
+
#prompt { width: auto; padding: 1 2; border: round $accent; }
|
|
11
|
+
"""
|
|
12
|
+
BINDINGS = [
|
|
13
|
+
Binding("enter,ctrl+c", "dismiss('leave')", "Leave running"),
|
|
14
|
+
Binding("s", "dismiss('stop')", "Stop them"),
|
|
15
|
+
Binding("escape", "dismiss", "Cancel"),
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
def __init__(self, count: int) -> None:
|
|
19
|
+
super().__init__()
|
|
20
|
+
self.count = count
|
|
21
|
+
|
|
22
|
+
def compose(self) -> ComposeResult:
|
|
23
|
+
runs = "run" if self.count == 1 else "runs"
|
|
24
|
+
yield Static(
|
|
25
|
+
f"{self.count} {runs} still going. "
|
|
26
|
+
"Leave them running (enter) / stop them (s) / cancel (esc).",
|
|
27
|
+
id="prompt",
|
|
28
|
+
)
|
|
@@ -10,10 +10,11 @@ from textual.widgets import DataTable, Footer, Header, Input, Static
|
|
|
10
10
|
|
|
11
11
|
from labnotes.models import Controls, Start
|
|
12
12
|
from labnotes.runner.describe_event import describe_event
|
|
13
|
-
from labnotes.runner.stop_then_kill import stop_then_kill
|
|
13
|
+
from labnotes.runner.stop_then_kill import GRACE_SECONDS, stop_then_kill
|
|
14
14
|
from labnotes.runner.param_args import param_args
|
|
15
15
|
from labnotes.tui.dim import dim
|
|
16
16
|
from labnotes.tui.format_elapsed import format_elapsed
|
|
17
|
+
from labnotes.tui.leave_prompt import LeavePrompt
|
|
17
18
|
from labnotes.tui.run_output import RunOutput
|
|
18
19
|
from labnotes.tui.runs_table import RunsTable
|
|
19
20
|
|
|
@@ -29,7 +30,7 @@ GRABBING_ACTIONS = {*GRABBED_ACTIONS, "grab", "quit", "interrupt", "command_pale
|
|
|
29
30
|
class RunApp(App[None]):
|
|
30
31
|
CSS = "#concurrency { dock: right; width: auto; padding: 0 1; }"
|
|
31
32
|
BINDINGS = [
|
|
32
|
-
Binding("ctrl+c", "interrupt", "
|
|
33
|
+
Binding("ctrl+c", "interrupt", "Quit"),
|
|
33
34
|
Binding("n", "run_next", "Run next"),
|
|
34
35
|
Binding("m", "grab", "Move"),
|
|
35
36
|
Binding("j,down", "shift(1)", priority=True),
|
|
@@ -45,7 +46,6 @@ class RunApp(App[None]):
|
|
|
45
46
|
Binding("escape", "leave", "Back"),
|
|
46
47
|
Binding("plus,equals_sign", "concurrency(1)", "More at once", key_display="+"),
|
|
47
48
|
Binding("minus", "concurrency(-1)", "Fewer at once", key_display="-"),
|
|
48
|
-
Binding("q", "quit", "Quit"),
|
|
49
49
|
]
|
|
50
50
|
|
|
51
51
|
def __init__(self, start: Start, title: str) -> None:
|
|
@@ -111,7 +111,7 @@ class RunApp(App[None]):
|
|
|
111
111
|
|
|
112
112
|
def listen(self, controls: Controls) -> None:
|
|
113
113
|
self.controls = controls
|
|
114
|
-
stop_then_kill(self.
|
|
114
|
+
stop_then_kill(self.stop_runs, signal.SIGTERM)
|
|
115
115
|
asyncio.get_running_loop().add_signal_handler(signal.SIGHUP, self.exit)
|
|
116
116
|
|
|
117
117
|
def show_event(self, event: dict[str, object]) -> None:
|
|
@@ -200,7 +200,7 @@ class RunApp(App[None]):
|
|
|
200
200
|
def show_summary(self) -> None:
|
|
201
201
|
failed = len(self.failed)
|
|
202
202
|
passed = len(self.ended) - failed
|
|
203
|
-
self.show(f"{passed} passed, {failed} failed.
|
|
203
|
+
self.show(f"{passed} passed, {failed} failed. Ctrl-C to quit.")
|
|
204
204
|
|
|
205
205
|
def reposition(self, event: dict[str, object], run: str) -> None:
|
|
206
206
|
table = self.query_one(DataTable)
|
|
@@ -231,6 +231,8 @@ class RunApp(App[None]):
|
|
|
231
231
|
table.update_cell(run, column, cell, update_width=True)
|
|
232
232
|
|
|
233
233
|
def check_action(self, action: str, parameters: tuple[object, ...]) -> bool:
|
|
234
|
+
if isinstance(self.screen, LeavePrompt):
|
|
235
|
+
return False
|
|
234
236
|
if self.grabbed is not None:
|
|
235
237
|
return action in GRABBING_ACTIONS
|
|
236
238
|
if action in GRABBED_ACTIONS:
|
|
@@ -254,18 +256,30 @@ class RunApp(App[None]):
|
|
|
254
256
|
self.next_run = None
|
|
255
257
|
self.query_one("#status", Static).update(text)
|
|
256
258
|
|
|
257
|
-
def
|
|
259
|
+
def stop_runs(self) -> None:
|
|
258
260
|
if self.idle:
|
|
259
261
|
self.controls.finish()
|
|
260
262
|
else:
|
|
261
263
|
self.controls.interrupt()
|
|
262
264
|
|
|
263
|
-
|
|
264
|
-
if self.
|
|
265
|
+
def action_interrupt(self) -> None:
|
|
266
|
+
if self.started:
|
|
267
|
+
self.push_screen(LeavePrompt(len(self.started)), self.answer)
|
|
268
|
+
elif self.idle:
|
|
265
269
|
self.controls.finish()
|
|
266
270
|
else:
|
|
267
271
|
self.exit()
|
|
268
272
|
|
|
273
|
+
async def action_quit(self) -> None:
|
|
274
|
+
self.action_interrupt()
|
|
275
|
+
|
|
276
|
+
def answer(self, choice: str | None) -> None:
|
|
277
|
+
if choice == "leave":
|
|
278
|
+
self.exit()
|
|
279
|
+
elif choice == "stop":
|
|
280
|
+
self.controls.interrupt()
|
|
281
|
+
self.set_timer(GRACE_SECONDS, self.controls.interrupt)
|
|
282
|
+
|
|
269
283
|
def cursor_run(self) -> str | None:
|
|
270
284
|
table = self.query_one(DataTable)
|
|
271
285
|
if not table.row_count:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|