Skip to content

Commit

Permalink
make VerdiCommand default, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
agoscinski authored and sphuber committed Jun 6, 2024
1 parent 5b16cdb commit e305232
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 15 deletions.
3 changes: 1 addition & 2 deletions src/aiida/cmdline/commands/cmd_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

from aiida.cmdline.commands.cmd_verdi import verdi
from aiida.cmdline.groups.dynamic import DynamicEntryPointCommandGroup
from aiida.cmdline.groups.verdi import VerdiCommand
from aiida.cmdline.params import arguments, options, types
from aiida.cmdline.params.options.commands import code as options_code
from aiida.cmdline.utils import echo, echo_tabulate
Expand Down Expand Up @@ -90,7 +89,7 @@ def set_code_builder(ctx, param, value):
# because the ``LABEL`` option has a callback that relies on the computer being already set. Execution order is
# guaranteed only for the interactive case, however. For the non-interactive case, the callback is called explicitly
# once more in the command body to cover the case when the label is specified before the computer.
@verdi_code.command('setup', deprecated='Please use `verdi code create` instead.', cls=VerdiCommand)
@verdi_code.command('setup', deprecated='Please use `verdi code create` instead.')
@options_code.ON_COMPUTER()
@options_code.COMPUTER()
@options_code.LABEL()
Expand Down
3 changes: 1 addition & 2 deletions src/aiida/cmdline/commands/cmd_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@
import click

from aiida.cmdline.commands.cmd_verdi import verdi
from aiida.cmdline.groups.verdi import VerdiCommand
from aiida.cmdline.params import options
from aiida.cmdline.params.options.commands import setup as options_setup
from aiida.cmdline.utils import decorators, echo
from aiida.manage.configuration import Profile, load_profile


@verdi.command('setup', deprecated='Please use `verdi profile setup` instead.', cls=VerdiCommand)
@verdi.command('setup', deprecated='Please use `verdi profile setup` instead.')
@options.NON_INTERACTIVE()
@options_setup.SETUP_PROFILE()
@options_setup.SETUP_USER_EMAIL()
Expand Down
17 changes: 6 additions & 11 deletions src/aiida/cmdline/groups/verdi.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ def __init__(self, *args, **kwargs):


class VerdiCommand(click.Command):
""" """
"""Custom command implementation to change the logic how the deprecation warning is handled. In the parent class the
warning is printed only on invocation and after the parsing of the arguments. In this class we print the warning in
addition when the help page is printed and change the behavior on invocation. It is printed on invocation before the
arguments are parsed. That allows a printing of the deprecation warning with the first prompt requesting missing
arguments."""

def parse_args(self, ctx: click.Context, args: t.List[str]) -> t.List[str]:
if self.deprecated:
Expand All @@ -96,7 +100,6 @@ def parse_args(self, ctx: click.Context, args: t.List[str]) -> t.List[str]:
return super().parse_args(ctx, args)

def invoke(self, ctx: click.Context) -> t.Any:
"""Overwrites the deprecation warning that is now printed in parse_args"""
if self.callback is not None:
return ctx.invoke(self.callback, **ctx.params)

Expand All @@ -109,6 +112,7 @@ class VerdiCommandGroup(click.Group):
"""

context_class = VerdiContext
command_class = VerdiCommand

@staticmethod
def add_verbosity_option(cmd: click.Command) -> click.Command:
Expand Down Expand Up @@ -154,15 +158,6 @@ def get_command(self, ctx: click.Context, cmd_name: str) -> click.Command | None
cmd = super().get_command(ctx, cmd_name)

if cmd is not None:
# if cmd.deprecated:
# import ipdb; ipdb.set_trace()
# # We are abusing click.Command `deprecated` member variable by using a
# # string instead of a bool to also use it as optional deprecated message
# echo_deprecated(
# cmd.deprecated
# if isinstance(cmd.deprecated, str) # type: ignore[redundant-expr]
# else 'This command is deprecated.'
# )
return self.add_verbosity_option(cmd)

# If this command is called during tab-completion, we do not want to print an error message if the command can't
Expand Down
15 changes: 15 additions & 0 deletions tests/cmdline/commands/test_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ def test_help(run_cli_command):
run_cli_command(cmd_code.setup_code, ['--help'])


def test_code_setup_deprecation(run_cli_command):
"""Checks if a deprecation warning is printed in stdout and stderr."""
# Checks if the deprecation warning is present when invoking the help page
result = run_cli_command(cmd_code.setup_code, ['--help'])
assert 'Deprecated:' in result.output
assert 'Deprecated:' in result.stderr

# Checks if the deprecation warning is present when invoking the command
# Runs setup in interactive mode and sends Ctrl+D (\x04) as input so we exit the prompts.
# This way we can check if the deprecated message was printed with the first prompt.
result = run_cli_command(cmd_code.setup_code, user_input='\x04', use_subprocess=True, raises=True)
assert 'Deprecated:' in result.output
assert 'Deprecated:' in result.stderr


@pytest.mark.usefixtures('aiida_profile_clean')
def test_code_list_no_codes_error_message(run_cli_command):
"""Test ``verdi code list`` when no codes exist."""
Expand Down
14 changes: 14 additions & 0 deletions tests/cmdline/commands/test_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ def init_profile(self, pg_test_cluster, empty_config, run_cli_command):
self.pg_test = pg_test_cluster
self.cli_runner = run_cli_command

def test_setup_deprecation(self):
"""Checks if a deprecation warning is printed in stdout and stderr."""
# Checks if the deprecation warning is present when invoking the help page
result = self.cli_runner(cmd_setup.setup, ['--help'])
assert 'Deprecated:' in result.output
assert 'Deprecated:' in result.stderr

# Checks if the deprecation warning is present when invoking the command
# Runs setup in interactive mode and sends Ctrl+D (\x04) as input so we exit the prompts.
# This way we can check if the deprecation warning was printed with the first prompt.
result = self.cli_runner(cmd_setup.setup, user_input='\x04', use_subprocess=True, raises=True)
assert 'Deprecated:' in result.output
assert 'Deprecated:' in result.stderr

def test_help(self):
"""Check that the `--help` option is eager, is not overruled and will properly display the help message.
Expand Down

0 comments on commit e305232

Please sign in to comment.