Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 6 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Upcoming (TBD)
==============

Features
---------
* Show purpose in tabular `--checkup` output.
* Add optional dependencies to `--checkup`.


Documentation
---------
* Add `.|` and `.>` to TIPS.
Expand Down
55 changes: 34 additions & 21 deletions mycli/main_modes/checkup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -24,48 +26,59 @@ 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)
except importlib.metadata.PackageNotFoundError:
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:
Expand Down
28 changes: 18 additions & 10 deletions test/pytests/test_checkup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand Down
Loading