Skip to content

Commit 69f9bbe

Browse files
committed
move --list-dsn execution path out of main.py
1 parent ba0435f commit 69f9bbe

4 files changed

Lines changed: 132 additions & 14 deletions

File tree

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Internal
3333
* Refactor suggestion logic into declarative rules.
3434
* Factor the `--batch` execution modes out of `main.py`.
3535
* Move `--checkup` logic to the new `main_modes` with `--batch`.
36+
* Move `--list-dsn` logic to the new `main_modes` with `--batch`.
3637
* Sort coverage report in tox suite.
3738
* Skip more tests when a database connection is not present.
3839

mycli/main.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
main_batch_without_progress_bar,
8787
)
8888
from mycli.main_modes.checkup import main_checkup
89+
from mycli.main_modes.list_dsn import main_list_dsn
8990
from mycli.packages import special
9091
from mycli.packages.filepaths import dir_path_exists, guess_socket_location
9192
from mycli.packages.hybrid_redirection import get_redirect_components, is_redirect_command
@@ -2311,20 +2312,7 @@ def get_password_from_file(password_file: str | None) -> str | None:
23112312
)
23122313

23132314
if cli_args.list_dsn:
2314-
try:
2315-
alias_dsn = mycli.config["alias_dsn"]
2316-
except KeyError:
2317-
click.secho("Invalid DSNs found in the config file. Please check the \"[alias_dsn]\" section in myclirc.", err=True, fg="red")
2318-
sys.exit(1)
2319-
except Exception as e:
2320-
click.secho(str(e), err=True, fg="red")
2321-
sys.exit(1)
2322-
for alias, value in alias_dsn.items():
2323-
if cli_args.verbose:
2324-
click.secho(f"{alias} : {value}")
2325-
else:
2326-
click.secho(alias)
2327-
sys.exit(0)
2315+
sys.exit(main_list_dsn(mycli, cli_args))
23282316

23292317
if cli_args.list_ssh_config:
23302318
ssh_config = read_ssh_config(cli_args.ssh_config_path)

mycli/main_modes/list_dsn.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING
4+
5+
import click
6+
7+
if TYPE_CHECKING:
8+
from mycli.main import CliArgs, MyCli
9+
10+
11+
def main_list_dsn(mycli: 'MyCli', cli_args: 'CliArgs') -> int:
12+
try:
13+
alias_dsn = mycli.config['alias_dsn']
14+
except KeyError:
15+
click.secho('Invalid DSNs found in the config file. Please check the "[alias_dsn]" section in myclirc.', err=True, fg='red')
16+
return 1
17+
except Exception as e:
18+
click.secho(str(e), err=True, fg='red')
19+
return 1
20+
for alias, value in alias_dsn.items():
21+
if cli_args.verbose:
22+
click.secho(f'{alias} : {value}')
23+
else:
24+
click.secho(alias)
25+
return 0
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
from __future__ import annotations
2+
3+
from dataclasses import dataclass
4+
from typing import Any, cast
5+
6+
import mycli.main_modes.list_dsn as list_dsn_mode
7+
8+
9+
@dataclass
10+
class DummyCliArgs:
11+
verbose: bool = False
12+
13+
14+
class DummyConfig:
15+
def __init__(self, value: dict[str, str] | Exception) -> None:
16+
self.value = value
17+
18+
def __getitem__(self, key: str) -> dict[str, str]:
19+
assert key == 'alias_dsn'
20+
if isinstance(self.value, Exception):
21+
raise self.value
22+
return self.value
23+
24+
25+
class DummyMyCli:
26+
def __init__(self, config: Any) -> None:
27+
self.config = config
28+
29+
30+
def main_list_dsn(mycli: DummyMyCli, cli_args: DummyCliArgs) -> int:
31+
return list_dsn_mode.main_list_dsn(cast(Any, mycli), cast(Any, cli_args))
32+
33+
34+
def test_main_list_dsn_lists_aliases_without_values(monkeypatch) -> None:
35+
secho_calls: list[tuple[str, bool | None, str | None]] = []
36+
mycli = DummyMyCli(DummyConfig({'prod': 'mysql://u:p@h/db', 'staging': 'mysql://u2:p2@h2/db2'}))
37+
38+
monkeypatch.setattr(
39+
list_dsn_mode.click,
40+
'secho',
41+
lambda message, err=None, fg=None: secho_calls.append((message, err, fg)),
42+
)
43+
44+
result = main_list_dsn(mycli, DummyCliArgs(verbose=False))
45+
46+
assert result == 0
47+
assert secho_calls == [
48+
('prod', None, None),
49+
('staging', None, None),
50+
]
51+
52+
53+
def test_main_list_dsn_lists_aliases_with_values_in_verbose_mode(monkeypatch) -> None:
54+
secho_calls: list[tuple[str, bool | None, str | None]] = []
55+
mycli = DummyMyCli(DummyConfig({'prod': 'mysql://u:p@h/db'}))
56+
57+
monkeypatch.setattr(
58+
list_dsn_mode.click,
59+
'secho',
60+
lambda message, err=None, fg=None: secho_calls.append((message, err, fg)),
61+
)
62+
63+
result = main_list_dsn(mycli, DummyCliArgs(verbose=True))
64+
65+
assert result == 0
66+
assert secho_calls == [('prod : mysql://u:p@h/db', None, None)]
67+
68+
69+
def test_main_list_dsn_reports_invalid_alias_section(monkeypatch) -> None:
70+
secho_calls: list[tuple[str, bool | None, str | None]] = []
71+
mycli = DummyMyCli(DummyConfig(KeyError('alias_dsn')))
72+
73+
monkeypatch.setattr(
74+
list_dsn_mode.click,
75+
'secho',
76+
lambda message, err=None, fg=None: secho_calls.append((message, err, fg)),
77+
)
78+
79+
result = main_list_dsn(mycli, DummyCliArgs())
80+
81+
assert result == 1
82+
assert secho_calls == [
83+
(
84+
'Invalid DSNs found in the config file. Please check the "[alias_dsn]" section in myclirc.',
85+
True,
86+
'red',
87+
)
88+
]
89+
90+
91+
def test_main_list_dsn_reports_other_config_errors(monkeypatch) -> None:
92+
secho_calls: list[tuple[str, bool | None, str | None]] = []
93+
mycli = DummyMyCli(DummyConfig(RuntimeError('boom')))
94+
95+
monkeypatch.setattr(
96+
list_dsn_mode.click,
97+
'secho',
98+
lambda message, err=None, fg=None: secho_calls.append((message, err, fg)),
99+
)
100+
101+
result = main_list_dsn(mycli, DummyCliArgs())
102+
103+
assert result == 1
104+
assert secho_calls == [('boom', True, 'red')]

0 commit comments

Comments
 (0)