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,130 @@
|
|
|
1
|
+
from dataclasses import asdict
|
|
2
|
+
|
|
3
|
+
from cmdbox.cli.ui.primitives import stack, kv_table, section
|
|
4
|
+
from cmdbox.settings.models import Settings
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def render_settings_show(settings: Settings, fields: list[str] | None = None):
|
|
8
|
+
"""
|
|
9
|
+
Renders the settings to display either fully or partially, based on the input.
|
|
10
|
+
|
|
11
|
+
This function takes in a settings object and an optional list of fields. If the
|
|
12
|
+
fields list is provided, only the specified fields from the settings object
|
|
13
|
+
will be rendered. Otherwise, the entire settings object will be rendered.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
settings (Settings): The settings object to be rendered.
|
|
17
|
+
fields (list[str] | None): An optional list of field names to render. If
|
|
18
|
+
None, the full settings object is rendered.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
str: The rendered representation of the settings.
|
|
22
|
+
"""
|
|
23
|
+
if fields is None:
|
|
24
|
+
return render_full_settings(settings)
|
|
25
|
+
else:
|
|
26
|
+
return render_settings_fields(settings, fields)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def render_full_settings(settings: Settings):
|
|
30
|
+
"""
|
|
31
|
+
Renders the full configuration settings into a styled section format.
|
|
32
|
+
|
|
33
|
+
This function iterates through the provided settings object, extracts sections
|
|
34
|
+
and their respective values, and organizes them into a structured visual
|
|
35
|
+
presentation. Each section is assigned a styled border to enhance readability.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
settings (Settings): The settings object containing configuration data,
|
|
39
|
+
structured as key-value pairs.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
Section: A styled section containing all rendered sub-sections representing
|
|
43
|
+
the settings in a visually organized format.
|
|
44
|
+
"""
|
|
45
|
+
ret = []
|
|
46
|
+
for _section, values in asdict(settings).items():
|
|
47
|
+
ret.append(
|
|
48
|
+
section(
|
|
49
|
+
title=_section, body=render_section(values), border_style="status.info"
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
return section(title="Settings", body=stack(*ret), border_style="status.info")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def render_section(_section: dict):
|
|
56
|
+
"""
|
|
57
|
+
Renders a nested dictionary structure into a visual representation using specific rendering functions.
|
|
58
|
+
|
|
59
|
+
This function processes a nested dictionary and generates a rendered output. It recursively handles
|
|
60
|
+
dictionaries as nested sections and renders key-value pairs as a table. Special handling is provided
|
|
61
|
+
for dictionary items with the key 'alias_mapping'.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
_section (dict): The nested dictionary structure to be rendered.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
Any: The final rendered output based on the processed structure.
|
|
68
|
+
"""
|
|
69
|
+
ret = []
|
|
70
|
+
for key, value in _section.items():
|
|
71
|
+
if isinstance(value, dict):
|
|
72
|
+
sub = render_section(value)
|
|
73
|
+
if key == "alias_mapping":
|
|
74
|
+
body = sub
|
|
75
|
+
else:
|
|
76
|
+
body = section(title=key, body=sub)
|
|
77
|
+
else:
|
|
78
|
+
body = kv_table(rows=[(key, value)])
|
|
79
|
+
ret.append(body)
|
|
80
|
+
return stack(*ret)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def render_settings_fields(settings: Settings, fields: list[str]):
|
|
84
|
+
"""
|
|
85
|
+
Renders the settings fields as a formatted table.
|
|
86
|
+
|
|
87
|
+
This function takes settings and a list of field names, extracts the relevant
|
|
88
|
+
fields from the settings object, and displays them as rows in a table. The
|
|
89
|
+
output is a styled section containing the table.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
settings (Settings): An object containing configuration settings, structured
|
|
93
|
+
as fields and their respective values.
|
|
94
|
+
fields (list[str]): A list of field names to extract and display from the
|
|
95
|
+
settings object.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
str: A styled section containing a table representation of the settings
|
|
99
|
+
fields.
|
|
100
|
+
"""
|
|
101
|
+
display_fields = []
|
|
102
|
+
for key, value in asdict(settings).items():
|
|
103
|
+
display_fields.extend(parse_settings_fields(value, fields))
|
|
104
|
+
table = kv_table(rows=display_fields)
|
|
105
|
+
return section(title="Settings", body=table, border_style="status.info")
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def parse_settings_fields(_section: dict, fields: list[str]):
|
|
109
|
+
"""
|
|
110
|
+
Parses a nested dictionary to extract specific fields and their
|
|
111
|
+
associated values.
|
|
112
|
+
|
|
113
|
+
This function traverses a given dictionary recursively and collects
|
|
114
|
+
key-value pairs from the dictionary that match the specified fields.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
_section (dict): A nested dictionary to search for matching fields.
|
|
118
|
+
fields (list[str]): A list of field names to look for in _section.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
list[tuple]: A list of tuples containing key-value pairs for
|
|
122
|
+
the fields found in _section, including from nested dictionaries.
|
|
123
|
+
"""
|
|
124
|
+
ret = []
|
|
125
|
+
for key, value in _section.items():
|
|
126
|
+
if isinstance(value, dict):
|
|
127
|
+
ret.extend(parse_settings_fields(value, fields))
|
|
128
|
+
if key in fields:
|
|
129
|
+
ret.append((key, value))
|
|
130
|
+
return ret
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
from typing import Sequence, Callable
|
|
2
|
+
|
|
3
|
+
from cmdbox.cli.ui.primitives import (
|
|
4
|
+
col,
|
|
5
|
+
pluralize,
|
|
6
|
+
table_panel,
|
|
7
|
+
kv_table,
|
|
8
|
+
section,
|
|
9
|
+
)
|
|
10
|
+
from cmdbox.models import Tag
|
|
11
|
+
|
|
12
|
+
TAG_COLUMNS: dict[str, tuple[str, dict, Callable[[Tag], object]]] = {
|
|
13
|
+
"name": (
|
|
14
|
+
"Name",
|
|
15
|
+
{"style": "entity.name", "no_wrap": True},
|
|
16
|
+
lambda t: t.name,
|
|
17
|
+
),
|
|
18
|
+
"description": (
|
|
19
|
+
"Description",
|
|
20
|
+
{"overflow": "fold"},
|
|
21
|
+
lambda t: t.description,
|
|
22
|
+
),
|
|
23
|
+
"date_created": (
|
|
24
|
+
"Created",
|
|
25
|
+
{"style": "entity.time", "no_wrap": True},
|
|
26
|
+
lambda t: t.date_created,
|
|
27
|
+
),
|
|
28
|
+
"last_updated": (
|
|
29
|
+
"Updated",
|
|
30
|
+
{"style": "entity.time", "no_wrap": True},
|
|
31
|
+
lambda t: t.last_updated,
|
|
32
|
+
),
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
DEFAULT_FIELDS = ["name", "description"]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def render_tag_created(tag: Tag):
|
|
40
|
+
rendered_tag = render_tag(tag)
|
|
41
|
+
return section(
|
|
42
|
+
title=f"Tag '{tag.name}' created",
|
|
43
|
+
body=rendered_tag,
|
|
44
|
+
border_style="status.success",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def render_tag(tag: Tag):
|
|
49
|
+
rows = []
|
|
50
|
+
for value in TAG_COLUMNS.values():
|
|
51
|
+
header, _, extractor = value
|
|
52
|
+
rows.append((header, extractor(tag)))
|
|
53
|
+
return kv_table(rows)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def render_tag_list(
|
|
57
|
+
tags: Sequence[Tag], *, title: str = None, fields: list[str] | None = None
|
|
58
|
+
):
|
|
59
|
+
active_fields = fields or DEFAULT_FIELDS
|
|
60
|
+
active_fields = [f for f in active_fields if f in TAG_COLUMNS]
|
|
61
|
+
|
|
62
|
+
columns = []
|
|
63
|
+
extractors = []
|
|
64
|
+
|
|
65
|
+
for field in active_fields:
|
|
66
|
+
header, col_args, extractor = TAG_COLUMNS[field]
|
|
67
|
+
columns.append(col(header, **col_args))
|
|
68
|
+
extractors.append(extractor)
|
|
69
|
+
|
|
70
|
+
rows = [tuple(extractor(t) for extractor in extractors) for t in tags]
|
|
71
|
+
|
|
72
|
+
caption = f"{pluralize(len(tags), 'tag')} found"
|
|
73
|
+
|
|
74
|
+
return table_panel(
|
|
75
|
+
title=title or "Tags",
|
|
76
|
+
columns=columns,
|
|
77
|
+
rows=rows,
|
|
78
|
+
caption=caption,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def render_tag_updated(tag: Tag):
|
|
83
|
+
rendered_tag = render_tag(tag)
|
|
84
|
+
return section(
|
|
85
|
+
title=f"Tag '{tag.name}' updated",
|
|
86
|
+
body=rendered_tag,
|
|
87
|
+
border_style="status.success",
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def render_tag_deleted(tag: Tag):
|
|
92
|
+
rendered_tag = render_tag(tag)
|
|
93
|
+
return section(
|
|
94
|
+
title=f"Tag '{tag.name}' deleted",
|
|
95
|
+
body=rendered_tag,
|
|
96
|
+
border_style="status.success",
|
|
97
|
+
)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from typing import Sequence, Callable
|
|
2
|
+
|
|
3
|
+
from cmdbox.cli.ui.primitives import (
|
|
4
|
+
col,
|
|
5
|
+
pluralize,
|
|
6
|
+
table_panel,
|
|
7
|
+
kv_table,
|
|
8
|
+
section,
|
|
9
|
+
tag_block,
|
|
10
|
+
)
|
|
11
|
+
from cmdbox.models import Variable
|
|
12
|
+
|
|
13
|
+
VARIABLE_COLUMNS: dict[str, tuple[str, dict, Callable[[Variable], object]]] = {
|
|
14
|
+
"name": (
|
|
15
|
+
"Name",
|
|
16
|
+
{"style": "entity.name", "no_wrap": True},
|
|
17
|
+
lambda v: v.name,
|
|
18
|
+
),
|
|
19
|
+
"value": (
|
|
20
|
+
"Value",
|
|
21
|
+
{"style": "code.inline", "overflow": "fold"},
|
|
22
|
+
lambda v: v.value,
|
|
23
|
+
),
|
|
24
|
+
"date_created": (
|
|
25
|
+
"Created",
|
|
26
|
+
{"style": "entity.time", "no_wrap": True},
|
|
27
|
+
lambda v: v.date_created,
|
|
28
|
+
),
|
|
29
|
+
"last_updated": (
|
|
30
|
+
"Updated",
|
|
31
|
+
{"style": "entity.time", "no_wrap": True},
|
|
32
|
+
lambda v: v.last_updated,
|
|
33
|
+
),
|
|
34
|
+
"tags": (
|
|
35
|
+
"Tags",
|
|
36
|
+
{"overflow": "fold"},
|
|
37
|
+
lambda v: tag_block([x.tag.name for x in v.tags]),
|
|
38
|
+
),
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
DEFAULT_FIELDS = ["name", "value"]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def render_variable_created(variable: Variable):
|
|
45
|
+
rendered_variable = render_variable(variable)
|
|
46
|
+
return section(
|
|
47
|
+
title=f'Variable "{variable.name}" created',
|
|
48
|
+
body=rendered_variable,
|
|
49
|
+
border_style="status.success",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def render_variable(variable: Variable):
|
|
54
|
+
rows = []
|
|
55
|
+
for value in VARIABLE_COLUMNS.values():
|
|
56
|
+
header, _, extractor = value
|
|
57
|
+
rows.append((header, extractor(variable)))
|
|
58
|
+
var_display = kv_table(rows)
|
|
59
|
+
return var_display
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def render_variable_list(
|
|
63
|
+
variables: Sequence[Variable], *, title: str = None, fields: list[str] | None = None
|
|
64
|
+
):
|
|
65
|
+
active_fields = fields or DEFAULT_FIELDS
|
|
66
|
+
active_fields = [f for f in active_fields if f in VARIABLE_COLUMNS]
|
|
67
|
+
|
|
68
|
+
columns = []
|
|
69
|
+
extractors = []
|
|
70
|
+
|
|
71
|
+
for field in active_fields:
|
|
72
|
+
header, col_args, extractor = VARIABLE_COLUMNS[field]
|
|
73
|
+
columns.append(col(header, **col_args))
|
|
74
|
+
extractors.append(extractor)
|
|
75
|
+
|
|
76
|
+
rows = [tuple(extractor(v) for extractor in extractors) for v in variables]
|
|
77
|
+
|
|
78
|
+
caption = f"{pluralize(len(variables), 'variable')} found"
|
|
79
|
+
|
|
80
|
+
return table_panel(
|
|
81
|
+
title=title or "Variables",
|
|
82
|
+
caption=caption,
|
|
83
|
+
columns=columns,
|
|
84
|
+
rows=rows,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def render_variable_updated(variable: Variable):
|
|
89
|
+
rendered_variable = render_variable(variable)
|
|
90
|
+
return section(
|
|
91
|
+
title=f"Variable '{variable.name}' updated",
|
|
92
|
+
body=rendered_variable,
|
|
93
|
+
border_style="status.success",
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def render_variable_deleted(variable: Variable):
|
|
98
|
+
rendered_variable = render_variable(variable)
|
|
99
|
+
return section(
|
|
100
|
+
title=f"Variable '{variable.name}' deleted",
|
|
101
|
+
body=rendered_variable,
|
|
102
|
+
border_style="status.success",
|
|
103
|
+
)
|