ask-shell 0.6.0__tar.gz → 0.7.0__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.
Files changed (28) hide show
  1. {ask_shell-0.6.0 → ask_shell-0.7.0}/PKG-INFO +1 -1
  2. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/__init__.py +3 -1
  3. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/_run.py +4 -0
  4. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/models.py +3 -0
  5. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/rich_progress.py +7 -1
  6. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/rich_run_state.py +6 -0
  7. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/settings.py +11 -0
  8. {ask_shell-0.6.0 → ask_shell-0.7.0}/pyproject.toml +1 -1
  9. {ask_shell-0.6.0 → ask_shell-0.7.0}/.gitignore +0 -0
  10. {ask_shell-0.6.0 → ask_shell-0.7.0}/LICENSE +0 -0
  11. {ask_shell-0.6.0 → ask_shell-0.7.0}/README.md +0 -0
  12. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/__main__.py +0 -0
  13. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/__init__.py +0 -0
  14. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/_run_env.py +0 -0
  15. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/events.py +0 -0
  16. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/global_callbacks.py +0 -0
  17. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/interactive.py +0 -0
  18. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/rich_live.py +0 -0
  19. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/rich_live_callback.py +0 -0
  20. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/run_pool.py +0 -0
  21. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/_internal/typer_command.py +0 -0
  22. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/ask.py +0 -0
  23. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/console.py +0 -0
  24. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/py.typed +0 -0
  25. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/shell.py +0 -0
  26. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/shell_events.py +0 -0
  27. {ask_shell-0.6.0 → ask_shell-0.7.0}/ask_shell/test_docs.py +0 -0
  28. {ask_shell-0.6.0 → ask_shell-0.7.0}/scripts/fix_source_links.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ask-shell
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: CLIs with prompts, shell runs, and testable flows
5
5
  Author-email: EspenAlbert <espen.albert1@gmail.com>
6
6
  License-Expression: MIT
@@ -5,12 +5,14 @@ from ask_shell import console
5
5
  from ask_shell import shell_events
6
6
  from ask_shell import ask
7
7
  from ask_shell.settings import AskShellSettings
8
+ from ask_shell.settings import ShellRunSummary
8
9
 
9
- VERSION = "0.6.0"
10
+ VERSION = "0.7.0"
10
11
  __all__ = [
11
12
  "shell",
12
13
  "console",
13
14
  "shell_events",
14
15
  "ask",
15
16
  "AskShellSettings",
17
+ "ShellRunSummary",
16
18
  ]
@@ -484,6 +484,7 @@ def run(
484
484
  start_timeout: float | None = None,
485
485
  terminal_width: int | None = None,
486
486
  skip_interactive_check: bool | None = None,
487
+ mute_shell_summary: bool | None = None,
487
488
  ) -> ShellRun:
