Skip to content

Commit 388a872

Browse files
committed
accept true/false for ssl_mode, keeping on/off
More liberally accept true/false/on/off (and capitalization variants) for --ssl_mode. Some inconsistencies in the interface have crept in as features were added. Some settings from ~/.myclirc especially, but also in the CLI arguments, use str_to_bool() for liberal boolean parsing. Other settings, such as --ssl_mode, are using on/off only. Other settings, such as --use_keyring, are using true/false only. This change is a step towards converging all boolean settings on liberal str_to_bool(). It should ultimately include DSN query parameters, too. The "auto" value for ssl_mode is still special-cased, and not affected by these changes. The only loss is that click doesn't automatically display the choices in the helpdoc, but they are already listed in the description. We keep the description targeted to on/off, and only silently accept the other variants.
1 parent a447c48 commit 388a872

5 files changed

Lines changed: 71 additions & 3 deletions

File tree

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Features
1010
* Let `help <keyword>` list similar keywords when not found.
1111
* Optionally highlight fuzzy search previews.
1212
* Make `\edit` synonymous with the `\e` command.
13+
* More liberally accept `on`/`off` values for `true`/`false`, and vice versa.
1314

1415

1516
Bug Fixes

mycli/config.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,13 @@ def str_to_bool(s: str | bool) -> bool:
305305
raise ValueError(f'not a recognized boolean value: {s}')
306306

307307

308+
def str_to_on_off(s: str | bool) -> str:
309+
bool_str = str(str_to_bool(s))
310+
if bool_str == 'True':
311+
return 'on'
312+
return 'off'
313+
314+
308315
def strip_matching_quotes(s: str) -> str:
309316
"""Remove matching, surrounding quotes from a string.
310317

mycli/main.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,15 @@
5858
from mycli.clitoolbar import create_toolbar_tokens_func
5959
from mycli.compat import WIN
6060
from mycli.completion_refresher import CompletionRefresher
61-
from mycli.config import get_mylogin_cnf_path, open_mylogin_cnf, read_config_files, str_to_bool, strip_matching_quotes, write_default_config
61+
from mycli.config import (
62+
get_mylogin_cnf_path,
63+
open_mylogin_cnf,
64+
read_config_files,
65+
str_to_bool,
66+
str_to_on_off,
67+
strip_matching_quotes,
68+
write_default_config,
69+
)
6270
from mycli.constants import ISSUES_URL
6371
from mycli.key_bindings import mycli_bindings
6472
from mycli.lexer import MyCliLexer
@@ -226,7 +234,9 @@ def __init__(
226234

227235
# set ssl_mode if a valid option is provided in a config file, otherwise None
228236
ssl_mode = c["main"].get("ssl_mode", None) or c["connection"].get("default_ssl_mode", None)
229-
if ssl_mode not in ("auto", "on", "off", None):
237+
if ssl_mode is None:
238+
self.ssl_mode = ssl_mode
239+
elif ssl_mode.lower() not in ("auto", "on", "off", "1", "0", "true", "false"):
230240
self.echo(f"Invalid config option provided for ssl_mode ({ssl_mode}); ignoring.", err=True, fg="red")
231241
self.ssl_mode = None
232242
else:
@@ -1720,7 +1730,7 @@ def get_last_query(self) -> str | None:
17201730
"--ssl-mode",
17211731
"ssl_mode",
17221732
help="Set desired SSL behavior. auto=preferred if TCP/IP, on=required, off=off.",
1723-
type=click.Choice(["auto", "on", "off"]),
1733+
type=str,
17241734
)
17251735
@click.option("--ssl/--no-ssl", "ssl_enable", default=None, help="Enable SSL for connection (automatically enabled with other flags).")
17261736
@click.option("--ssl-ca", help="CA file in PEM format.", type=click.Path(exists=True))
@@ -2080,6 +2090,14 @@ def get_password_from_file(password_file: str | None) -> str | None:
20802090

20812091
keepalive_ticks = keepalive_ticks if keepalive_ticks is not None else mycli.default_keepalive_ticks
20822092
ssl_mode = ssl_mode or mycli.ssl_mode # cli option or config option
2093+
if ssl_mode:
2094+
ssl_mode = ssl_mode.lower()
2095+
if ssl_mode and ssl_mode != 'auto':
2096+
try:
2097+
ssl_mode = str_to_on_off(ssl_mode)
2098+
except ValueError:
2099+
click.secho('Unknown value for ssl_mode', err=True, fg='red')
2100+
sys.exit(1)
20832101

20842102
# if there is a mismatch between the ssl_mode value and other sources of ssl config, show a warning
20852103
# specifically using "is False" to not pickup the case where ssl_enable is None (not set by the user)

test/test_config.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
read_and_decrypt_mylogin_cnf,
1717
read_config_file,
1818
str_to_bool,
19+
str_to_on_off,
1920
strip_matching_quotes,
2021
)
2122

@@ -149,6 +150,25 @@ def test_str_to_bool():
149150
str_to_bool(None)
150151

151152

153+
def test_str_to_on_off():
154+
assert str_to_on_off(False) == 'off'
155+
assert str_to_on_off(True) == 'on'
156+
assert str_to_on_off("False") == 'off'
157+
assert str_to_on_off("True") == 'on'
158+
assert str_to_on_off("TRUE") == 'on'
159+
assert str_to_on_off("1") == 'on'
160+
assert str_to_on_off("0") == 'off'
161+
assert str_to_on_off("on") == 'on'
162+
assert str_to_on_off("off") == 'off'
163+
assert str_to_on_off("off") == 'off'
164+
165+
with pytest.raises(ValueError):
166+
str_to_on_off("foo")
167+
168+
with pytest.raises(TypeError):
169+
str_to_on_off(None)
170+
171+
152172
def test_read_config_file_list_values_default():
153173
"""Test that reading a config file uses list_values by default."""
154174

test/test_main.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,17 @@ def test_ssl_mode_on(executor, capsys):
156156
assert ssl_cipher
157157

158158

159+
@dbtest
160+
def test_ssl_mode_true(executor, capsys):
161+
runner = CliRunner()
162+
ssl_mode = 'true'
163+
sql = 'select * from performance_schema.session_status where variable_name = "Ssl_cipher"'
164+
result = runner.invoke(cli, args=CLI_ARGS + ['--csv', '--ssl-mode', ssl_mode], input=sql)
165+
result_dict = next(csv.DictReader(result.stdout.split('\n')))
166+
ssl_cipher = result_dict.get('VARIABLE_VALUE', None)
167+
assert ssl_cipher
168+
169+
159170
@dbtest
160171
def test_ssl_mode_auto(executor, capsys):
161172
runner = CliRunner()
@@ -178,6 +189,17 @@ def test_ssl_mode_off(executor, capsys):
178189
assert not ssl_cipher
179190

180191

192+
@dbtest
193+
def test_ssl_mode_false(executor, capsys):
194+
runner = CliRunner()
195+
ssl_mode = 'False'
196+
sql = 'select * from performance_schema.session_status where variable_name = "Ssl_cipher"'
197+
result = runner.invoke(cli, args=CLI_ARGS + ['--csv', '--ssl-mode', ssl_mode], input=sql)
198+
result_dict = next(csv.DictReader(result.stdout.split('\n')))
199+
ssl_cipher = result_dict.get('VARIABLE_VALUE', None)
200+
assert not ssl_cipher
201+
202+
181203
@dbtest
182204
def test_ssl_mode_overrides_ssl(executor, capsys):
183205
runner = CliRunner()

0 commit comments

Comments
 (0)