Skip to content

Commit

Permalink
allow commands tagged with atstart to be async and run in the backgro…
Browse files Browse the repository at this point in the history
…und (perhaps some long running process while the rest of the shell executes)
  • Loading branch information
Robert Blackhart committed Jun 4, 2022
1 parent e7a39c3 commit d3018a6
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 8 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "recline"
version = "2022.5"
version = "2022.6"
description = "Writing argparse-based command line applications can become tedious, repetitive, and difficult to do right. Relax and let this library free you from that burden."
license = "BSD-3-Clause"
authors = ["NetApp <[email protected]>"]
Expand Down
16 changes: 11 additions & 5 deletions recline/commands/cli_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ def __init__(
is_alias=False,
hidden=False,
is_async=False,
is_background=False,
):
self.func = func
self.name = name if name else func.__name__
self.is_alias = is_alias
self.group = group
self.is_async = is_async
self._hidden = hidden
self.is_background = is_background

signature = inspect.signature(func)
parameters = signature.parameters
Expand Down Expand Up @@ -322,7 +324,8 @@ def command(
aliases: List[str] = None,
atstart: bool = False,
atexit: bool = False,
hidden: Union[Callable[[], bool], bool] = False
hidden: Union[Callable[[], bool], bool] = False,
background: bool = False
):
"""Wrapping a function with this registers it with the recline library and
exposes it as a command the user of the application can call.
Expand Down Expand Up @@ -352,13 +355,16 @@ def command(
output or available for autocompletion. It will still be executable
by the user if they type it out. This can be either a function which
evaluates to True or False, or just a constant True or False.
background: If the command is async and long running, then setting
background to True may be advisable so that other commands can be
run in the foreground in the meantime.
"""


if func is None:
return partial(
command, name=name, group=group, aliases=aliases, atstart=atstart,
atexit=atexit, hidden=hidden,
atexit=atexit, hidden=hidden, background=background,
)

is_async = inspect.iscoroutinefunction(func)
Expand All @@ -367,16 +373,16 @@ def command(
def wrapper(*args, **kwargs):
return func(*args, **kwargs)

_register(wrapper, name, group, aliases, atstart, atexit, hidden, is_async)
_register(wrapper, name, group, aliases, atstart, atexit, hidden, is_async, background)
return wrapper


# pylint: disable=too-many-arguments
def _register(func, name, group, aliases, atstart, atexit, hidden, is_async):
def _register(func, name, group, aliases, atstart, atexit, hidden, is_async, is_background):
if atstart:
if commands.START_COMMAND:
raise RuntimeError(f'A start command is already defined: {func}')
commands.START_COMMAND = CLICommand(func)
commands.START_COMMAND = CLICommand(func, is_async=is_async, is_background=is_background)
return
if atexit:
if commands.EXIT_COMMAND:
Expand Down
7 changes: 5 additions & 2 deletions recline/repl/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,10 @@ def signal_handler(signum, frame):
atexit.register(_run_command, commands.EXIT_COMMAND, [])

if commands.START_COMMAND:
_run_command(commands.START_COMMAND, argv[1:])
try:
_run_command(commands.START_COMMAND, argv[1:])
except CommandBackgrounded:
pass


def _run_command(command: str, cmd_args: List[str]) -> int:
Expand All @@ -217,7 +220,7 @@ def _run_command(command: str, cmd_args: List[str]) -> int:
if command.is_async:
command_thread = AsyncCommand(command, *args, **kwargs)
command_thread.start()
if namespace.background:
if namespace.background or command.is_background:
raise CommandBackgrounded(command_thread.job_pid)
result = command_thread.foreground()
else:
Expand Down

0 comments on commit d3018a6

Please sign in to comment.