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
cmdbox/__init__.py
ADDED
|
File without changes
|
cmdbox/cli/__init__.py
ADDED
|
File without changes
|
cmdbox/cli/app.py
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from typing import Annotated
|
|
3
|
+
|
|
4
|
+
import typer
|
|
5
|
+
|
|
6
|
+
from cmdbox import container
|
|
7
|
+
from cmdbox.cli.commands.alias_fallback import AliasFallbackGroup
|
|
8
|
+
from cmdbox.cli.ui.presenters.app_presenter import render_version
|
|
9
|
+
from cmdbox.logging_setup.log_handlers import configure_logging
|
|
10
|
+
from cmdbox.logging_setup.log_config import build_log_config, get_logger
|
|
11
|
+
from cmdbox.version import __version__
|
|
12
|
+
from cmdbox.database import ensure_schema, get_db
|
|
13
|
+
from .commands.command_crud import app as command_crud_app
|
|
14
|
+
from .commands.command_run import app as command_run_app
|
|
15
|
+
from .commands.variable_crud import app as variable_crud_app
|
|
16
|
+
from .commands.tag_crud import app as tag_crud_app
|
|
17
|
+
from .commands.init import app as init_app
|
|
18
|
+
from .commands.settings import app as settings_app
|
|
19
|
+
from .commands.history import app as history_app
|
|
20
|
+
|
|
21
|
+
app = typer.Typer(
|
|
22
|
+
name="cb",
|
|
23
|
+
cls=AliasFallbackGroup,
|
|
24
|
+
help="CmdBox is a CLI tool for storing and recalling commands with many helpful quality of life features.",
|
|
25
|
+
no_args_is_help=True,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
app.add_typer(
|
|
29
|
+
command_crud_app,
|
|
30
|
+
name="cmd",
|
|
31
|
+
help="CRUD (Create, Read, Update, Delete) operations for commands.",
|
|
32
|
+
)
|
|
33
|
+
app.add_typer(variable_crud_app, name="var", help="CRUD operations for variables.")
|
|
34
|
+
app.add_typer(tag_crud_app, name="tag", help="CRUD operations for tags.")
|
|
35
|
+
app.add_typer(command_run_app)
|
|
36
|
+
app.add_typer(init_app)
|
|
37
|
+
app.add_typer(settings_app, name="settings", help="Manage CmdBox settings.")
|
|
38
|
+
app.add_typer(
|
|
39
|
+
history_app, name="history", help="View and re-run command execution history."
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def version_callback(value: bool):
|
|
44
|
+
if value:
|
|
45
|
+
console = container.get_console()
|
|
46
|
+
rendered_version = render_version(__version__)
|
|
47
|
+
console.print(rendered_version)
|
|
48
|
+
raise typer.Exit()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@app.callback()
|
|
52
|
+
def common(
|
|
53
|
+
test: Annotated[
|
|
54
|
+
bool,
|
|
55
|
+
typer.Option(
|
|
56
|
+
"--test",
|
|
57
|
+
"-t",
|
|
58
|
+
help="Enables testing mode. Database will be created in memory and will not affect the "
|
|
59
|
+
"applications persistent database.",
|
|
60
|
+
),
|
|
61
|
+
] = False,
|
|
62
|
+
verbose: Annotated[
|
|
63
|
+
bool,
|
|
64
|
+
typer.Option(
|
|
65
|
+
"--verbose",
|
|
66
|
+
"-v",
|
|
67
|
+
help="Enable additional diagnostic output in the terminal. Sets console log level to INFO.",
|
|
68
|
+
),
|
|
69
|
+
] = False,
|
|
70
|
+
debug: Annotated[
|
|
71
|
+
bool,
|
|
72
|
+
typer.Option(
|
|
73
|
+
"--debug",
|
|
74
|
+
"-d",
|
|
75
|
+
help="Enable full diagnostic output in the terminal. Sets console log level to DEBUG.",
|
|
76
|
+
),
|
|
77
|
+
] = False,
|
|
78
|
+
file_logs: Annotated[
|
|
79
|
+
bool | None,
|
|
80
|
+
typer.Option(
|
|
81
|
+
"--file-logs/--no-file-logs",
|
|
82
|
+
help="Enable/disables writing diagnostic logs to a file. Defaults to settings.",
|
|
83
|
+
),
|
|
84
|
+
] = None,
|
|
85
|
+
version: Annotated[
|
|
86
|
+
bool,
|
|
87
|
+
typer.Option(
|
|
88
|
+
"--version",
|
|
89
|
+
"-V",
|
|
90
|
+
callback=version_callback,
|
|
91
|
+
is_eager=True,
|
|
92
|
+
help="Print the app version and exit.",
|
|
93
|
+
),
|
|
94
|
+
] = None,
|
|
95
|
+
) -> None:
|
|
96
|
+
if test:
|
|
97
|
+
get_db(testing=True)
|
|
98
|
+
|
|
99
|
+
settings = container.get_settings()
|
|
100
|
+
|
|
101
|
+
run_id = uuid.uuid4().hex[:6]
|
|
102
|
+
log_config = build_log_config(
|
|
103
|
+
settings=settings, verbose=verbose, debug=debug, file_logs=file_logs
|
|
104
|
+
)
|
|
105
|
+
configure_logging(log_config, run_id=run_id)
|
|
106
|
+
|
|
107
|
+
log = get_logger()
|
|
108
|
+
log.debug(
|
|
109
|
+
f"startup: test={test}, verbose={verbose}, debug={debug}, file_logs={file_logs}"
|
|
110
|
+
)
|
|
111
|
+
log.debug(f"file_logging={log_config.file_enabled} path={log_config.file_path}")
|
|
112
|
+
|
|
113
|
+
ensure_schema()
|
|
114
|
+
|
|
115
|
+
if test:
|
|
116
|
+
console = container.get_console()
|
|
117
|
+
console.info("Testing mode is active, database is in memory.")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def main() -> None:
|
|
121
|
+
app()
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
if __name__ == "__main__":
|
|
125
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from typer.core import TyperGroup
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AliasFallbackGroup(TyperGroup):
|
|
6
|
+
"""
|
|
7
|
+
Handles command grouping with support for alias-based fallback.
|
|
8
|
+
|
|
9
|
+
This class extends the functionality of TyperGroup to include command alias
|
|
10
|
+
resolution. When a command is not directly found, it attempts to resolve the
|
|
11
|
+
command name using a predefined alias mapping and dynamically generates an
|
|
12
|
+
alias command that forwards its arguments to a core `run` command. This allows
|
|
13
|
+
users to define shorter or alternate names for commands while maintaining
|
|
14
|
+
flexibility.
|
|
15
|
+
|
|
16
|
+
Attributes:
|
|
17
|
+
_command_aliases (dict[str, str]): A mapping of alias names to their
|
|
18
|
+
corresponding actual command names. Used for resolving commands
|
|
19
|
+
through aliases.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
_command_aliases: dict[str, str] = {
|
|
23
|
+
"cmds": "cmd",
|
|
24
|
+
"vars": "var",
|
|
25
|
+
"tags": "tag",
|
|
26
|
+
"hist": "history",
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
The second item in the list is the name of the command as configured by
|
|
31
|
+
`@app.command("command_name")`, not the method name. Further items in the list
|
|
32
|
+
will be supplied to that sub-command as args.
|
|
33
|
+
"""
|
|
34
|
+
_shortcut_commands: dict[str, list[str]] = {"!!": ["history", "last"]}
|
|
35
|
+
|
|
36
|
+
def get_command(self, ctx: click.Context, cmd_name: str):
|
|
37
|
+
"""
|
|
38
|
+
Retrieves a command based on the command name, creating an alias command if
|
|
39
|
+
the command was not directly found.
|
|
40
|
+
|
|
41
|
+
If the command corresponding to `cmd_name` doesn't exist, a new alias
|
|
42
|
+
command is generated using the `run` command, forwarding all its parameters
|
|
43
|
+
except the `alias` parameter.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
ctx (click.Context): The Click context in which the command is being
|
|
47
|
+
invoked.
|
|
48
|
+
cmd_name (str): The name of the command to retrieve.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
click.Command: The command object corresponding to the given
|
|
52
|
+
`cmd_name`, or an alias command if the original command does not exist.
|
|
53
|
+
Returns None if `run` command is also unavailable.
|
|
54
|
+
"""
|
|
55
|
+
cmd_name = self._command_aliases.get(cmd_name, cmd_name)
|
|
56
|
+
|
|
57
|
+
rv = super().get_command(ctx, cmd_name)
|
|
58
|
+
if rv is not None:
|
|
59
|
+
return rv
|
|
60
|
+
|
|
61
|
+
run_cmd = super().get_command(ctx, "run")
|
|
62
|
+
if run_cmd is None:
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
forwarded_params = [p for p in run_cmd.params if p.name != "alias"]
|
|
66
|
+
|
|
67
|
+
@click.command(
|
|
68
|
+
cmd_name,
|
|
69
|
+
params=forwarded_params,
|
|
70
|
+
help=f"Run stored command '{cmd_name}'.",
|
|
71
|
+
context_settings=run_cmd.context_settings,
|
|
72
|
+
)
|
|
73
|
+
@click.pass_context
|
|
74
|
+
def _alias_cmd(inner_ctx: click.Context, **kwargs):
|
|
75
|
+
inner_ctx.meta["_extra_args"] = inner_ctx.args[:]
|
|
76
|
+
inner_ctx.invoke(run_cmd, alias=cmd_name, **kwargs)
|
|
77
|
+
|
|
78
|
+
return _alias_cmd
|
|
79
|
+
|
|
80
|
+
def resolve_command(self, ctx: click.Context, args: list):
|
|
81
|
+
"""
|
|
82
|
+
Resolves the command by expanding shortcut commands if applicable.
|
|
83
|
+
|
|
84
|
+
This method checks whether the provided command arguments include a shortcut
|
|
85
|
+
command. If a shortcut command is detected, it is expanded into its full form
|
|
86
|
+
and the resulting extended argument list is passed to the parent class's
|
|
87
|
+
`resolve_command` method. If no shortcut is found, the original argument list
|
|
88
|
+
is passed directly.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
ctx (click.Context): The Click context containing information about the
|
|
92
|
+
execution of the command.
|
|
93
|
+
args (list): A list of command-line arguments passed to the command.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
tuple: A tuple containing the command name, the command object, and a list
|
|
97
|
+
of remaining arguments.
|
|
98
|
+
"""
|
|
99
|
+
if args and args[0] in self._shortcut_commands:
|
|
100
|
+
expanded = self._shortcut_commands[args[0]]
|
|
101
|
+
return super().resolve_command(ctx, expanded + list(args[1:]))
|
|
102
|
+
return super().resolve_command(ctx, args)
|
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
import logging
|
|
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.commands import complete_command_aliases
|
|
9
|
+
from cmdbox.cli.completions.fields import (
|
|
10
|
+
command_field_options,
|
|
11
|
+
command_editable_field_options,
|
|
12
|
+
)
|
|
13
|
+
from cmdbox.cli.completions.tags import complete_tag_names
|
|
14
|
+
from cmdbox.cli.handlers import command_handlers
|
|
15
|
+
|
|
16
|
+
app = typer.Typer(no_args_is_help=True)
|
|
17
|
+
|
|
18
|
+
cli_guard = make_cli_guard(container.get_console)
|
|
19
|
+
|
|
20
|
+
log = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@app.command("add")
|
|
24
|
+
@cli_guard
|
|
25
|
+
def add(
|
|
26
|
+
alias: Annotated[
|
|
27
|
+
str,
|
|
28
|
+
typer.Argument(
|
|
29
|
+
help="The name of the command. Will be used to recall the command."
|
|
30
|
+
),
|
|
31
|
+
] = None,
|
|
32
|
+
template: Annotated[
|
|
33
|
+
str,
|
|
34
|
+
typer.Argument(
|
|
35
|
+
help="The actual command value that will be executed when the command is recalled using the alias."
|
|
36
|
+
),
|
|
37
|
+
] = None,
|
|
38
|
+
description: Annotated[
|
|
39
|
+
str, typer.Option("--description", "-d", help="A description of the command.")
|
|
40
|
+
] = None,
|
|
41
|
+
tags: Annotated[
|
|
42
|
+
list[str],
|
|
43
|
+
typer.Option(
|
|
44
|
+
"--tags",
|
|
45
|
+
"-t",
|
|
46
|
+
help="A list of tags to associate with the command, separated by commas.",
|
|
47
|
+
autocompletion=complete_tag_names,
|
|
48
|
+
),
|
|
49
|
+
] = None,
|
|
50
|
+
cwd: Annotated[
|
|
51
|
+
str,
|
|
52
|
+
typer.Option("--cwd", "-c", help="Working directory to run the command from."),
|
|
53
|
+
] = None,
|
|
54
|
+
shell: Annotated[
|
|
55
|
+
str,
|
|
56
|
+
typer.Option("--shell", "-s", help="Shell to use when running the command."),
|
|
57
|
+
] = None,
|
|
58
|
+
env: Annotated[
|
|
59
|
+
list[str],
|
|
60
|
+
typer.Option(
|
|
61
|
+
"--env",
|
|
62
|
+
"-e",
|
|
63
|
+
help="Environment variable to set when running the command, in KEY=VALUE format.",
|
|
64
|
+
),
|
|
65
|
+
] = None,
|
|
66
|
+
timeout: Annotated[
|
|
67
|
+
int,
|
|
68
|
+
typer.Option(
|
|
69
|
+
"--timeout",
|
|
70
|
+
"-o",
|
|
71
|
+
help="Maximum number of seconds before the process is killed.",
|
|
72
|
+
),
|
|
73
|
+
] = None,
|
|
74
|
+
interactive: Annotated[
|
|
75
|
+
bool,
|
|
76
|
+
typer.Option("--interactive", "-i", is_flag=True, help="Interactive mode."),
|
|
77
|
+
] = False,
|
|
78
|
+
) -> None:
|
|
79
|
+
"""
|
|
80
|
+
Adds a new command with an alias, a template, description, and tags. The command
|
|
81
|
+
can be created in interactive if no options are provided or the `--interactive`
|
|
82
|
+
flag is used.
|
|
83
|
+
"""
|
|
84
|
+
log.debug("cmd.add called. alias=%s, interactive=%s", alias, interactive)
|
|
85
|
+
add_cmd_args = command_handlers.AddCommandArgs(
|
|
86
|
+
alias=alias,
|
|
87
|
+
template=template,
|
|
88
|
+
description=description,
|
|
89
|
+
tags=tags,
|
|
90
|
+
cwd=cwd,
|
|
91
|
+
shell=shell,
|
|
92
|
+
env=env,
|
|
93
|
+
timeout=timeout,
|
|
94
|
+
interactive=interactive,
|
|
95
|
+
)
|
|
96
|
+
command_handlers.run_add_command(
|
|
97
|
+
args=add_cmd_args,
|
|
98
|
+
get_cmd_services=container.get_command_services,
|
|
99
|
+
get_tag_services=container.get_tag_services,
|
|
100
|
+
get_console=container.get_console,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@app.command("get")
|
|
105
|
+
@cli_guard
|
|
106
|
+
def get(
|
|
107
|
+
alias: Annotated[
|
|
108
|
+
str,
|
|
109
|
+
typer.Argument(
|
|
110
|
+
help="The alias of the command to retrieve.",
|
|
111
|
+
autocompletion=complete_command_aliases,
|
|
112
|
+
),
|
|
113
|
+
],
|
|
114
|
+
) -> None:
|
|
115
|
+
"""
|
|
116
|
+
Retrieves and displays a saved command stored under the provided alias.
|
|
117
|
+
"""
|
|
118
|
+
log.debug("cmd.get called. alias=%s", alias)
|
|
119
|
+
command_handlers.run_get_command(
|
|
120
|
+
alias=alias,
|
|
121
|
+
get_cmd_services=container.get_command_services,
|
|
122
|
+
get_console=container.get_console,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@app.command("update")
|
|
127
|
+
@cli_guard
|
|
128
|
+
def update(
|
|
129
|
+
alias: Annotated[
|
|
130
|
+
str,
|
|
131
|
+
typer.Argument(
|
|
132
|
+
help="The alias of the command to update.",
|
|
133
|
+
autocompletion=complete_command_aliases,
|
|
134
|
+
),
|
|
135
|
+
],
|
|
136
|
+
template: Annotated[
|
|
137
|
+
str, typer.Option("--template", "-t", help="The new template.")
|
|
138
|
+
] = None,
|
|
139
|
+
description: Annotated[
|
|
140
|
+
str, typer.Option("--description", "-d", help="The new description.")
|
|
141
|
+
] = None,
|
|
142
|
+
new_alias: Annotated[
|
|
143
|
+
str, typer.Option("--alias", "-a", help="The new alias.")
|
|
144
|
+
] = None,
|
|
145
|
+
cwd: Annotated[
|
|
146
|
+
str,
|
|
147
|
+
typer.Option("--cwd", "-c", help="Working directory to run the command from."),
|
|
148
|
+
] = None,
|
|
149
|
+
shell: Annotated[
|
|
150
|
+
str,
|
|
151
|
+
typer.Option("--shell", "-s", help="Shell to use when running the command."),
|
|
152
|
+
] = None,
|
|
153
|
+
env: Annotated[
|
|
154
|
+
list[str],
|
|
155
|
+
typer.Option(
|
|
156
|
+
"--env",
|
|
157
|
+
"-e",
|
|
158
|
+
help="Environment variable to set when running the command, in KEY=VALUE format.",
|
|
159
|
+
),
|
|
160
|
+
] = None,
|
|
161
|
+
timeout: Annotated[
|
|
162
|
+
int,
|
|
163
|
+
typer.Option(
|
|
164
|
+
"--timeout",
|
|
165
|
+
"-o",
|
|
166
|
+
help="Maximum number of seconds before the process is killed.",
|
|
167
|
+
),
|
|
168
|
+
] = None,
|
|
169
|
+
set_: Annotated[
|
|
170
|
+
list[str],
|
|
171
|
+
typer.Option(
|
|
172
|
+
"--set",
|
|
173
|
+
"-s",
|
|
174
|
+
help="A list of key=value pairs to update.",
|
|
175
|
+
autocompletion=command_editable_field_options,
|
|
176
|
+
),
|
|
177
|
+
] = None,
|
|
178
|
+
edit_mode: Annotated[
|
|
179
|
+
bool,
|
|
180
|
+
typer.Option("--edit", "-e", help="Edit mode."),
|
|
181
|
+
] = False,
|
|
182
|
+
edit_fields: Annotated[
|
|
183
|
+
str,
|
|
184
|
+
typer.Option(
|
|
185
|
+
"--edit-fields",
|
|
186
|
+
help="A list of fields to be edited in edit mode, separated by commas. Defaults to all fields.",
|
|
187
|
+
),
|
|
188
|
+
] = None,
|
|
189
|
+
) -> None:
|
|
190
|
+
"""
|
|
191
|
+
Updates an existing command with the provided options. Each field can be updated
|
|
192
|
+
individually or in bulk using the `--set` option. Using the `--edit` option enables
|
|
193
|
+
editing the already stored values in an interactive mode.
|
|
194
|
+
"""
|
|
195
|
+
log.debug(
|
|
196
|
+
"cmd.update called. alias=%s template_provided=%s description_provided=%s new_alias_provided=%s "
|
|
197
|
+
"set_used=%s, edit_mode=%s, edit_fields=%s",
|
|
198
|
+
alias,
|
|
199
|
+
template is not None,
|
|
200
|
+
description is not None,
|
|
201
|
+
new_alias is not None,
|
|
202
|
+
set_ is not None,
|
|
203
|
+
edit_mode,
|
|
204
|
+
edit_fields,
|
|
205
|
+
)
|
|
206
|
+
command_handlers.run_update_command(
|
|
207
|
+
alias=alias,
|
|
208
|
+
template=template,
|
|
209
|
+
description=description,
|
|
210
|
+
new_alias=new_alias,
|
|
211
|
+
cwd=cwd,
|
|
212
|
+
shell=shell,
|
|
213
|
+
env=env,
|
|
214
|
+
timeout=timeout,
|
|
215
|
+
set_pairs=set_,
|
|
216
|
+
edit_mode=edit_mode,
|
|
217
|
+
edit_fields=edit_fields,
|
|
218
|
+
get_cmd_services=container.get_command_services,
|
|
219
|
+
get_settings=container.get_settings,
|
|
220
|
+
get_console=container.get_console,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
app.command("edit", hidden=True)(update)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
@app.command("list")
|
|
228
|
+
@cli_guard
|
|
229
|
+
def list_cmds(
|
|
230
|
+
order: Annotated[
|
|
231
|
+
str,
|
|
232
|
+
typer.Option(
|
|
233
|
+
"--order",
|
|
234
|
+
"-o",
|
|
235
|
+
help="The field to order the results by.",
|
|
236
|
+
autocompletion=command_field_options,
|
|
237
|
+
),
|
|
238
|
+
] = "alias",
|
|
239
|
+
tags: Annotated[
|
|
240
|
+
list[str],
|
|
241
|
+
typer.Option(
|
|
242
|
+
"--tag",
|
|
243
|
+
"-t",
|
|
244
|
+
help="The tag to filter by.",
|
|
245
|
+
autocompletion=complete_tag_names,
|
|
246
|
+
),
|
|
247
|
+
] = None,
|
|
248
|
+
limit: Annotated[
|
|
249
|
+
int,
|
|
250
|
+
typer.Option("--limit", "-l", help="The maximum number of results to return."),
|
|
251
|
+
] = 10,
|
|
252
|
+
fields: Annotated[
|
|
253
|
+
list[str] | None,
|
|
254
|
+
typer.Option(
|
|
255
|
+
"--field",
|
|
256
|
+
"-f",
|
|
257
|
+
help="The field(s) to display in the results list. Defaults fields in settings.",
|
|
258
|
+
autocompletion=command_field_options,
|
|
259
|
+
),
|
|
260
|
+
] = None,
|
|
261
|
+
) -> None:
|
|
262
|
+
"""
|
|
263
|
+
Displays all stored commands in a list format. The number of results can be limited
|
|
264
|
+
with the `--limit` option. The output fields can be customized with the `--field` option.
|
|
265
|
+
"""
|
|
266
|
+
log.debug(
|
|
267
|
+
"cmd.list called. order=%s, tags=%s, limit=%s, fields=%s",
|
|
268
|
+
order,
|
|
269
|
+
tags,
|
|
270
|
+
limit,
|
|
271
|
+
fields,
|
|
272
|
+
)
|
|
273
|
+
command_handlers.run_list_command(
|
|
274
|
+
limit=limit,
|
|
275
|
+
order=order,
|
|
276
|
+
tags=tags,
|
|
277
|
+
fields=fields,
|
|
278
|
+
get_cmd_services=container.get_command_services,
|
|
279
|
+
get_settings=container.get_settings,
|
|
280
|
+
get_console=container.get_console,
|
|
281
|
+
get_display_field_resolver=container.get_command_display_field_resolver,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
app.command("ls", hidden=True)(list_cmds)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
@app.command("search")
|
|
289
|
+
@cli_guard
|
|
290
|
+
def search(
|
|
291
|
+
term: Annotated[str, typer.Argument(help="The search term to use.")],
|
|
292
|
+
limit: Annotated[
|
|
293
|
+
int, typer.Option(help="The maximum number of results to return.")
|
|
294
|
+
] = 10,
|
|
295
|
+
search_fields: Annotated[
|
|
296
|
+
list[str],
|
|
297
|
+
typer.Option(
|
|
298
|
+
"--in",
|
|
299
|
+
"-i",
|
|
300
|
+
help="The fields to search within.",
|
|
301
|
+
autocompletion=command_field_options,
|
|
302
|
+
),
|
|
303
|
+
] = None,
|
|
304
|
+
fields: Annotated[
|
|
305
|
+
list[str] | None,
|
|
306
|
+
typer.Option(
|
|
307
|
+
"--field",
|
|
308
|
+
"-f",
|
|
309
|
+
help="The field(s) to display in the results list. Defaults to all fields.",
|
|
310
|
+
autocompletion=command_field_options,
|
|
311
|
+
),
|
|
312
|
+
] = None,
|
|
313
|
+
) -> None:
|
|
314
|
+
"""
|
|
315
|
+
Searches the database for commands matching the provided search term. The search fields
|
|
316
|
+
can be customized with the `--in` option. The output fields can be customized with the
|
|
317
|
+
`--field` option.
|
|
318
|
+
"""
|
|
319
|
+
log.debug(
|
|
320
|
+
"cmd.search called. term=%s, limit=%s, search_fields=%s, fields=%s",
|
|
321
|
+
term,
|
|
322
|
+
limit,
|
|
323
|
+
search_fields,
|
|
324
|
+
fields,
|
|
325
|
+
)
|
|
326
|
+
command_handlers.run_search_command(
|
|
327
|
+
term=term,
|
|
328
|
+
limit=limit,
|
|
329
|
+
search_fields=search_fields,
|
|
330
|
+
fields=fields,
|
|
331
|
+
get_cmd_services=container.get_command_services,
|
|
332
|
+
get_settings=container.get_settings,
|
|
333
|
+
get_console=container.get_console,
|
|
334
|
+
get_display_field_resolver=container.get_command_display_field_resolver,
|
|
335
|
+
get_search_field_resolver=container.get_command_search_field_resolver,
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
app.command("find", hidden=True)(search)
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
@app.command("delete")
|
|
343
|
+
@cli_guard
|
|
344
|
+
def delete(
|
|
345
|
+
alias: Annotated[
|
|
346
|
+
str,
|
|
347
|
+
typer.Argument(
|
|
348
|
+
help="The alias of the command to delete.",
|
|
349
|
+
autocompletion=complete_command_aliases,
|
|
350
|
+
),
|
|
351
|
+
],
|
|
352
|
+
) -> None:
|
|
353
|
+
"""
|
|
354
|
+
Deletes the command stored under the provided alias.
|
|
355
|
+
"""
|
|
356
|
+
log.debug("cmd.delete called. alias=%s", alias)
|
|
357
|
+
command_handlers.run_delete_command(
|
|
358
|
+
alias=alias,
|
|
359
|
+
get_cmd_services=container.get_command_services,
|
|
360
|
+
get_console=container.get_console,
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
app.command("del", hidden=True)(delete)
|
|
365
|
+
app.command("rm", hidden=True)(delete)
|
|
366
|
+
app.command("remove", hidden=True)(delete)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
@app.command("tag")
|
|
370
|
+
@cli_guard
|
|
371
|
+
def add_tags(
|
|
372
|
+
alias: Annotated[
|
|
373
|
+
str,
|
|
374
|
+
typer.Argument(
|
|
375
|
+
help="The alias of the command to tag.",
|
|
376
|
+
autocompletion=complete_command_aliases,
|
|
377
|
+
),
|
|
378
|
+
] = None,
|
|
379
|
+
tags: Annotated[
|
|
380
|
+
list[str],
|
|
381
|
+
typer.Argument(
|
|
382
|
+
help="The tags to add to the command, separated by commas.",
|
|
383
|
+
autocompletion=complete_tag_names,
|
|
384
|
+
),
|
|
385
|
+
] = None,
|
|
386
|
+
) -> None:
|
|
387
|
+
"""
|
|
388
|
+
Adds the provided tags to the command stored under the provided alias. Tags must
|
|
389
|
+
be existing.
|
|
390
|
+
"""
|
|
391
|
+
log.debug("cmd.tag.add called. alias=%s, tags=%s", alias, tags)
|
|
392
|
+
command_handlers.run_attach_tags(
|
|
393
|
+
alias=alias,
|
|
394
|
+
tag_names=tags,
|
|
395
|
+
get_cmd_services=container.get_command_services,
|
|
396
|
+
get_tag_services=container.get_tag_services,
|
|
397
|
+
get_console=container.get_console,
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
@app.command("untag")
|
|
402
|
+
@cli_guard
|
|
403
|
+
def remove_tags(
|
|
404
|
+
alias: Annotated[
|
|
405
|
+
str,
|
|
406
|
+
typer.Argument(
|
|
407
|
+
help="The alias of the command to untag.",
|
|
408
|
+
autocompletion=complete_command_aliases,
|
|
409
|
+
),
|
|
410
|
+
] = None,
|
|
411
|
+
tags: Annotated[
|
|
412
|
+
list[str],
|
|
413
|
+
typer.Argument(
|
|
414
|
+
help="The tags to remove from the command, separated by commas.",
|
|
415
|
+
autocompletion=complete_tag_names,
|
|
416
|
+
),
|
|
417
|
+
] = None,
|
|
418
|
+
) -> None:
|
|
419
|
+
"""
|
|
420
|
+
Removes the provided tags from the command stored under the provided alias.
|
|
421
|
+
"""
|
|
422
|
+
log.debug("cmd.tag.remove called. alias=%s, tags=%s", alias, tags)
|
|
423
|
+
command_handlers.run_detach_tags(
|
|
424
|
+
alias=alias,
|
|
425
|
+
tag_names=tags,
|
|
426
|
+
get_cmd_services=container.get_command_services,
|
|
427
|
+
get_tag_services=container.get_tag_services,
|
|
428
|
+
get_console=container.get_console,
|
|
429
|
+
)
|