diff --git a/src/aiida/cmdline/commands/cmd_code.py b/src/aiida/cmdline/commands/cmd_code.py index aa16b91564..477d2f61ab 100644 --- a/src/aiida/cmdline/commands/cmd_code.py +++ b/src/aiida/cmdline/commands/cmd_code.py @@ -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 @@ -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() diff --git a/src/aiida/cmdline/commands/cmd_setup.py b/src/aiida/cmdline/commands/cmd_setup.py index 0063d31d10..0c18ce4238 100644 --- a/src/aiida/cmdline/commands/cmd_setup.py +++ b/src/aiida/cmdline/commands/cmd_setup.py @@ -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() diff --git a/src/aiida/cmdline/groups/verdi.py b/src/aiida/cmdline/groups/verdi.py index 8f0f3abcc5..987baa1c0c 100644 --- a/src/aiida/cmdline/groups/verdi.py +++ b/src/aiida/cmdline/groups/verdi.py @@ -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: @@ -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) @@ -109,6 +112,7 @@ class VerdiCommandGroup(click.Group): """ context_class = VerdiContext + command_class = VerdiCommand @staticmethod def add_verbosity_option(cmd: click.Command) -> click.Command: @@ -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 diff --git a/tests/cmdline/commands/test_code.py b/tests/cmdline/commands/test_code.py index a36a7bb28a..8aeeb5cec8 100644 --- a/tests/cmdline/commands/test_code.py +++ b/tests/cmdline/commands/test_code.py @@ -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.""" diff --git a/tests/cmdline/commands/test_setup.py b/tests/cmdline/commands/test_setup.py index 9a12e3fb88..6c7a668542 100644 --- a/tests/cmdline/commands/test_setup.py +++ b/tests/cmdline/commands/test_setup.py @@ -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.