Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

making verdi setup & verdi quicksetup more user friendly #606

Merged
merged 22 commits into from
Sep 12, 2017
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2d8cff9
added prompt for profile name to verdi quicksetup
ltalirz Jun 21, 2017
47bb2a0
Merge remote-tracking branch 'upstream/develop' into fix_XXX_verdi_qu…
ltalirz Jun 21, 2017
a59e93d
improved verdi quicksetup help
ltalirz Jun 21, 2017
8f9f24e
fixed underscores and added documentation
ltalirz Jun 21, 2017
fedc731
verdi help now shows command line options
ltalirz Jun 22, 2017
3eefe19
removed default email in verdi setup
ltalirz Jun 22, 2017
5e4da13
added --set-default, --no-set-default options
ltalirz Jul 17, 2017
0432d15
add verdi profile delete
ltalirz Jul 17, 2017
3dbcfc2
Merge branch 'develop' into fix_XXX_verdi_quicksetup
ltalirz Jul 17, 2017
d5efa7d
minor improvements in documentation
ltalirz Jul 17, 2017
f76d431
now deleting profile repository as well
ltalirz Jul 28, 2017
9078c69
Merge branch 'develop' into fix_XXX_verdi_quicksetup
ltalirz Jul 28, 2017
bc75b05
Merge branch 'develop' into fix_XXX_verdi_quicksetup
sphuber Aug 16, 2017
fd76925
add checks, trim overly long lines
ltalirz Aug 17, 2017
43ddd64
Merge branch 'develop' into fix_XXX_verdi_quicksetup
ltalirz Aug 28, 2017
157fbc2
Merge branch 'develop' into fix_XXX_verdi_quicksetup
ltalirz Sep 5, 2017
604413f
add --yes option for verdi profile delete
ltalirz Sep 12, 2017
6c8f05b
Merge branch 'fix_XXX_verdi_quicksetup' of github.com:ltalirz/aiida_c…
ltalirz Sep 12, 2017
9bbf2a5
fix bug verdi profile delete
ltalirz Sep 12, 2017
be21424
Merge branch 'develop' into fix_XXX_verdi_quicksetup
ltalirz Sep 12, 2017
dbc9f8c
improve comments
ltalirz Sep 12, 2017
0783ce1
switch from --yes to --force
ltalirz Sep 12, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
94 changes: 64 additions & 30 deletions aiida/cmdline/verdilib.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,10 +344,14 @@ class Setup(VerdiCommand):
"""

def run(self, *args):
ctx = _setup_cmd.make_context('setup', list(args))
ctx = self._ctx(args)
with ctx:
_setup_cmd.invoke(ctx)

@staticmethod
def _ctx(args, info_name='verdi setup', **kwargs):
return _setup_cmd.make_context(info_name, list(args), **kwargs)

def complete(self, subargs_idx, subargs):
"""
No completion after 'verdi install'.
Expand All @@ -362,22 +366,23 @@ def complete(self, subargs_idx, subargs):
@click.argument('profile', default='', type=str)
@click.option('--only-config', is_flag=True)
@click.option('--non-interactive', is_flag=True, help='never prompt the user for input, read values from options')
@click.option('--backend', type=click.Choice(['django', 'sqlalchemy']),
help='ignored unless --non-interactive is given')
@click.option('--email', type=str, help='ignored unless --non-interactive is given')
@click.option('--db_host', type=str, help='ignored unless --non-interactive is given')
@click.option('--db_port', type=int, help='ignored unless --non-interactive is given')
@click.option('--db_name', type=str, help='ignored unless --non-interactive is given')
@click.option('--db_user', type=str, help='ignored unless --non-interactive is given')
@click.option('--db_pass', type=str, help='ignored unless --non-interactive is given')
@click.option('--first-name', type=str, help='ignored unless --non-interactive is given')
@click.option('--last-name', type=str, help='ignored unless --non-interactive is given')
@click.option('--institution', type=str, help='ignored unless --non-interactive is given')
@click.option('--no-password', is_flag=True, help='ignored unless --non-interactive is given')
@click.option('--repo', type=str, help='ignored unless --non-interactive is given')
@click.option('--backend', type=click.Choice(['django', 'sqlalchemy']),)
@click.option('--email', type=str)
@click.option('--db_host', type=str)
@click.option('--db_port', type=int)
@click.option('--db_name', type=str)
@click.option('--db_user', type=str)
@click.option('--db_pass', type=str)
@click.option('--first-name', type=str)
@click.option('--last-name', type=str)
@click.option('--institution', type=str)
@click.option('--no-password', is_flag=True)
@click.option('--repo', type=str)
def _setup_cmd(profile, only_config, non_interactive, backend, email, db_host, db_port, db_name, db_user, db_pass,
first_name, last_name, institution, no_password, repo):
'''verdi setup command, forward cmdline arguments to the setup function.'''
'''verdi setup command, forward cmdline arguments to the setup function.

Note: command line options are IGNORED unless --non-interactive is given.'''
setup(profile=profile,
only_config=only_config,
non_interactive=non_interactive,
Expand Down Expand Up @@ -614,9 +619,9 @@ class Quicksetup(VerdiCommand):
'''
Quick setup for the most common usecase (1 user, 1 machine).

Uses click for options. Creates a database user 'aiida_qs_<username>' with random password if it doesn't exist.
Creates a 'aiidadb_qs_<username>' database (prompts to use or change the name if already exists).
Makes sure not to overwrite existing databases or profiles without prompting for confirmation.
Creates a database user 'aiida_qs_<login-name>' with random password (if it
doesn't exist). Creates a database '<profile>_<username>' (if it exists,
prompts user to use or change the name).
'''
from aiida.backends.profile import (BACKEND_DJANGO, BACKEND_SQLA)

Expand All @@ -626,11 +631,15 @@ class Quicksetup(VerdiCommand):
_get_users_command = "SELECT usename FROM pg_user WHERE usename='{}'"

def run(self, *args):
ctx = self._quicksetup_cmd.make_context('quicksetup', list(args))
ctx = self._ctx(args)
with ctx:
ctx.obj = self
self._quicksetup_cmd.invoke(ctx)

@staticmethod
def _ctx(args, info_name='verdi quicksetup', **kwargs):
return Quicksetup._quicksetup_cmd.make_context(info_name, list(args), **kwargs)

def _get_pg_access(self):
'''
find out how postgres can be accessed.
Expand Down Expand Up @@ -706,8 +715,10 @@ def _prompt_db_info(self):
click.echo('Unable to connect to postgres, please try again')
return dbinfo


@click.command('quicksetup', context_settings=CONTEXT_SETTINGS)
@click.option('--email', prompt='Email Address (will be used to identify your data when sharing)', type=str,
@click.option('--profile', prompt='Profile name', type=str, default='quicksetup')
@click.option('--email', prompt='Email Address (identifies your data when sharing)', type=str,
help='This email address will be associated with your data and will be exported along with it, should you choose to share any of your work')
@click.option('--first-name', prompt='First Name', type=str)
@click.option('--last-name', prompt='Last Name', type=str)
Expand All @@ -717,12 +728,11 @@ def _prompt_db_info(self):
@click.option('--db-user', type=str)
@click.option('--db-user-pw', type=str)
@click.option('--db-name', type=str)
@click.option('--profile', type=str)
@click.option('--repo', type=str)
@click.pass_obj
def _quicksetup_cmd(self, email, first_name, last_name, institution, backend, db_port, db_user, db_user_pw, db_name,
profile, repo):
'''setup a sane aiida configuration with as little interaction as possible.'''
'''Set up a sane aiida configuration with as little interaction as possible.'''
from aiida.common.setup import create_base_dirs, AIIDA_CONFIG_FOLDER
create_base_dirs()

Expand All @@ -733,15 +743,18 @@ def _quicksetup_cmd(self, email, first_name, last_name, institution, backend, db
pg_execute = pg_info['method']
dbinfo = pg_info['dbinfo']

# check if a database setup already exists
# otherwise setup the database user aiida
# setup the database aiida_qs_<username>
from getpass import getuser
from aiida.common.setup import generate_random_secret_key
osuser = getuser()
# default database name is <profile>_<login-name>
# this ensures that for profiles named test_... the database will also
# be named test_...
import getpass
osuser = getpass.getuser()
dbname = db_name or profile + '_' + osuser

# default database user name is aiida_qs_<login-name>
# default password is random
dbuser = db_user or 'aiida_qs_' + osuser
from aiida.common.setup import generate_random_secret_key
dbpass = db_user_pw or generate_random_secret_key()
dbname = db_name or 'aiidadb_qs_' + osuser

# check if there is a profile that contains the db user already
# and if yes, take the db user password from there
Expand Down Expand Up @@ -959,6 +972,8 @@ def _check_db_name(self, dbname, method=None, **kwargs):
return dbname, create




class Run(VerdiCommand):
"""
Execute an AiiDA script
Expand Down Expand Up @@ -1155,9 +1170,27 @@ def exec_from_cmdline(argv):

short_doc = {}
long_doc = {}
for k, v in raw_docstrings.iteritems():
for k, cmd in list_commands.iteritems():
if k in hidden_commands:
continue

# assemble help string
# first from python docstring
if cmd.__doc__:
v = cmd.__doc__
else:
v = ""

# if command has parser written with the 'click' module
# we also add a dynamic help string documenting the options
# Note: to enable this for a command, simply add a static
# _ctx method (see e.g. Quicksetup)
if hasattr(cmd, '_ctx'):
v += "\n"
# resilient_parsing suppresses interactive prompts
v += cmd._ctx(args=[], resilient_parsing=True).get_help()
v = v.split('\n') # need list of lines

lines = [l.strip() for l in v]
empty_lines = [bool(l) for l in lines]
try:
Expand All @@ -1170,6 +1203,7 @@ def exec_from_cmdline(argv):
short_doc[k] = lines[first_idx]
long_doc[k] = os.linesep.join(lines[first_idx + 1:])


execname = os.path.basename(argv[0])

try:
Expand Down
4 changes: 2 additions & 2 deletions aiida/common/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -656,8 +656,8 @@ def create_configuration(profile='default'):
# Setting the email
valid_email = False
readline.set_startup_hook(lambda: readline.insert_text(
this_existing_confs.get(DEFAULT_USER_CONFIG_FIELD,
DEFAULT_AIIDA_USER)))
this_existing_confs.get(DEFAULT_AIIDA_USER)))
#this_existing_confs.get(DEFAULT_USER_CONFIG_FIELD,DEFAULT_AIIDA_USER)))
while not valid_email:
this_new_confs[DEFAULT_USER_CONFIG_FIELD] = raw_input(
'Default user email: ')
Expand Down