falyx 0.1.48__tar.gz → 0.1.50__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.
- {falyx-0.1.48 → falyx-0.1.50}/PKG-INFO +1 -1
- falyx-0.1.50/falyx/.coverage +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/base.py +1 -1
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/menu_action.py +4 -1
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/prompt_menu_action.py +4 -1
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/select_file_action.py +4 -1
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/selection_action.py +4 -1
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/user_input_action.py +4 -1
- {falyx-0.1.48 → falyx-0.1.50}/falyx/bottom_bar.py +1 -1
- {falyx-0.1.48 → falyx-0.1.50}/falyx/command.py +1 -1
- {falyx-0.1.48 → falyx-0.1.50}/falyx/config.py +1 -2
- {falyx-0.1.48 → falyx-0.1.50}/falyx/context.py +15 -2
- {falyx-0.1.48 → falyx-0.1.50}/falyx/debug.py +1 -1
- {falyx-0.1.48 → falyx-0.1.50}/falyx/execution_registry.py +98 -18
- {falyx-0.1.48 → falyx-0.1.50}/falyx/falyx.py +70 -21
- {falyx-0.1.48 → falyx-0.1.50}/falyx/init.py +1 -1
- {falyx-0.1.48 → falyx-0.1.50}/falyx/parsers/argparse.py +5 -2
- {falyx-0.1.48 → falyx-0.1.50}/falyx/selection.py +5 -5
- falyx-0.1.50/falyx/version.py +1 -0
- {falyx-0.1.48 → falyx-0.1.50}/pyproject.toml +1 -1
- falyx-0.1.48/falyx/version.py +0 -1
- {falyx-0.1.48 → falyx-0.1.50}/LICENSE +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/README.md +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/.pytyped +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/__init__.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/__main__.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/.pytyped +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/__init__.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/action.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/action_factory.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/action_group.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/chained_action.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/fallback_action.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/http_action.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/io_action.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/literal_input_action.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/mixins.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/process_action.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/process_pool_action.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/signal_action.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/action/types.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/exceptions.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/hook_manager.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/hooks.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/logger.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/menu.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/options_manager.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/parsers/.pytyped +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/parsers/__init__.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/parsers/parsers.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/parsers/signature.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/parsers/utils.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/prompt_utils.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/protocols.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/retry.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/retry_utils.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/signals.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/tagged_table.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/themes/__init__.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/themes/colors.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/utils.py +0 -0
- {falyx-0.1.48 → falyx-0.1.50}/falyx/validators.py +0 -0
Binary file
|
@@ -74,7 +74,7 @@ class BaseAction(ABC):
|
|
74
74
|
self.inject_into: str = inject_into
|
75
75
|
self._never_prompt: bool = never_prompt
|
76
76
|
self._skip_in_chain: bool = False
|
77
|
-
self.console = Console(color_system="
|
77
|
+
self.console = Console(color_system="truecolor")
|
78
78
|
self.options_manager: OptionsManager | None = None
|
79
79
|
|
80
80
|
if logging_hooks:
|
@@ -51,7 +51,10 @@ class MenuAction(BaseAction):
|
|
51
51
|
self.columns = columns
|
52
52
|
self.prompt_message = prompt_message
|
53
53
|
self.default_selection = default_selection
|
54
|
-
|
54
|
+
if isinstance(console, Console):
|
55
|
+
self.console = console
|
56
|
+
elif console:
|
57
|
+
raise ValueError("`console` must be an instance of `rich.console.Console`")
|
55
58
|
self.prompt_session = prompt_session or PromptSession()
|
56
59
|
self.include_reserved = include_reserved
|
57
60
|
self.show_table = show_table
|
@@ -43,7 +43,10 @@ class PromptMenuAction(BaseAction):
|
|
43
43
|
self.menu_options = menu_options
|
44
44
|
self.prompt_message = prompt_message
|
45
45
|
self.default_selection = default_selection
|
46
|
-
|
46
|
+
if isinstance(console, Console):
|
47
|
+
self.console = console
|
48
|
+
elif console:
|
49
|
+
raise ValueError("`console` must be an instance of `rich.console.Console`")
|
47
50
|
self.prompt_session = prompt_session or PromptSession()
|
48
51
|
self.include_reserved = include_reserved
|
49
52
|
|
@@ -76,7 +76,10 @@ class SelectFileAction(BaseAction):
|
|
76
76
|
self.prompt_message = prompt_message
|
77
77
|
self.suffix_filter = suffix_filter
|
78
78
|
self.style = style
|
79
|
-
|
79
|
+
if isinstance(console, Console):
|
80
|
+
self.console = console
|
81
|
+
elif console:
|
82
|
+
raise ValueError("`console` must be an instance of `rich.console.Console`")
|
80
83
|
self.prompt_session = prompt_session or PromptSession()
|
81
84
|
self.return_type = self._coerce_return_type(return_type)
|
82
85
|
|
@@ -67,7 +67,10 @@ class SelectionAction(BaseAction):
|
|
67
67
|
self.return_type: SelectionReturnType = self._coerce_return_type(return_type)
|
68
68
|
self.title = title
|
69
69
|
self.columns = columns
|
70
|
-
|
70
|
+
if isinstance(console, Console):
|
71
|
+
self.console = console
|
72
|
+
elif console:
|
73
|
+
raise ValueError("`console` must be an instance of `rich.console.Console`")
|
71
74
|
self.prompt_session = prompt_session or PromptSession()
|
72
75
|
self.default_selection = default_selection
|
73
76
|
self.prompt_message = prompt_message
|
@@ -40,7 +40,10 @@ class UserInputAction(BaseAction):
|
|
40
40
|
)
|
41
41
|
self.prompt_text = prompt_text
|
42
42
|
self.validator = validator
|
43
|
-
|
43
|
+
if isinstance(console, Console):
|
44
|
+
self.console = console
|
45
|
+
elif console:
|
46
|
+
raise ValueError("`console` must be an instance of `rich.console.Console`")
|
44
47
|
self.prompt_session = prompt_session or PromptSession()
|
45
48
|
|
46
49
|
def get_infer_target(self) -> tuple[None, None]:
|
@@ -30,7 +30,7 @@ class BottomBar:
|
|
30
30
|
key_validator: Callable[[str], bool] | None = None,
|
31
31
|
) -> None:
|
32
32
|
self.columns = columns
|
33
|
-
self.console = Console(color_system="
|
33
|
+
self.console = Console(color_system="truecolor")
|
34
34
|
self._named_items: dict[str, Callable[[], HTML]] = {}
|
35
35
|
self._value_getters: dict[str, Callable[[], Any]] = CaseInsensitiveDict()
|
36
36
|
self.toggle_keys: list[str] = []
|
@@ -18,11 +18,10 @@ from falyx.action.base import BaseAction
|
|
18
18
|
from falyx.command import Command
|
19
19
|
from falyx.falyx import Falyx
|
20
20
|
from falyx.logger import logger
|
21
|
-
from falyx.parsers import CommandArgumentParser
|
22
21
|
from falyx.retry import RetryPolicy
|
23
22
|
from falyx.themes import OneColors
|
24
23
|
|
25
|
-
console = Console(color_system="
|
24
|
+
console = Console(color_system="truecolor")
|
26
25
|
|
27
26
|
|
28
27
|
def wrap_if_needed(obj: Any, name=None) -> BaseAction | Command:
|
@@ -70,7 +70,7 @@ class ExecutionContext(BaseModel):
|
|
70
70
|
|
71
71
|
name: str
|
72
72
|
args: tuple = ()
|
73
|
-
kwargs: dict =
|
73
|
+
kwargs: dict = Field(default_factory=dict)
|
74
74
|
action: Any
|
75
75
|
result: Any | None = None
|
76
76
|
exception: Exception | None = None
|
@@ -80,8 +80,10 @@ class ExecutionContext(BaseModel):
|
|
80
80
|
start_wall: datetime | None = None
|
81
81
|
end_wall: datetime | None = None
|
82
82
|
|
83
|
+
index: int | None = None
|
84
|
+
|
83
85
|
extra: dict[str, Any] = Field(default_factory=dict)
|
84
|
-
console: Console = Field(default_factory=lambda: Console(color_system="
|
86
|
+
console: Console = Field(default_factory=lambda: Console(color_system="truecolor"))
|
85
87
|
|
86
88
|
shared_context: SharedContext | None = None
|
87
89
|
|
@@ -118,6 +120,17 @@ class ExecutionContext(BaseModel):
|
|
118
120
|
def status(self) -> str:
|
119
121
|
return "OK" if self.success else "ERROR"
|
120
122
|
|
123
|
+
@property
|
124
|
+
def signature(self) -> str:
|
125
|
+
"""
|
126
|
+
Returns a string representation of the action signature, including
|
127
|
+
its name and arguments.
|
128
|
+
"""
|
129
|
+
args = ", ".join(map(repr, self.args))
|
130
|
+
kwargs = ", ".join(f"{key}={value!r}" for key, value in self.kwargs.items())
|
131
|
+
signature = ", ".join(filter(None, [args, kwargs]))
|
132
|
+
return f"{self.name} ({signature})"
|
133
|
+
|
121
134
|
def as_dict(self) -> dict:
|
122
135
|
return {
|
123
136
|
"name": self.name,
|
@@ -8,7 +8,7 @@ from falyx.logger import logger
|
|
8
8
|
def log_before(context: ExecutionContext):
|
9
9
|
"""Log the start of an action."""
|
10
10
|
args = ", ".join(map(repr, context.args))
|
11
|
-
kwargs = ", ".join(f"{
|
11
|
+
kwargs = ", ".join(f"{key}={value!r}" for key, value in context.kwargs.items())
|
12
12
|
signature = ", ".join(filter(None, [args, kwargs]))
|
13
13
|
logger.info("[%s] Starting -> %s(%s)", context.name, context.action, signature)
|
14
14
|
|
@@ -29,7 +29,8 @@ from __future__ import annotations
|
|
29
29
|
|
30
30
|
from collections import defaultdict
|
31
31
|
from datetime import datetime
|
32
|
-
from
|
32
|
+
from threading import Lock
|
33
|
+
from typing import Literal
|
33
34
|
|
34
35
|
from rich import box
|
35
36
|
from rich.console import Console
|
@@ -70,23 +71,30 @@ class ExecutionRegistry:
|
|
70
71
|
ExecutionRegistry.summary()
|
71
72
|
"""
|
72
73
|
|
73
|
-
_store_by_name:
|
74
|
-
|
75
|
-
|
74
|
+
_store_by_name: dict[str, list[ExecutionContext]] = defaultdict(list)
|
75
|
+
_store_by_index: dict[int, ExecutionContext] = {}
|
76
|
+
_store_all: list[ExecutionContext] = []
|
77
|
+
_console = Console(color_system="truecolor")
|
78
|
+
_index = 0
|
79
|
+
_lock = Lock()
|
76
80
|
|
77
81
|
@classmethod
|
78
82
|
def record(cls, context: ExecutionContext):
|
79
83
|
"""Record an execution context."""
|
80
84
|
logger.debug(context.to_log_line())
|
85
|
+
with cls._lock:
|
86
|
+
context.index = cls._index
|
87
|
+
cls._store_by_index[cls._index] = context
|
88
|
+
cls._index += 1
|
81
89
|
cls._store_by_name[context.name].append(context)
|
82
90
|
cls._store_all.append(context)
|
83
91
|
|
84
92
|
@classmethod
|
85
|
-
def get_all(cls) ->
|
93
|
+
def get_all(cls) -> list[ExecutionContext]:
|
86
94
|
return cls._store_all
|
87
95
|
|
88
96
|
@classmethod
|
89
|
-
def get_by_name(cls, name: str) ->
|
97
|
+
def get_by_name(cls, name: str) -> list[ExecutionContext]:
|
90
98
|
return cls._store_by_name.get(name, [])
|
91
99
|
|
92
100
|
@classmethod
|
@@ -97,11 +105,79 @@ class ExecutionRegistry:
|
|
97
105
|
def clear(cls):
|
98
106
|
cls._store_by_name.clear()
|
99
107
|
cls._store_all.clear()
|
108
|
+
cls._store_by_index.clear()
|
100
109
|
|
101
110
|
@classmethod
|
102
|
-
def summary(
|
103
|
-
|
104
|
-
|
111
|
+
def summary(
|
112
|
+
cls,
|
113
|
+
name: str = "",
|
114
|
+
index: int | None = None,
|
115
|
+
result: int | None = None,
|
116
|
+
clear: bool = False,
|
117
|
+
last_result: bool = False,
|
118
|
+
status: Literal["all", "success", "error"] = "all",
|
119
|
+
):
|
120
|
+
if clear:
|
121
|
+
cls.clear()
|
122
|
+
cls._console.print(f"[{OneColors.GREEN}]✅ Execution history cleared.")
|
123
|
+
return
|
124
|
+
|
125
|
+
if last_result:
|
126
|
+
for ctx in reversed(cls._store_all):
|
127
|
+
if ctx.name.upper() not in [
|
128
|
+
"HISTORY",
|
129
|
+
"HELP",
|
130
|
+
"EXIT",
|
131
|
+
"VIEW EXECUTION HISTORY",
|
132
|
+
"BACK",
|
133
|
+
]:
|
134
|
+
cls._console.print(ctx.result)
|
135
|
+
return
|
136
|
+
cls._console.print(
|
137
|
+
f"[{OneColors.DARK_RED}]❌ No valid executions found to display last result."
|
138
|
+
)
|
139
|
+
return
|
140
|
+
|
141
|
+
if result is not None and result >= 0:
|
142
|
+
try:
|
143
|
+
result_context = cls._store_by_index[result]
|
144
|
+
except KeyError:
|
145
|
+
cls._console.print(
|
146
|
+
f"[{OneColors.DARK_RED}]❌ No execution found for index {index}."
|
147
|
+
)
|
148
|
+
return
|
149
|
+
cls._console.print(f"{result_context.signature}:")
|
150
|
+
if result_context.exception:
|
151
|
+
cls._console.print(result_context.exception)
|
152
|
+
else:
|
153
|
+
cls._console.print(result_context.result)
|
154
|
+
return
|
155
|
+
|
156
|
+
if name:
|
157
|
+
contexts = cls.get_by_name(name)
|
158
|
+
if not contexts:
|
159
|
+
cls._console.print(
|
160
|
+
f"[{OneColors.DARK_RED}]❌ No executions found for action '{name}'."
|
161
|
+
)
|
162
|
+
return
|
163
|
+
title = f"📊 Execution History for '{contexts[0].name}'"
|
164
|
+
elif index is not None and index >= 0:
|
165
|
+
try:
|
166
|
+
contexts = [cls._store_by_index[index]]
|
167
|
+
print(contexts)
|
168
|
+
except KeyError:
|
169
|
+
cls._console.print(
|
170
|
+
f"[{OneColors.DARK_RED}]❌ No execution found for index {index}."
|
171
|
+
)
|
172
|
+
return
|
173
|
+
title = f"📊 Execution History for Index {index}"
|
174
|
+
else:
|
175
|
+
contexts = cls.get_all()
|
176
|
+
title = "📊 Execution History"
|
177
|
+
|
178
|
+
table = Table(title=title, expand=True, box=box.SIMPLE)
|
179
|
+
|
180
|
+
table.add_column("Index", justify="right", style="dim")
|
105
181
|
table.add_column("Name", style="bold cyan")
|
106
182
|
table.add_column("Start", justify="right", style="dim")
|
107
183
|
table.add_column("End", justify="right", style="dim")
|
@@ -109,7 +185,7 @@ class ExecutionRegistry:
|
|
109
185
|
table.add_column("Status", style="bold")
|
110
186
|
table.add_column("Result / Exception", overflow="fold")
|
111
187
|
|
112
|
-
for ctx in
|
188
|
+
for ctx in contexts:
|
113
189
|
start = (
|
114
190
|
datetime.fromtimestamp(ctx.start_time).strftime("%H:%M:%S")
|
115
191
|
if ctx.start_time
|
@@ -122,15 +198,19 @@ class ExecutionRegistry:
|
|
122
198
|
)
|
123
199
|
duration = f"{ctx.duration:.3f}s" if ctx.duration else "n/a"
|
124
200
|
|
125
|
-
if ctx.exception:
|
126
|
-
|
127
|
-
|
201
|
+
if ctx.exception and status.lower() in ["all", "error"]:
|
202
|
+
final_status = f"[{OneColors.DARK_RED}]❌ Error"
|
203
|
+
final_result = repr(ctx.exception)
|
204
|
+
elif status.lower() in ["all", "success"]:
|
205
|
+
final_status = f"[{OneColors.GREEN}]✅ Success"
|
206
|
+
final_result = repr(ctx.result)
|
207
|
+
if len(final_result) > 1000:
|
208
|
+
final_result = f"{final_result[:1000]}..."
|
128
209
|
else:
|
129
|
-
|
130
|
-
result = repr(ctx.result)
|
131
|
-
if len(result) > 1000:
|
132
|
-
result = f"{result[:1000]}..."
|
210
|
+
continue
|
133
211
|
|
134
|
-
table.add_row(
|
212
|
+
table.add_row(
|
213
|
+
str(ctx.index), ctx.name, start, end, duration, final_status, final_result
|
214
|
+
)
|
135
215
|
|
136
216
|
cls._console.print(table)
|
@@ -201,7 +201,7 @@ class Falyx:
|
|
201
201
|
self.help_command: Command | None = (
|
202
202
|
self._get_help_command() if include_help_command else None
|
203
203
|
)
|
204
|
-
self.console: Console = Console(color_system="
|
204
|
+
self.console: Console = Console(color_system="truecolor", theme=get_nord_theme())
|
205
205
|
self.welcome_message: str | Markdown | dict[str, Any] = welcome_message
|
206
206
|
self.exit_message: str | Markdown | dict[str, Any] = exit_message
|
207
207
|
self.hooks: HookManager = HookManager()
|
@@ -300,6 +300,40 @@ class Falyx:
|
|
300
300
|
|
301
301
|
def _get_history_command(self) -> Command:
|
302
302
|
"""Returns the history command for the menu."""
|
303
|
+
parser = CommandArgumentParser(
|
304
|
+
command_key="Y",
|
305
|
+
command_description="History",
|
306
|
+
command_style=OneColors.DARK_YELLOW,
|
307
|
+
aliases=["HISTORY"],
|
308
|
+
)
|
309
|
+
parser.add_argument(
|
310
|
+
"-n",
|
311
|
+
"--name",
|
312
|
+
help="Filter by execution name.",
|
313
|
+
)
|
314
|
+
parser.add_argument(
|
315
|
+
"-i",
|
316
|
+
"--index",
|
317
|
+
type=int,
|
318
|
+
help="Filter by execution index (0-based).",
|
319
|
+
)
|
320
|
+
parser.add_argument(
|
321
|
+
"-s",
|
322
|
+
"--status",
|
323
|
+
choices=["all", "success", "error"],
|
324
|
+
default="all",
|
325
|
+
help="Filter by execution status (default: all).",
|
326
|
+
)
|
327
|
+
parser.add_argument(
|
328
|
+
"-c",
|
329
|
+
"--clear",
|
330
|
+
action="store_true",
|
331
|
+
help="Clear the Execution History.",
|
332
|
+
)
|
333
|
+
parser.add_argument("-r", "--result", type=int, help="Get the result by index")
|
334
|
+
parser.add_argument(
|
335
|
+
"-l", "--last-result", action="store_true", help="Get the last result"
|
336
|
+
)
|
303
337
|
return Command(
|
304
338
|
key="Y",
|
305
339
|
description="History",
|
@@ -307,6 +341,8 @@ class Falyx:
|
|
307
341
|
action=Action(name="View Execution History", action=er.summary),
|
308
342
|
style=OneColors.DARK_YELLOW,
|
309
343
|
simple_help_signature=True,
|
344
|
+
arg_parser=parser,
|
345
|
+
help_text="View the execution history of commands.",
|
310
346
|
)
|
311
347
|
|
312
348
|
async def _show_help(self, tag: str = "") -> None:
|
@@ -760,7 +796,12 @@ class Falyx:
|
|
760
796
|
def table(self) -> Table:
|
761
797
|
"""Creates or returns a custom table to display the menu commands."""
|
762
798
|
if callable(self.custom_table):
|
763
|
-
|
799
|
+
custom_table = self.custom_table(self)
|
800
|
+
if not isinstance(custom_table, Table):
|
801
|
+
raise FalyxError(
|
802
|
+
"custom_table must return an instance of rich.table.Table."
|
803
|
+
)
|
804
|
+
return custom_table
|
764
805
|
elif isinstance(self.custom_table, Table):
|
765
806
|
return self.custom_table
|
766
807
|
else:
|
@@ -798,21 +839,31 @@ class Falyx:
|
|
798
839
|
|
799
840
|
choice = choice.upper()
|
800
841
|
name_map = self._name_map
|
842
|
+
run_command = None
|
801
843
|
if name_map.get(choice):
|
844
|
+
run_command = name_map[choice]
|
845
|
+
else:
|
846
|
+
prefix_matches = [
|
847
|
+
cmd for key, cmd in name_map.items() if key.startswith(choice)
|
848
|
+
]
|
849
|
+
if len(prefix_matches) == 1:
|
850
|
+
run_command = prefix_matches[0]
|
851
|
+
|
852
|
+
if run_command:
|
802
853
|
if not from_validate:
|
803
|
-
logger.info("Command '%s' selected.",
|
854
|
+
logger.info("Command '%s' selected.", run_command.key)
|
804
855
|
if is_preview:
|
805
|
-
return True,
|
856
|
+
return True, run_command, args, kwargs
|
806
857
|
elif self.mode in {FalyxMode.RUN, FalyxMode.RUN_ALL, FalyxMode.PREVIEW}:
|
807
|
-
return False,
|
858
|
+
return False, run_command, args, kwargs
|
808
859
|
try:
|
809
|
-
args, kwargs = await
|
810
|
-
input_args, from_validate
|
811
|
-
)
|
860
|
+
args, kwargs = await run_command.parse_args(input_args, from_validate)
|
812
861
|
except (CommandArgumentError, Exception) as error:
|
813
862
|
if not from_validate:
|
814
|
-
|
815
|
-
self.console.print(
|
863
|
+
run_command.show_help()
|
864
|
+
self.console.print(
|
865
|
+
f"[{OneColors.DARK_RED}]❌ [{run_command.key}]: {error}"
|
866
|
+
)
|
816
867
|
else:
|
817
868
|
raise ValidationError(
|
818
869
|
message=str(error), cursor_position=len(raw_choices)
|
@@ -820,11 +871,7 @@ class Falyx:
|
|
820
871
|
return is_preview, None, args, kwargs
|
821
872
|
except HelpSignal:
|
822
873
|
return True, None, args, kwargs
|
823
|
-
return is_preview,
|
824
|
-
|
825
|
-
prefix_matches = [cmd for key, cmd in name_map.items() if key.startswith(choice)]
|
826
|
-
if len(prefix_matches) == 1:
|
827
|
-
return is_preview, prefix_matches[0], args, kwargs
|
874
|
+
return is_preview, run_command, args, kwargs
|
828
875
|
|
829
876
|
fuzzy_matches = get_close_matches(choice, list(name_map.keys()), n=3, cutoff=0.7)
|
830
877
|
if fuzzy_matches:
|
@@ -854,12 +901,14 @@ class Falyx:
|
|
854
901
|
)
|
855
902
|
return is_preview, None, args, kwargs
|
856
903
|
|
857
|
-
def _create_context(
|
858
|
-
|
904
|
+
def _create_context(
|
905
|
+
self, selected_command: Command, args: tuple, kwargs: dict[str, Any]
|
906
|
+
) -> ExecutionContext:
|
907
|
+
"""Creates an ExecutionContext object for the selected command."""
|
859
908
|
return ExecutionContext(
|
860
909
|
name=selected_command.description,
|
861
|
-
args=
|
862
|
-
kwargs=
|
910
|
+
args=args,
|
911
|
+
kwargs=kwargs,
|
863
912
|
action=selected_command,
|
864
913
|
)
|
865
914
|
|
@@ -893,7 +942,7 @@ class Falyx:
|
|
893
942
|
logger.info("Back selected: exiting %s", self.get_title())
|
894
943
|
return False
|
895
944
|
|
896
|
-
context = self._create_context(selected_command)
|
945
|
+
context = self._create_context(selected_command, args, kwargs)
|
897
946
|
context.start_timer()
|
898
947
|
try:
|
899
948
|
await self.hooks.trigger(HookType.BEFORE, context)
|
@@ -938,7 +987,7 @@ class Falyx:
|
|
938
987
|
selected_command.description,
|
939
988
|
)
|
940
989
|
|
941
|
-
context = self._create_context(selected_command)
|
990
|
+
context = self._create_context(selected_command, args, kwargs)
|
942
991
|
context.start_timer()
|
943
992
|
try:
|
944
993
|
await self.hooks.trigger(HookType.BEFORE, context)
|
@@ -159,7 +159,7 @@ class CommandArgumentParser:
|
|
159
159
|
aliases: list[str] | None = None,
|
160
160
|
) -> None:
|
161
161
|
"""Initialize the CommandArgumentParser."""
|
162
|
-
self.console = Console(color_system="
|
162
|
+
self.console = Console(color_system="truecolor")
|
163
163
|
self.command_key: str = command_key
|
164
164
|
self.command_description: str = command_description
|
165
165
|
self.command_style: str = command_style
|
@@ -629,7 +629,10 @@ class CommandArgumentParser:
|
|
629
629
|
consumed_positional_indicies.add(j)
|
630
630
|
|
631
631
|
if i < len(args):
|
632
|
-
|
632
|
+
plural = "s" if len(args[i:]) > 1 else ""
|
633
|
+
raise CommandArgumentError(
|
634
|
+
f"Unexpected positional argument{plural}: {', '.join(args[i:])}"
|
635
|
+
)
|
633
636
|
|
634
637
|
return i
|
635
638
|
|
@@ -273,7 +273,7 @@ async def prompt_for_index(
|
|
273
273
|
show_table: bool = True,
|
274
274
|
) -> int:
|
275
275
|
prompt_session = prompt_session or PromptSession()
|
276
|
-
console = console or Console(color_system="
|
276
|
+
console = console or Console(color_system="truecolor")
|
277
277
|
|
278
278
|
if show_table:
|
279
279
|
console.print(table, justify="center")
|
@@ -298,7 +298,7 @@ async def prompt_for_selection(
|
|
298
298
|
) -> str:
|
299
299
|
"""Prompt the user to select a key from a set of options. Return the selected key."""
|
300
300
|
prompt_session = prompt_session or PromptSession()
|
301
|
-
console = console or Console(color_system="
|
301
|
+
console = console or Console(color_system="truecolor")
|
302
302
|
|
303
303
|
if show_table:
|
304
304
|
console.print(table, justify="center")
|
@@ -351,7 +351,7 @@ async def select_value_from_list(
|
|
351
351
|
highlight=highlight,
|
352
352
|
)
|
353
353
|
prompt_session = prompt_session or PromptSession()
|
354
|
-
console = console or Console(color_system="
|
354
|
+
console = console or Console(color_system="truecolor")
|
355
355
|
|
356
356
|
selection_index = await prompt_for_index(
|
357
357
|
len(selections) - 1,
|
@@ -376,7 +376,7 @@ async def select_key_from_dict(
|
|
376
376
|
) -> Any:
|
377
377
|
"""Prompt for a key from a dict, returns the key."""
|
378
378
|
prompt_session = prompt_session or PromptSession()
|
379
|
-
console = console or Console(color_system="
|
379
|
+
console = console or Console(color_system="truecolor")
|
380
380
|
|
381
381
|
console.print(table, justify="center")
|
382
382
|
|
@@ -401,7 +401,7 @@ async def select_value_from_dict(
|
|
401
401
|
) -> Any:
|
402
402
|
"""Prompt for a key from a dict, but return the value."""
|
403
403
|
prompt_session = prompt_session or PromptSession()
|
404
|
-
console = console or Console(color_system="
|
404
|
+
console = console or Console(color_system="truecolor")
|
405
405
|
|
406
406
|
console.print(table, justify="center")
|
407
407
|
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "0.1.50"
|
falyx-0.1.48/falyx/version.py
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = "0.1.48"
|
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
|