From d6eeccf72fa4b14f2af6f04751685a359b6f9c77 Mon Sep 17 00:00:00 2001 From: Leopold Talirz Date: Mon, 31 Oct 2022 22:37:20 +0100 Subject: [PATCH] CLI: `verdi setup/quicksetup` store autofill user info early (#5729) `verdi setup` and `verdi quicksetup` store information about the user, such as their name, email, and institution, but they only do so when the setup finishes successfully. This is tedious when setup fails as the user is forced to re-enter this information anew for every try. Here we simply make sure to store this information early. Co-authored-by: Sebastiaan Huber --- aiida/cmdline/commands/cmd_setup.py | 27 ++++++++++++++++++--------- tests/cmdline/commands/test_setup.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/aiida/cmdline/commands/cmd_setup.py b/aiida/cmdline/commands/cmd_setup.py index d58ca42fd6..a994e1859d 100644 --- a/aiida/cmdline/commands/cmd_setup.py +++ b/aiida/cmdline/commands/cmd_setup.py @@ -41,8 +41,9 @@ @options_setup.SETUP_TEST_PROFILE() @options_setup.SETUP_PROFILE_UUID() @options.CONFIG_FILE() +@click.pass_context def setup( - non_interactive, profile: Profile, email, first_name, last_name, institution, db_engine, db_backend, db_host, + ctx, non_interactive, profile: Profile, email, first_name, last_name, institution, db_engine, db_backend, db_host, db_port, db_name, db_username, db_password, broker_protocol, broker_username, broker_password, broker_host, broker_port, broker_virtual_host, repository, test_profile, profile_uuid ): @@ -52,7 +53,9 @@ def setup( """ # pylint: disable=too-many-arguments,too-many-locals,unused-argument from aiida import orm - from aiida.manage.configuration import get_config + + # store default user settings so user does not have to re-enter them + _store_default_user_settings(ctx.obj.config, email, first_name, last_name, institution) if profile_uuid is not None: profile.uuid = profile_uuid @@ -80,7 +83,7 @@ def setup( ) profile.is_test_profile = test_profile - config = get_config() + config = ctx.obj.config # Create the profile, set it as the default and load it config.add_profile(profile) @@ -101,12 +104,6 @@ def setup( else: echo.echo_success('storage initialisation completed.') - # Optionally setting configuration default user settings - config.set_option('autofill.user.email', email, override=False) - config.set_option('autofill.user.first_name', first_name, override=False) - config.set_option('autofill.user.last_name', last_name, override=False) - config.set_option('autofill.user.institution', institution, override=False) - # Create the user if it does not yet exist created, user = orm.User.collection.get_or_create( email=email, first_name=first_name, last_name=last_name, institution=institution @@ -159,6 +156,9 @@ def quicksetup( # pylint: disable=too-many-arguments,too-many-locals from aiida.manage.external.postgres import Postgres, manual_setup_instructions + # store default user settings so user does not have to re-enter them + _store_default_user_settings(ctx.obj.config, email, first_name, last_name, institution) + dbinfo_su = { 'host': db_host, 'port': db_port, @@ -211,3 +211,12 @@ def quicksetup( 'test_profile': test_profile, } ctx.invoke(setup, **setup_parameters) + + +def _store_default_user_settings(config, email, first_name, last_name, institution): + """Store the default user settings if not already present.""" + config.set_option('autofill.user.email', email, override=False) + config.set_option('autofill.user.first_name', first_name, override=False) + config.set_option('autofill.user.last_name', last_name, override=False) + config.set_option('autofill.user.institution', institution, override=False) + config.store() diff --git a/tests/cmdline/commands/test_setup.py b/tests/cmdline/commands/test_setup.py index df5ec7848b..c5a2df60a2 100644 --- a/tests/cmdline/commands/test_setup.py +++ b/tests/cmdline/commands/test_setup.py @@ -99,6 +99,34 @@ def test_quicksetup_from_config_file(self): handle.flush() self.cli_runner(cmd_setup.quicksetup, ['--config', os.path.realpath(handle.name)]) + def test_quicksetup_autofill_on_early_exit(self): + """Test `verdi quicksetup` stores user information even if command fails.""" + config = configuration.get_config() + assert config.get_option('autofill.user.email', scope=None) is None + assert config.get_option('autofill.user.first_name', scope=None) is None + assert config.get_option('autofill.user.last_name', scope=None) is None + assert config.get_option('autofill.user.institution', scope=None) is None + + user_email = 'some@email.com' + user_first_name = 'John' + user_last_name = 'Smith' + user_institution = 'ECMA' + + # The incorrect port will cause the command to fail, but the user information should have been stored on the + # configuration such that the user won't have to retype it but can use the pre-stored defaults. + options = [ + '--non-interactive', '--profile', 'testing', '--email', user_email, '--first-name', user_first_name, + '--last-name', user_last_name, '--institution', user_institution, '--db-port', + self.pg_test.dsn['port'] + 100 + ] + + self.cli_runner(cmd_setup.quicksetup, options, raises=True) + + assert config.get_option('autofill.user.email', scope=None) == user_email + assert config.get_option('autofill.user.first_name', scope=None) == user_first_name + assert config.get_option('autofill.user.last_name', scope=None) == user_last_name + assert config.get_option('autofill.user.institution', scope=None) == user_institution + def test_quicksetup_wrong_port(self): """Test `verdi quicksetup` exits if port is wrong.""" profile_name = 'testing'