diff --git a/changelog.md b/changelog.md index a96dbf57..242448cb 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,12 @@ Upcoming (TBD) ============== +Features +--------- +* Show purpose in tabular `--checkup` output. +* Add optional dependencies to `--checkup`. + + Documentation --------- * Add `.|` and `.>` to TIPS. diff --git a/mycli/main_modes/checkup.py b/mycli/main_modes/checkup.py index a1b5d18d..551fbf5f 100644 --- a/mycli/main_modes/checkup.py +++ b/mycli/main_modes/checkup.py @@ -6,6 +6,8 @@ import urllib.error import urllib.request +from tabulate import tabulate + from mycli.constants import REPO_URL PYPI_API_BASE = 'https://pypi.org/pypi' @@ -24,15 +26,20 @@ def pypi_api_fetch(fragment: str) -> dict: def _dependencies_checkup() -> None: print('\n### Key Python dependencies:\n') - for dependency in [ - 'cli_helpers', - 'click', - 'prompt_toolkit', - 'pygments', - 'pymysql', - 'sqlglot', - 'sqlglotc', - 'tabulate', + table = [] + for dependency, purpose in [ + ('cli_helpers', 'required'), + ('click', 'required'), + ('prompt_toolkit', 'required'), + ('pygments', 'required'), + ('pymysql', 'required'), + ('sqlglot', 'required'), + ('sqlglotc', 'required'), + ('tabulate', 'required'), + ('llm', 'optional for /llm command'), + ('polars', 'optional for .| operator'), + ('altair', 'optional for .| operator'), + ('vl-convert-python', 'optional for .| operator'), ]: try: installed_version = importlib.metadata.version(dependency) @@ -40,32 +47,38 @@ def _dependencies_checkup() -> None: installed_version = None pypi_profile = pypi_api_fetch(f'/{dependency}/json') latest_version = pypi_profile.get('info', {}).get('version', None) - print(f'{dependency} version {installed_version} (latest {latest_version})') + table.append([dependency, installed_version, latest_version, purpose]) + print(tabulate(table, headers=['library', 'version', 'latest', 'purpose'])) def _executables_checkup() -> None: print('\n### External executables:\n') - for executable in [ - 'less', - 'fzf', - 'pygmentize', + table = [] + for executable, purpose in [ + ('less', 'required for paging'), + ('fzf', r'optional for history search and \x'), + ('pygmentize', 'optional for history search'), ]: + # executable, purpose = external if shutil.which(executable): - print(f'The "{executable}" executable was found — good!') + table.append([executable, 'found', purpose]) else: - print(f'The recommended "{executable}" executable was not found — some functionality will suffer.') + table.append([executable, 'MISSING', purpose]) + print(tabulate(table, headers=['executable', 'status', 'purpose'])) def _environment_checkup() -> None: print('\n### Environment variables:\n') - for variable in [ - 'EDITOR', - 'VISUAL', + table = [] + for variable, purpose in [ + ('EDITOR', r'optional for \edit and C-x C-e'), + ('VISUAL', r'optional for \edit and C-x C-e'), ]: if value := os.environ.get(variable): - print(f'The ${variable} environment variable was set to "{value}" — good!') + table.append([f'${variable}', value, purpose]) else: - print(f'The ${variable} environment variable was not set — some functionality will suffer.') + table.append([f'${variable}', 'UNSET', purpose]) + print(tabulate(table, headers=['variable', 'setting', 'purpose'])) def _configuration_checkup(mycli) -> None: diff --git a/test/pytests/test_checkup.py b/test/pytests/test_checkup.py index c0d65f59..a27e8ef7 100644 --- a/test/pytests/test_checkup.py +++ b/test/pytests/test_checkup.py @@ -50,6 +50,11 @@ def test_dependencies_checkup(monkeypatch, capsys) -> None: 'pygments': '2.19.2', 'sqlglot': '30.7.0', 'sqlglotc': '30.7.0', + 'tabulate': '0.10.0', + 'llm': '0.30', + 'polars': '1.42.1', + 'altair': '6.2.2', + 'vl-convert-python': '1.9.0', } def fake_version(name: str) -> str: @@ -68,11 +73,12 @@ def fake_pypi_api_fetch(fragment: str) -> dict: output = capsys.readouterr().out assert '### Key Python dependencies:' in output - assert 'cli_helpers version 1.0.0 (latest latest-cli_helpers)' in output - assert 'click version 2.0.0 (latest latest-click)' in output - assert 'prompt_toolkit version 3.0.0 (latest latest-prompt_toolkit)' in output - assert 'pymysql version 4.0.0 (latest latest-pymysql)' in output - assert 'tabulate version None (latest latest-tabulate)' in output + rows = [line.split() for line in output.splitlines()] + assert ['cli_helpers', '1.0.0', 'latest-cli_helpers', 'required'] in rows + assert ['click', '2.0.0', 'latest-click', 'required'] in rows + assert ['prompt_toolkit', '3.0.0', 'latest-prompt_toolkit', 'required'] in rows + assert ['pymysql', '4.0.0', 'latest-pymysql', 'required'] in rows + assert ['tabulate', 'latest-tabulate', 'required'] in rows def test_executables_checkup(monkeypatch, capsys) -> None: @@ -86,9 +92,10 @@ def test_executables_checkup(monkeypatch, capsys) -> None: output = capsys.readouterr().out assert '### External executables:' in output - assert 'The "less" executable was found' in output - assert 'The recommended "fzf" executable was not found' in output - assert 'The "pygmentize" executable was found' in output + rows = [line.split() for line in output.splitlines()] + assert ['less', 'found', 'required', 'for', 'paging'] in rows + assert ['fzf', 'MISSING', 'optional', 'for', 'history', 'search', 'and', r'\x'] in rows + assert ['pygmentize', 'found', 'optional', 'for', 'history', 'search'] in rows def test_environment_checkup(monkeypatch, capsys) -> None: @@ -99,8 +106,9 @@ def test_environment_checkup(monkeypatch, capsys) -> None: output = capsys.readouterr().out assert '### Environment variables:' in output - assert 'The $EDITOR environment variable was set to "vim" ' in output - assert 'The $VISUAL environment variable was not set' in output + rows = [line.split() for line in output.splitlines()] + assert ['$EDITOR', 'vim', 'optional', 'for', r'\edit', 'and', 'C-x', 'C-e'] in rows + assert ['$VISUAL', 'UNSET', 'optional', 'for', r'\edit', 'and', 'C-x', 'C-e'] in rows def test_configuration_checkup_missing_file(capsys) -> None: