cmdbox-cli 1.0.0__py3-none-any.whl
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.
- cmdbox/__init__.py +0 -0
- cmdbox/cli/__init__.py +0 -0
- cmdbox/cli/app.py +125 -0
- cmdbox/cli/commands/__init__.py +0 -0
- cmdbox/cli/commands/alias_fallback.py +102 -0
- cmdbox/cli/commands/command_crud.py +429 -0
- cmdbox/cli/commands/command_run.py +255 -0
- cmdbox/cli/commands/history.py +109 -0
- cmdbox/cli/commands/init.py +54 -0
- cmdbox/cli/commands/settings.py +62 -0
- cmdbox/cli/commands/tag_crud.py +277 -0
- cmdbox/cli/commands/variable_crud.py +349 -0
- cmdbox/cli/common/__init__.py +0 -0
- cmdbox/cli/common/errors.py +58 -0
- cmdbox/cli/common/update_fields.py +88 -0
- cmdbox/cli/completions/__init__.py +0 -0
- cmdbox/cli/completions/commands.py +26 -0
- cmdbox/cli/completions/fields.py +31 -0
- cmdbox/cli/completions/tags.py +24 -0
- cmdbox/cli/completions/variables.py +26 -0
- cmdbox/cli/handlers/__init__.py +0 -0
- cmdbox/cli/handlers/command_handlers.py +357 -0
- cmdbox/cli/handlers/common_handlers.py +15 -0
- cmdbox/cli/handlers/history_handlers.py +94 -0
- cmdbox/cli/handlers/init_handler.py +127 -0
- cmdbox/cli/handlers/run_handler.py +178 -0
- cmdbox/cli/handlers/settings_handler.py +59 -0
- cmdbox/cli/handlers/tag_handlers.py +220 -0
- cmdbox/cli/handlers/variable_handlers.py +272 -0
- cmdbox/cli/prompts/__init__.py +0 -0
- cmdbox/cli/prompts/completers.py +161 -0
- cmdbox/cli/prompts/prompts.py +108 -0
- cmdbox/cli/prompts/validators.py +46 -0
- cmdbox/cli/ui/__init__.py +0 -0
- cmdbox/cli/ui/console.py +31 -0
- cmdbox/cli/ui/editor.py +141 -0
- cmdbox/cli/ui/presenters/__init__.py +0 -0
- cmdbox/cli/ui/presenters/app_presenter.py +8 -0
- cmdbox/cli/ui/presenters/command_presenter.py +168 -0
- cmdbox/cli/ui/presenters/history_presenter.py +83 -0
- cmdbox/cli/ui/presenters/init_instructions.py +52 -0
- cmdbox/cli/ui/presenters/init_presenter.py +57 -0
- cmdbox/cli/ui/presenters/result_presenter.py +144 -0
- cmdbox/cli/ui/presenters/settings_presenter.py +130 -0
- cmdbox/cli/ui/presenters/tag_presenter.py +97 -0
- cmdbox/cli/ui/presenters/variable_presenter.py +103 -0
- cmdbox/cli/ui/primitives.py +410 -0
- cmdbox/cli/ui/theme.py +43 -0
- cmdbox/cli/ui/theme_builder.py +49 -0
- cmdbox/common/__init__.py +0 -0
- cmdbox/common/io.py +34 -0
- cmdbox/container.py +156 -0
- cmdbox/core/__init__.py +0 -0
- cmdbox/core/fields.py +48 -0
- cmdbox/core/paths.py +52 -0
- cmdbox/database.py +65 -0
- cmdbox/exceptions.py +10 -0
- cmdbox/init/__init__.py +0 -0
- cmdbox/init/detect.py +82 -0
- cmdbox/init/integrations/bash.sh +10 -0
- cmdbox/init/integrations/cmd.bat +14 -0
- cmdbox/init/integrations/fish.fish +11 -0
- cmdbox/init/integrations/powershell.ps1 +14 -0
- cmdbox/init/integrations/zsh.sh +10 -0
- cmdbox/init/io.py +68 -0
- cmdbox/init/specs.py +54 -0
- cmdbox/logging_setup/__init__.py +0 -0
- cmdbox/logging_setup/log_config.py +123 -0
- cmdbox/logging_setup/log_decorators.py +40 -0
- cmdbox/logging_setup/log_handlers.py +94 -0
- cmdbox/migrations/__init__.py +1 -0
- cmdbox/migrations/errors.py +10 -0
- cmdbox/migrations/runner.py +127 -0
- cmdbox/migrations/versions/__init__.py +0 -0
- cmdbox/models.py +165 -0
- cmdbox/repositories/__init__.py +0 -0
- cmdbox/repositories/base_repository.py +181 -0
- cmdbox/repositories/command_repository.py +391 -0
- cmdbox/repositories/errors.py +120 -0
- cmdbox/repositories/history_repository.py +155 -0
- cmdbox/repositories/results.py +37 -0
- cmdbox/repositories/tag_repository.py +91 -0
- cmdbox/repositories/validators.py +256 -0
- cmdbox/repositories/variable_repository.py +324 -0
- cmdbox/resolve/__init__.py +0 -0
- cmdbox/resolve/errors.py +65 -0
- cmdbox/resolve/lookup.py +137 -0
- cmdbox/resolve/resolver.py +402 -0
- cmdbox/resolve/type_defs.py +96 -0
- cmdbox/runtime/__init__.py +0 -0
- cmdbox/runtime/executor.py +454 -0
- cmdbox/runtime/results.py +25 -0
- cmdbox/runtime/shell.py +90 -0
- cmdbox/services/__init__.py +0 -0
- cmdbox/services/command_services.py +261 -0
- cmdbox/services/errors.py +37 -0
- cmdbox/services/field_selection.py +162 -0
- cmdbox/services/history_service.py +68 -0
- cmdbox/services/run_service.py +204 -0
- cmdbox/services/tag_services.py +134 -0
- cmdbox/services/variable_services.py +224 -0
- cmdbox/settings/__init__.py +0 -0
- cmdbox/settings/models.py +129 -0
- cmdbox/settings/settings_repository.py +36 -0
- cmdbox/settings/settings_service.py +144 -0
- cmdbox/version.py +1 -0
- cmdbox_cli-1.0.0.dist-info/METADATA +125 -0
- cmdbox_cli-1.0.0.dist-info/RECORD +112 -0
- cmdbox_cli-1.0.0.dist-info/WHEEL +5 -0
- cmdbox_cli-1.0.0.dist-info/entry_points.txt +2 -0
- cmdbox_cli-1.0.0.dist-info/licenses/LICENSE +21 -0
- cmdbox_cli-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Annotated
|
|
3
|
+
|
|
4
|
+
import typer
|
|
5
|
+
|
|
6
|
+
from cmdbox import container
|
|
7
|
+
from cmdbox.cli.common.errors import make_cli_guard
|
|
8
|
+
from cmdbox.cli.completions.fields import tag_editable_field_options, tag_field_options
|
|
9
|
+
from cmdbox.cli.completions.tags import complete_tag_names
|
|
10
|
+
from cmdbox.cli.handlers import tag_handlers
|
|
11
|
+
|
|
12
|
+
app = typer.Typer(no_args_is_help=True)
|
|
13
|
+
|
|
14
|
+
cli_guard = make_cli_guard(container.get_console)
|
|
15
|
+
|
|
16
|
+
log = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@app.command("add")
|
|
20
|
+
@cli_guard
|
|
21
|
+
def add(
|
|
22
|
+
name: Annotated[
|
|
23
|
+
str,
|
|
24
|
+
typer.Argument(help="The name of the tag.", autocompletion=complete_tag_names),
|
|
25
|
+
] = None,
|
|
26
|
+
description: Annotated[
|
|
27
|
+
str, typer.Argument(help="A description of the tag.")
|
|
28
|
+
] = None,
|
|
29
|
+
interactive: Annotated[
|
|
30
|
+
bool,
|
|
31
|
+
typer.Option(
|
|
32
|
+
"--interactive",
|
|
33
|
+
"-i",
|
|
34
|
+
is_flag=True,
|
|
35
|
+
help="Prompt for tag details interactively.",
|
|
36
|
+
),
|
|
37
|
+
] = False,
|
|
38
|
+
) -> None:
|
|
39
|
+
"""
|
|
40
|
+
Adds a new tag with a name and description. The tag can be created in
|
|
41
|
+
interactive if no options are provided or the `--interactive` flag is
|
|
42
|
+
used.
|
|
43
|
+
"""
|
|
44
|
+
log.debug(
|
|
45
|
+
"tag.add called. name=%s, description=%s, interactive=%s",
|
|
46
|
+
name,
|
|
47
|
+
description,
|
|
48
|
+
interactive,
|
|
49
|
+
)
|
|
50
|
+
add_tag_args = tag_handlers.AddTagArgs(
|
|
51
|
+
name=name, description=description, interactive=interactive
|
|
52
|
+
)
|
|
53
|
+
tag_handlers.run_add_tag(
|
|
54
|
+
args=add_tag_args,
|
|
55
|
+
get_tag_services=container.get_tag_services,
|
|
56
|
+
get_console=container.get_console,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@app.command("get")
|
|
61
|
+
@cli_guard
|
|
62
|
+
def get(
|
|
63
|
+
name: Annotated[
|
|
64
|
+
str,
|
|
65
|
+
typer.Argument(
|
|
66
|
+
help="The name of the tag to retrieve.", autocompletion=complete_tag_names
|
|
67
|
+
),
|
|
68
|
+
],
|
|
69
|
+
) -> None:
|
|
70
|
+
"""
|
|
71
|
+
Gets and displays a saved tag under the provided name.
|
|
72
|
+
"""
|
|
73
|
+
log.debug("tag.get called. name=%s", name)
|
|
74
|
+
tag_handlers.run_get_tag(
|
|
75
|
+
name=name,
|
|
76
|
+
get_tag_services=container.get_tag_services,
|
|
77
|
+
get_console=container.get_console,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@app.command("update")
|
|
82
|
+
@cli_guard
|
|
83
|
+
def update(
|
|
84
|
+
name: Annotated[
|
|
85
|
+
str,
|
|
86
|
+
typer.Argument(
|
|
87
|
+
help="The name of the tag to update.", autocompletion=complete_tag_names
|
|
88
|
+
),
|
|
89
|
+
],
|
|
90
|
+
description: Annotated[
|
|
91
|
+
str,
|
|
92
|
+
typer.Option("--description", "-d", help="The new description of the tag."),
|
|
93
|
+
] = None,
|
|
94
|
+
new_name: Annotated[
|
|
95
|
+
str,
|
|
96
|
+
typer.Option("--name", "-n", help="The new name of the tag."),
|
|
97
|
+
] = None,
|
|
98
|
+
set_: Annotated[
|
|
99
|
+
list[str],
|
|
100
|
+
typer.Option(
|
|
101
|
+
"--set",
|
|
102
|
+
"-s",
|
|
103
|
+
help="A list of key=value pairs to update.",
|
|
104
|
+
autocompletion=tag_editable_field_options,
|
|
105
|
+
),
|
|
106
|
+
] = None,
|
|
107
|
+
edit_mode: Annotated[
|
|
108
|
+
bool,
|
|
109
|
+
typer.Option("--edit", "-e", help="Edit mode."),
|
|
110
|
+
] = False,
|
|
111
|
+
edit_fields: Annotated[
|
|
112
|
+
str,
|
|
113
|
+
typer.Option(
|
|
114
|
+
"--edit-fields",
|
|
115
|
+
"-ef",
|
|
116
|
+
help="A list of fields to be edited in edit mode, separated by commas. Defaults to all fields.",
|
|
117
|
+
),
|
|
118
|
+
] = None,
|
|
119
|
+
) -> None:
|
|
120
|
+
"""
|
|
121
|
+
Updates an existing tag with the provided options. Each field can be updated
|
|
122
|
+
individually or in bulk using the `--set` option. Using the `--edit` option enables
|
|
123
|
+
editing the already stored values in an interactive mode.
|
|
124
|
+
"""
|
|
125
|
+
log.debug(
|
|
126
|
+
"tag.update called. name=%s, description=%s, new_name=%s, set_pairs=%s, edit_mode=%s, edit_fields=%s",
|
|
127
|
+
name,
|
|
128
|
+
description,
|
|
129
|
+
new_name,
|
|
130
|
+
set_,
|
|
131
|
+
edit_mode,
|
|
132
|
+
edit_fields,
|
|
133
|
+
)
|
|
134
|
+
tag_handlers.run_update_tag(
|
|
135
|
+
name=name,
|
|
136
|
+
description=description,
|
|
137
|
+
new_name=new_name,
|
|
138
|
+
set_pairs=set_,
|
|
139
|
+
edit_mode=edit_mode,
|
|
140
|
+
edit_fields=edit_fields,
|
|
141
|
+
get_tag_services=container.get_tag_services,
|
|
142
|
+
get_settings=container.get_settings,
|
|
143
|
+
get_console=container.get_console,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
app.command("edit", hidden=True)(update)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@app.command("list")
|
|
151
|
+
@cli_guard
|
|
152
|
+
def list_tags(
|
|
153
|
+
order: Annotated[
|
|
154
|
+
str,
|
|
155
|
+
typer.Option(
|
|
156
|
+
"--order",
|
|
157
|
+
"-o",
|
|
158
|
+
help="The field to order the results by.",
|
|
159
|
+
autocompletion=tag_field_options,
|
|
160
|
+
),
|
|
161
|
+
] = "name",
|
|
162
|
+
limit: Annotated[
|
|
163
|
+
int,
|
|
164
|
+
typer.Option("--limit", "-l", help="The maximum number of results to return."),
|
|
165
|
+
] = 10,
|
|
166
|
+
fields: Annotated[
|
|
167
|
+
list[str] | None,
|
|
168
|
+
typer.Option(
|
|
169
|
+
"--field",
|
|
170
|
+
"-f",
|
|
171
|
+
help="The fields to display in the results list.",
|
|
172
|
+
autocompletion=tag_field_options,
|
|
173
|
+
),
|
|
174
|
+
] = None,
|
|
175
|
+
) -> None:
|
|
176
|
+
"""
|
|
177
|
+
Displays all stored tags in a list format. The number of results can be limited
|
|
178
|
+
with the `--limit` option. The output fields can be customized with the `--field` option.
|
|
179
|
+
"""
|
|
180
|
+
log.debug("tag.list called. order=%s, limit=%s, fields=%s", order, limit, fields)
|
|
181
|
+
tag_handlers.run_list_tags(
|
|
182
|
+
limit=limit,
|
|
183
|
+
fields=fields,
|
|
184
|
+
order_by=order,
|
|
185
|
+
get_tag_services=container.get_tag_services,
|
|
186
|
+
get_settings=container.get_settings,
|
|
187
|
+
get_console=container.get_console,
|
|
188
|
+
get_display_field_resolver=container.get_tag_display_field_resolver,
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
app.command("ls", hidden=True)(list_tags)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@app.command("search")
|
|
196
|
+
@cli_guard
|
|
197
|
+
def search(
|
|
198
|
+
term: Annotated[
|
|
199
|
+
str,
|
|
200
|
+
typer.Argument(
|
|
201
|
+
help="The search term to use.", autocompletion=complete_tag_names
|
|
202
|
+
),
|
|
203
|
+
],
|
|
204
|
+
limit: Annotated[
|
|
205
|
+
int, typer.Option(help="The maximum number of results to return.")
|
|
206
|
+
] = 10,
|
|
207
|
+
search_fields: Annotated[
|
|
208
|
+
list[str],
|
|
209
|
+
typer.Option(
|
|
210
|
+
"--in",
|
|
211
|
+
"-i",
|
|
212
|
+
help="The fields to search within.",
|
|
213
|
+
autocompletion=tag_field_options,
|
|
214
|
+
),
|
|
215
|
+
] = None,
|
|
216
|
+
fields: Annotated[
|
|
217
|
+
list[str] | None,
|
|
218
|
+
typer.Option(
|
|
219
|
+
"--field",
|
|
220
|
+
"-f",
|
|
221
|
+
help="The field(s) to display in the results list. Defaults to all fields.",
|
|
222
|
+
autocompletion=tag_field_options,
|
|
223
|
+
),
|
|
224
|
+
] = None,
|
|
225
|
+
) -> None:
|
|
226
|
+
"""
|
|
227
|
+
Searches the database for tags matching the provided search term. The search fields
|
|
228
|
+
can be customized with the `--in` option. The output fields can be customized with the
|
|
229
|
+
`--field` option.
|
|
230
|
+
"""
|
|
231
|
+
log.debug(
|
|
232
|
+
"tag.search called. term=%s, limit=%s, search_fields=%s, fields=%s",
|
|
233
|
+
term,
|
|
234
|
+
limit,
|
|
235
|
+
search_fields,
|
|
236
|
+
fields,
|
|
237
|
+
)
|
|
238
|
+
tag_handlers.run_search_tags(
|
|
239
|
+
term=term,
|
|
240
|
+
limit=limit,
|
|
241
|
+
search_fields=search_fields,
|
|
242
|
+
fields=fields,
|
|
243
|
+
get_tag_services=container.get_tag_services,
|
|
244
|
+
get_settings=container.get_settings,
|
|
245
|
+
get_console=container.get_console,
|
|
246
|
+
get_display_field_resolver=container.get_tag_display_field_resolver,
|
|
247
|
+
get_search_field_resolver=container.get_tag_search_field_resolver,
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
app.command("find", hidden=True)(search)
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
@app.command("delete")
|
|
255
|
+
@cli_guard
|
|
256
|
+
def delete(
|
|
257
|
+
name: Annotated[
|
|
258
|
+
str,
|
|
259
|
+
typer.Argument(
|
|
260
|
+
help="The name of the tag to delete.", autocompletion=complete_tag_names
|
|
261
|
+
),
|
|
262
|
+
],
|
|
263
|
+
) -> None:
|
|
264
|
+
"""
|
|
265
|
+
Deletes the tag stored under the provided name.
|
|
266
|
+
"""
|
|
267
|
+
log.debug("tag.delete called. name=%s", name)
|
|
268
|
+
tag_handlers.run_delete_tag(
|
|
269
|
+
name=name,
|
|
270
|
+
get_tag_services=container.get_tag_services,
|
|
271
|
+
get_console=container.get_console,
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
app.command("del", hidden=True)(delete)
|
|
276
|
+
app.command("rm", hidden=True)(delete)
|
|
277
|
+
app.command("remove", hidden=True)(delete)
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Annotated
|
|
3
|
+
|
|
4
|
+
import typer
|
|
5
|
+
|
|
6
|
+
from cmdbox import container
|
|
7
|
+
from cmdbox.cli.common.errors import make_cli_guard
|
|
8
|
+
from cmdbox.cli.completions.fields import variable_field_options
|
|
9
|
+
from cmdbox.cli.completions.variables import complete_variable_names
|
|
10
|
+
from cmdbox.cli.completions.tags import complete_tag_names
|
|
11
|
+
from cmdbox.cli.handlers import variable_handlers
|
|
12
|
+
|
|
13
|
+
app = typer.Typer(no_args_is_help=True)
|
|
14
|
+
|
|
15
|
+
cli_guard = make_cli_guard(container.get_console)
|
|
16
|
+
|
|
17
|
+
log = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@app.command("add")
|
|
21
|
+
@cli_guard
|
|
22
|
+
def add(
|
|
23
|
+
name: Annotated[str, typer.Argument(help="The name of the variable.")] = None,
|
|
24
|
+
value: Annotated[str, typer.Argument(help="The value of the variable.")] = None,
|
|
25
|
+
tags: Annotated[
|
|
26
|
+
list[str],
|
|
27
|
+
typer.Option(
|
|
28
|
+
"--tags",
|
|
29
|
+
"-t",
|
|
30
|
+
help="A list of tags to associate with the variable, separated by commas.",
|
|
31
|
+
autocompletion=complete_tag_names,
|
|
32
|
+
),
|
|
33
|
+
] = None,
|
|
34
|
+
interactive: Annotated[
|
|
35
|
+
bool,
|
|
36
|
+
typer.Option("--interactive", "-i", is_flag=True, help="Interactive mode."),
|
|
37
|
+
] = False,
|
|
38
|
+
) -> None:
|
|
39
|
+
"""
|
|
40
|
+
Adds a new variable with the specified name, value, and tags. The variable
|
|
41
|
+
can be created in interactive mode if no options are provided or the `--interactive`
|
|
42
|
+
flag is used.
|
|
43
|
+
"""
|
|
44
|
+
log.debug(
|
|
45
|
+
"var.add called. name=%s, value=%s, tags=%s, interactive=%s",
|
|
46
|
+
name,
|
|
47
|
+
value,
|
|
48
|
+
tags,
|
|
49
|
+
interactive,
|
|
50
|
+
)
|
|
51
|
+
add_var_args = variable_handlers.AddVariableArgs(
|
|
52
|
+
name=name, value=value, tags=tags, interactive=interactive
|
|
53
|
+
)
|
|
54
|
+
variable_handlers.run_add_variable(
|
|
55
|
+
args=add_var_args,
|
|
56
|
+
get_var_services=container.get_variable_services,
|
|
57
|
+
get_tag_services=container.get_tag_services,
|
|
58
|
+
get_console=container.get_console,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@app.command("get")
|
|
63
|
+
@cli_guard
|
|
64
|
+
def get(
|
|
65
|
+
name: Annotated[
|
|
66
|
+
str,
|
|
67
|
+
typer.Argument(
|
|
68
|
+
help="The name of the variable to retrieve.",
|
|
69
|
+
autocompletion=complete_variable_names,
|
|
70
|
+
),
|
|
71
|
+
],
|
|
72
|
+
) -> None:
|
|
73
|
+
"""
|
|
74
|
+
Retrieves and displays the variable stored under the provided name.
|
|
75
|
+
"""
|
|
76
|
+
log.debug("var.get called. name=%s", name)
|
|
77
|
+
variable_handlers.run_get_variable(
|
|
78
|
+
name=name,
|
|
79
|
+
get_var_services=container.get_variable_services,
|
|
80
|
+
get_console=container.get_console,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@app.command("update")
|
|
85
|
+
@cli_guard
|
|
86
|
+
def update(
|
|
87
|
+
name: Annotated[
|
|
88
|
+
str,
|
|
89
|
+
typer.Argument(
|
|
90
|
+
help="The name of the variable to update.",
|
|
91
|
+
autocompletion=complete_variable_names,
|
|
92
|
+
),
|
|
93
|
+
],
|
|
94
|
+
value: Annotated[str, typer.Option("--value", "-v", help="The new value.")] = None,
|
|
95
|
+
new_name: Annotated[str, typer.Option("--name", "-n", help="The new name.")] = None,
|
|
96
|
+
set_: Annotated[
|
|
97
|
+
list[str],
|
|
98
|
+
typer.Option(
|
|
99
|
+
"--set",
|
|
100
|
+
"-s",
|
|
101
|
+
help="A list of key=value pairs to update.",
|
|
102
|
+
autocompletion=variable_field_options,
|
|
103
|
+
),
|
|
104
|
+
] = None,
|
|
105
|
+
edit_mode: Annotated[
|
|
106
|
+
bool,
|
|
107
|
+
typer.Option("--edit", "-e", help="Edit mode."),
|
|
108
|
+
] = False,
|
|
109
|
+
edit_fields: Annotated[
|
|
110
|
+
str,
|
|
111
|
+
typer.Option(
|
|
112
|
+
"--edit-fields",
|
|
113
|
+
"-ef",
|
|
114
|
+
help="A list of fields to be edited in edit mode, separated by commas. Defaults to all fields.",
|
|
115
|
+
),
|
|
116
|
+
] = None,
|
|
117
|
+
) -> None:
|
|
118
|
+
"""
|
|
119
|
+
Updates an existing variable with the provided options. Each field can be updated
|
|
120
|
+
individually or in bulk using the `--set` option. Using the `--edit` option enables
|
|
121
|
+
editing the already stored values in an interactive mode.
|
|
122
|
+
"""
|
|
123
|
+
log.debug(
|
|
124
|
+
"var.update called. name=%s, value=%s, new_name=%s, set_pairs=%s, edit_mode=%s, edit_fields=%s",
|
|
125
|
+
name,
|
|
126
|
+
value,
|
|
127
|
+
new_name,
|
|
128
|
+
set_,
|
|
129
|
+
edit_mode,
|
|
130
|
+
edit_fields,
|
|
131
|
+
)
|
|
132
|
+
variable_handlers.run_update_variable(
|
|
133
|
+
name=name,
|
|
134
|
+
value=value,
|
|
135
|
+
new_name=new_name,
|
|
136
|
+
set_pairs=set_,
|
|
137
|
+
edit_mode=edit_mode,
|
|
138
|
+
edit_fields=edit_fields,
|
|
139
|
+
get_var_services=container.get_variable_services,
|
|
140
|
+
get_settings=container.get_settings,
|
|
141
|
+
get_console=container.get_console,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
app.command("edit", hidden=True)(update)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@app.command("list")
|
|
149
|
+
@cli_guard
|
|
150
|
+
def list_vars(
|
|
151
|
+
order: Annotated[
|
|
152
|
+
str,
|
|
153
|
+
typer.Option(
|
|
154
|
+
"--order",
|
|
155
|
+
"-o",
|
|
156
|
+
help="The field to order the results by.",
|
|
157
|
+
autocompletion=variable_field_options,
|
|
158
|
+
),
|
|
159
|
+
] = "name",
|
|
160
|
+
tags: Annotated[
|
|
161
|
+
list[str],
|
|
162
|
+
typer.Option(
|
|
163
|
+
"--tag",
|
|
164
|
+
"-t",
|
|
165
|
+
help="The tags to filter by.",
|
|
166
|
+
autocompletion=complete_tag_names,
|
|
167
|
+
),
|
|
168
|
+
] = None,
|
|
169
|
+
limit: Annotated[
|
|
170
|
+
int,
|
|
171
|
+
typer.Option("--limit", "-l", help="The maximum number of results to return."),
|
|
172
|
+
] = 10,
|
|
173
|
+
fields: Annotated[
|
|
174
|
+
list[str] | None,
|
|
175
|
+
typer.Option(
|
|
176
|
+
"--field",
|
|
177
|
+
"-f",
|
|
178
|
+
help="The fields to display in the results list.",
|
|
179
|
+
autocompletion=variable_field_options,
|
|
180
|
+
),
|
|
181
|
+
] = None,
|
|
182
|
+
) -> None:
|
|
183
|
+
"""
|
|
184
|
+
Displays all stored variables in a list format. The number of results can be limited
|
|
185
|
+
with the `--limit` option. The output fields can be customized with the `--field` option.
|
|
186
|
+
"""
|
|
187
|
+
log.debug(
|
|
188
|
+
"var.list called. order=%s, tags=%s, limit=%s, fields=%s",
|
|
189
|
+
order,
|
|
190
|
+
tags,
|
|
191
|
+
limit,
|
|
192
|
+
fields,
|
|
193
|
+
)
|
|
194
|
+
variable_handlers.run_list_variables(
|
|
195
|
+
order_by=order,
|
|
196
|
+
tags=tags,
|
|
197
|
+
limit=limit,
|
|
198
|
+
fields=fields,
|
|
199
|
+
get_var_services=container.get_variable_services,
|
|
200
|
+
get_settings=container.get_settings,
|
|
201
|
+
get_console=container.get_console,
|
|
202
|
+
get_display_field_resolver=container.get_variable_display_field_resolver,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
app.command("ls", hidden=True)(list_vars)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
@app.command("search")
|
|
210
|
+
@cli_guard
|
|
211
|
+
def search(
|
|
212
|
+
term: Annotated[str, typer.Argument(help="The search term to use.")],
|
|
213
|
+
limit: Annotated[
|
|
214
|
+
int, typer.Option(help="The maximum number of results to return.")
|
|
215
|
+
] = 10,
|
|
216
|
+
search_fields: Annotated[
|
|
217
|
+
list[str],
|
|
218
|
+
typer.Option(
|
|
219
|
+
"--in",
|
|
220
|
+
"-i",
|
|
221
|
+
help="The fields to search within.",
|
|
222
|
+
autocompletion=variable_field_options,
|
|
223
|
+
),
|
|
224
|
+
] = None,
|
|
225
|
+
fields: Annotated[
|
|
226
|
+
list[str] | None,
|
|
227
|
+
typer.Option(
|
|
228
|
+
"--field",
|
|
229
|
+
"-f",
|
|
230
|
+
help="The field(s) to display in the results list. Defaults to all fields.",
|
|
231
|
+
autocompletion=variable_field_options,
|
|
232
|
+
),
|
|
233
|
+
] = None,
|
|
234
|
+
) -> None:
|
|
235
|
+
"""
|
|
236
|
+
Searches the database for variables matching the provided search term. The search fields
|
|
237
|
+
can be customized with the `--in` option. The output fields can be customized with the
|
|
238
|
+
`--field` option.
|
|
239
|
+
"""
|
|
240
|
+
log.debug(
|
|
241
|
+
"var.search called. term=%s, limit=%s, search_fields=%s, fields=%s",
|
|
242
|
+
term,
|
|
243
|
+
limit,
|
|
244
|
+
search_fields,
|
|
245
|
+
fields,
|
|
246
|
+
)
|
|
247
|
+
variable_handlers.run_search_variables(
|
|
248
|
+
term=term,
|
|
249
|
+
limit=limit,
|
|
250
|
+
search_fields=search_fields,
|
|
251
|
+
fields=fields,
|
|
252
|
+
get_var_services=container.get_variable_services,
|
|
253
|
+
get_settings=container.get_settings,
|
|
254
|
+
get_console=container.get_console,
|
|
255
|
+
get_display_field_resolver=container.get_variable_display_field_resolver,
|
|
256
|
+
get_search_field_resolver=container.get_variable_search_field_resolver,
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
app.command("find", hidden=True)(search)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
@app.command("delete")
|
|
264
|
+
@cli_guard
|
|
265
|
+
def delete(
|
|
266
|
+
name: Annotated[
|
|
267
|
+
str,
|
|
268
|
+
typer.Argument(
|
|
269
|
+
help="The name of the variable to delete.",
|
|
270
|
+
autocompletion=complete_variable_names,
|
|
271
|
+
),
|
|
272
|
+
],
|
|
273
|
+
) -> None:
|
|
274
|
+
"""
|
|
275
|
+
Deletes the variable stored under the provided name.
|
|
276
|
+
"""
|
|
277
|
+
log.debug("var.delete called. name=%s", name)
|
|
278
|
+
variable_handlers.run_delete_variable(
|
|
279
|
+
name=name,
|
|
280
|
+
get_var_services=container.get_variable_services,
|
|
281
|
+
get_console=container.get_console,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
app.command("del", hidden=True)(delete)
|
|
286
|
+
app.command("rm", hidden=True)(delete)
|
|
287
|
+
app.command("remove", hidden=True)(delete)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
@app.command("tag")
|
|
291
|
+
@cli_guard
|
|
292
|
+
def add_tags(
|
|
293
|
+
name: Annotated[
|
|
294
|
+
str,
|
|
295
|
+
typer.Argument(
|
|
296
|
+
help="The name of the command to tag.",
|
|
297
|
+
autocompletion=complete_variable_names,
|
|
298
|
+
),
|
|
299
|
+
],
|
|
300
|
+
tags: Annotated[
|
|
301
|
+
list[str],
|
|
302
|
+
typer.Argument(
|
|
303
|
+
help="The tags to add to the command.", autocompletion=complete_tag_names
|
|
304
|
+
),
|
|
305
|
+
] = None,
|
|
306
|
+
) -> None:
|
|
307
|
+
"""
|
|
308
|
+
Adds the provided tags to the command stored under the provided alias. Tags must
|
|
309
|
+
be existing.
|
|
310
|
+
"""
|
|
311
|
+
log.debug("var.tag.add called. name=%s, tags=%s", name, tags)
|
|
312
|
+
variable_handlers.run_attach_tags(
|
|
313
|
+
name=name,
|
|
314
|
+
tag_names=tags,
|
|
315
|
+
get_var_services=container.get_variable_services,
|
|
316
|
+
get_tag_services=container.get_tag_services,
|
|
317
|
+
get_console=container.get_console,
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
@app.command("untag")
|
|
322
|
+
@cli_guard
|
|
323
|
+
def remove_tags(
|
|
324
|
+
name: Annotated[
|
|
325
|
+
str,
|
|
326
|
+
typer.Argument(
|
|
327
|
+
help="The name of the command to untag.",
|
|
328
|
+
autocompletion=complete_variable_names,
|
|
329
|
+
),
|
|
330
|
+
],
|
|
331
|
+
tags: Annotated[
|
|
332
|
+
list[str],
|
|
333
|
+
typer.Argument(
|
|
334
|
+
help="The tags to remove from the command.",
|
|
335
|
+
autocompletion=complete_tag_names,
|
|
336
|
+
),
|
|
337
|
+
] = None,
|
|
338
|
+
) -> None:
|
|
339
|
+
"""
|
|
340
|
+
Removes the provided tags from the command stored under the provided alias.
|
|
341
|
+
"""
|
|
342
|
+
log.debug("var.tag.remove called. name=%s, tags=%s", name, tags)
|
|
343
|
+
variable_handlers.run_detach_tags(
|
|
344
|
+
name=name,
|
|
345
|
+
tag_names=tags,
|
|
346
|
+
get_var_services=container.get_variable_services,
|
|
347
|
+
get_tag_services=container.get_tag_services,
|
|
348
|
+
get_console=container.get_console,
|
|
349
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from functools import wraps
|
|
3
|
+
from typing import Callable
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from cmdbox.cli.ui.console import ConsoleUI
|
|
8
|
+
from cmdbox.exceptions import CmdboxError
|
|
9
|
+
|
|
10
|
+
log = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def make_cli_guard(
|
|
14
|
+
get_console: Callable[[], ConsoleUI],
|
|
15
|
+
) -> Callable[[Callable], Callable]:
|
|
16
|
+
"""
|
|
17
|
+
Creates a decorator to handle exceptions in CLI commands and provide uniform error
|
|
18
|
+
handling and messaging via a ConsoleUI instance.
|
|
19
|
+
|
|
20
|
+
The decorator wraps any given function, intercepting exceptions raised during its execution.
|
|
21
|
+
If an unexpected exception occurs, it is logged using the ConsoleUI's error handler,
|
|
22
|
+
and the program exits with a specific error code.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
get_console: Callable that returns a `ConsoleUI` instance. Used to handle error
|
|
26
|
+
messages and output them in a consistent manner during CLI execution.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Callable: A decorator function that processes the given function, wrapping it with
|
|
30
|
+
exception handling and error reporting logic.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def cli_guard(fn):
|
|
34
|
+
@wraps(fn)
|
|
35
|
+
def wrapper(*args, **kwargs):
|
|
36
|
+
try:
|
|
37
|
+
return fn(*args, **kwargs)
|
|
38
|
+
except typer.BadParameter:
|
|
39
|
+
log.error("Invalid parameter(s) provided.")
|
|
40
|
+
raise
|
|
41
|
+
except typer.Exit:
|
|
42
|
+
log.debug("Exiting CLI. Typer exit raised.")
|
|
43
|
+
raise
|
|
44
|
+
except CmdboxError as exc:
|
|
45
|
+
log.error(exc)
|
|
46
|
+
console = get_console()
|
|
47
|
+
console.error(str(exc))
|
|
48
|
+
raise typer.Exit(code=1)
|
|
49
|
+
except Exception as exc:
|
|
50
|
+
message = f"An unexpected error occurred: {exc}"
|
|
51
|
+
log.critical(message, exc_info=True)
|
|
52
|
+
console = get_console()
|
|
53
|
+
console.error(message)
|
|
54
|
+
raise typer.Exit(code=1)
|
|
55
|
+
|
|
56
|
+
return wrapper
|
|
57
|
+
|
|
58
|
+
return cli_guard
|