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

CLI: Various improvements concerning user details #6173

Merged
merged 5 commits into from
Nov 12, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions aiida/cmdline/commands/cmd_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
# For further information please visit http://www.aiida.net #
###########################################################################
"""`verdi user` command."""

from functools import partial

import click
Expand Down Expand Up @@ -58,15 +57,22 @@ def user_list():
"""Show a list of all users."""
from aiida.orm import User

default_user = User.collection.get_default()
table = []

for user in sorted(User.collection.all(), key=lambda user: user.email):
row = ['*' if user.is_default else '', user.email, user.first_name, user.last_name, user.institution]
if user.is_default:
table.append(list(map(echo.highlight_string, row)))
else:
table.append(row)

if default_user is None:
echo.echo_warning('no default user has been configured')
echo.echo_tabulate(table, headers=['', 'Email', 'First name', 'Last name', 'Institution'])
echo.echo('')

attributes = ['email', 'first_name', 'last_name']
sort = lambda user: user.email
highlight = lambda x: x.email == default_user.email if default_user else None
echo.echo_formatted_list(User.collection.all(), attributes, sort=sort, highlight=highlight)
if User.collection.get_default() is None:
echo.echo_warning('No default user has been configured')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious if this ever can happen. One needs to set up a user to set up a profile, and that would immediately set this user as the default. If you haven't set up a profile, you get:

❯ verdi user list
Critical: no default profile defined: None
{'CONFIG_VERSION': {'CURRENT': 9, 'OLDEST_COMPATIBLE': 9}, 'profiles': {}, 'options': {'autofill.user.email': '[email protected]', 'autofill.user.first_name': 'John', 'autofill.user.last_name': 'Doe', 'autofill.user.institution': 'Unknown'}}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is possible. If you delete the user, or you simply change the user's email, or even if the config is corrupted and the default_user_email key is removed. Lot's of possibilities :D

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha, I guess you're right

❯ verdi user list
    Email      First name    Last name    Institution
--  ---------  ------------  -----------  -------------
    mwhahahha  John          Doe          Unknown

Warning: No default user has been configured

But these paths are probably not really desirable, since once you don't have a default user, you can't even store a simple Int node.

Side tangent: I checked out the docstring of the store method, and it thoroughly confused me.

Utter confusion
In [4]: Int(1).store?
Docstring:
Lightweight persistence for python variables.

Example::

  In [1]: l = ['hello',10,'world']
  In [2]: %store l
  Stored 'l' (list)
  In [3]: exit

  (IPython session is closed and started again...)

  ville@badger:~$ ipython
  In [1]: l
  NameError: name 'l' is not defined
  In [2]: %store -r
  In [3]: l
  Out[3]: ['hello', 10, 'world']

Usage:

* ``%store``          - Show list of all variables and their current
                        values
* ``%store spam bar`` - Store the *current* value of the variables spam
                        and bar to disk
* ``%store -d spam``  - Remove the variable and its value from storage
* ``%store -z``       - Remove all variables from storage
* ``%store -r``       - Refresh all variables, aliases and directory history
                        from store (overwrite current vals)
* ``%store -r spam bar`` - Refresh specified variables and aliases from store
                           (delete current val)
* ``%store foo >a.txt``  - Store value of foo to new file a.txt
* ``%store foo >>a.txt`` - Append value of foo to file a.txt

It should be noted that if you change the value of a variable, you
need to %store it again if you want to persist the new value.

Note also that the variables will need to be pickleable; most basic
python types can be safely %store'd.

Also aliases can be %store'd across sessions.
To remove an alias from the storage, use the %unalias magic.
File:      ~/.virtualenvs/tmp/lib/python3.11/site-packages/IPython/extensions/storemagic.py

else:
echo.echo_report('The user highlighted and marked with a * is the default user.')


@verdi_user.command('configure')
Expand Down
12 changes: 12 additions & 0 deletions aiida/cmdline/utils/echo.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ class ExitCode(enum.IntEnum):
}


def highlight_string(string: str, color: str = 'highlight') -> str:
"""Highlight a string with a certain color.

Uses ``click.style`` to highlight the string.

:param string: The string to highlight.
:param color: The color to use.
:returns: The highlighted string.
"""
return click.style(string, fg=COLORS[color])


def echo(message: Any, fg: Optional[str] = None, bold: bool = False, nl: bool = True, err: bool = False) -> None:
"""Log a message to the cmdline logger.

Expand Down