488
489
  config = _as_config(
489
490
  config,
@@ -510,6 +511,7 @@ def run(
510
511
  skip_os_env=skip_os_env,
511
512
  terminal_width=terminal_width,
512
513
  skip_interactive_check=skip_interactive_check,
514
+ mute_shell_summary=mute_shell_summary,
513
515
  )
514
516
  assert not config.user_input, (
515
517
  "run() does not support user_input (only 1 should be active at a time), use run_and_wait() instead"
@@ -549,6 +551,7 @@ def run_and_wait(
549
551
  user_input: bool | None = None,
550
552
  terminal_width: int | None = None,
551
553
  skip_interactive_check: bool | None = None,
554
+ mute_shell_summary: bool | None = None,
552
555
  ) -> ShellRun:
553
556
  config = _as_config(
554
557
  script,
@@ -576,6 +579,7 @@ def run_and_wait(
576
579
  terminal_width=terminal_width,
577
580
  skip_interactive_check=skip_interactive_check,
578
581
  skip_progress_output=skip_progress_output,
582
+ mute_shell_summary=mute_shell_summary,
579
583
  )
580
584
  run = ShellRun(config)
581
585
  future = _pool.submit(_execute_run, run)
@@ -172,6 +172,9 @@ class ShellConfig(Entity):
172
172
  default=False,
173
173
  description="Skip transitive std out/err output, useful for large outputs that are not needed in the logs when running parallel scripts",
174
174
  )
175
+ mute_shell_summary: bool = Field(
176
+ default=False, description="Skip shell summary logging useful when you want to ✅ or ❌ in the logs"
177
+ )
175
178
  terminal_width: int | None = 999
176
179
 
177
180
  # advanced settings
@@ -47,10 +47,16 @@ def log_task_done(
47
47
  error: BaseException | None = None,
48
48
  description_override: str | None = None,
49
49
  extra_parts: list[str] | None = None,
50
+ soft_failure: bool = False,
50
51
  ):
51
52
  exit_comji = "❌" if force_error or error is not None else "✅"
52
53
  description = description_override or task.description
53
- log_call = logger.info if exit_comji == "✅" else logger.error
54
+ if exit_comji == "✅":
55
+ log_call = logger.info
56
+ elif soft_failure:
57
+ log_call = logger.warning
58
+ else:
59
+ log_call = logger.error
54
60
  message_parts = [f"{exit_comji} {description}"]
55
61
  if rich_task := task._rich_task:
56
62
  if finish_time := rich_task.finished_time:
@@ -21,6 +21,7 @@ from ask_shell._internal.models import (
21
21
  ShellRunEventT,
22
22
  )
23
23
  from ask_shell._internal.rich_progress import ProgressManager, log_task_done, new_task
24
+ from ask_shell.settings import ShellRunSummary
24
25
 
25
26
 
26
27
  def _deque_default() -> deque[str]:
@@ -144,6 +145,10 @@ class _RunState:
144
145
  task.update(stderr=run_info.stderr_str)
145
146
  task.__exit__(None, None, None)
146
147
  run = run_info.run
148
+ if run.config.mute_shell_summary:
149
+ return
150
+ if run.config.settings.shell_run_summary == ShellRunSummary.ERRORS_ONLY and run.clean_complete:
151
+ return
147
152
  log_task_done(
148
153
  task,
149
154
  force_error=not run.clean_complete,
@@ -151,4 +156,5 @@ class _RunState:
151
156
  extra_parts=[
152
157
  "" if run.current_attempt == 1 else f"attempt {run.current_attempt}",
153
158
  ],
159
+ soft_failure=run.config.allow_non_zero_exit and not run.clean_complete,
154
160
  )
@@ -1,6 +1,7 @@
1
1
  import logging
2
2
  import os
3
3
  from datetime import datetime, timedelta
4
+ from enum import StrEnum
4
5
  from functools import cached_property, lru_cache
5
6
  from pathlib import Path
6
7
  from pydoc import locate
@@ -90,6 +91,11 @@ LogLevelIgnoredCase: TypeAlias = Annotated[
90
91
  ]
91
92
 
92
93
 
94
+ class ShellRunSummary(StrEnum):
95
+ ALL = "all"
96
+ ERRORS_ONLY = "errors_only"
97
+
98
+
93
99
  class AskShellSettings(StaticSettings):
94
100
  model_config = ConfigDict(populate_by_name=True) # type: ignore
95
101
  log_level: LogLevelIgnoredCase = "UNSET"
@@ -136,6 +142,11 @@ class AskShellSettings(StaticSettings):
136
142
  description="Runs once If `run_logs_dir` is not set. Can be 'yesterday' or a date string like '2023-01-01'. Will clean all logs up until the specified date but not that date itself.",
137
143
  alias=f"{ENV_PREFIX}RUN_LOGS_CLEAN",
138
144
  )
145
+ ENV_NAME_SHELL_RUN_SUMMARY: ClassVar[str] = f"{ENV_PREFIX}SHELL_RUN_SUMMARY"
146
+ shell_run_summary: ShellRunSummary = Field(
147
+ default=ShellRunSummary.ALL,
148
+ alias=ENV_NAME_SHELL_RUN_SUMMARY,
149
+ )
139
150
 
140
151
  @model_validator(mode="after")
141
152
  def ensure_vars_set(self) -> Self:
@@ -2,7 +2,7 @@
2
2
 
3
3
  [project]
4
4
  name = "ask-shell"
5
- version = "0.6.0"
5
+ version = "0.7.0"
6
6
  description = "CLIs with prompts, shell runs, and testable flows"
7
7
  requires-python = ">=3.13"
8
8
  license = "MIT"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes