For boolean configuration options, add separate "--foo" and "--no-foo" CLI flags (#303).

This commit is contained in:
Dan Helfman
2025-04-02 17:08:04 -07:00
parent 9301ab13cc
commit bbf6f27715
6 changed files with 86 additions and 117 deletions
+40 -53
View File
@@ -1121,7 +1121,7 @@ def test_add_arguments_from_schema_with_array_and_nested_object_adds_multiple_fl
)
def test_add_arguments_from_schema_with_default_false_boolean_adds_valueless_flag():
def test_add_arguments_from_schema_with_boolean_adds_two_valueless_flags():
arguments_group = flexmock()
flexmock(module).should_receive('make_argument_description').and_return('help')
flexmock(module.borgmatic.config.schema).should_receive('parse_type').and_return(bool)
@@ -1131,59 +1131,12 @@ def test_add_arguments_from_schema_with_default_false_boolean_adds_valueless_fla
default=None,
help='help',
).once()
flexmock(module).should_receive('add_array_element_arguments')
module.add_arguments_from_schema(
arguments_group=arguments_group,
schema={
'type': 'object',
'properties': {
'foo': {
'type': 'boolean',
'default': False,
}
},
},
unparsed_arguments=(),
)
def test_add_arguments_from_schema_with_default_true_boolean_adds_value_flag():
arguments_group = flexmock()
flexmock(module).should_receive('make_argument_description').and_return('help')
flexmock(module.borgmatic.config.schema).should_receive('parse_type').and_return(bool)
arguments_group.should_receive('add_argument').with_args(
'--foo',
type=bool,
metavar='FOO',
help='help',
).once()
flexmock(module).should_receive('add_array_element_arguments')
module.add_arguments_from_schema(
arguments_group=arguments_group,
schema={
'type': 'object',
'properties': {
'foo': {
'type': 'boolean',
'default': True,
}
},
},
unparsed_arguments=(),
)
def test_add_arguments_from_schema_with_defaultless_boolean_adds_value_flag():
arguments_group = flexmock()
flexmock(module).should_receive('make_argument_description').and_return('help')
flexmock(module.borgmatic.config.schema).should_receive('parse_type').and_return(bool)
arguments_group.should_receive('add_argument').with_args(
'--foo',
type=bool,
metavar='FOO',
help='help',
'--no-foo',
dest='foo',
action='store_false',
default=None,
help=object,
).once()
flexmock(module).should_receive('add_array_element_arguments')
@@ -1201,6 +1154,40 @@ def test_add_arguments_from_schema_with_defaultless_boolean_adds_value_flag():
)
def test_add_arguments_from_schema_with_nested_boolean_adds_two_valueless_flags():
arguments_group = flexmock()
flexmock(module).should_receive('make_argument_description').and_return('help')
flexmock(module.borgmatic.config.schema).should_receive('parse_type').and_return(bool)
arguments_group.should_receive('add_argument').with_args(
'--foo.bar.baz-quux',
action='store_true',
default=None,
help='help',
).once()
arguments_group.should_receive('add_argument').with_args(
'--foo.bar.no-baz-quux',
dest='foo.bar.baz_quux',
action='store_false',
default=None,
help=object,
).once()
flexmock(module).should_receive('add_array_element_arguments')
module.add_arguments_from_schema(
arguments_group=arguments_group,
schema={
'type': 'object',
'properties': {
'baz_quux': {
'type': 'boolean',
}
},
},
unparsed_arguments=(),
names=('foo', 'bar'),
)
def test_add_arguments_from_schema_skips_omitted_flag_name():
arguments_group = flexmock()
flexmock(module).should_receive('make_argument_description').and_return('help')
+25 -17
View File
@@ -44,19 +44,23 @@ def test_interactive_console_true_when_isatty_and_TERM_is_not_dumb(capsys):
assert module.interactive_console() is True
def test_should_do_markup_respects_no_color_value():
flexmock(module.os.environ).should_receive('get').and_return(None)
def test_should_do_markup_respects_json_enabled_value():
flexmock(module.os.environ).should_receive('get').never()
flexmock(module).should_receive('interactive_console').never()
assert module.should_do_markup(no_color=True, configs={}) is False
assert module.should_do_markup(configs={}, json_enabled=True) is False
def test_should_do_markup_respects_config_value():
flexmock(module.os.environ).should_receive('get').and_return(None)
flexmock(module).should_receive('interactive_console').never()
assert module.should_do_markup(no_color=False, configs={'foo.yaml': {'color': False}}) is False
assert (
module.should_do_markup(configs={'foo.yaml': {'color': False}}, json_enabled=False) is False
)
flexmock(module).should_receive('interactive_console').and_return(True).once()
assert module.should_do_markup(no_color=False, configs={'foo.yaml': {'color': True}}) is True
assert (
module.should_do_markup(configs={'foo.yaml': {'color': True}}, json_enabled=False) is True
)
def test_should_do_markup_prefers_any_false_config_value():
@@ -65,11 +69,11 @@ def test_should_do_markup_prefers_any_false_config_value():
assert (
module.should_do_markup(
no_color=False,
configs={
'foo.yaml': {'color': True},
'bar.yaml': {'color': False},
},
json_enabled=False,
)
is False
)
@@ -83,14 +87,16 @@ def test_should_do_markup_respects_PY_COLORS_environment_variable():
flexmock(module).should_receive('to_bool').and_return(True)
assert module.should_do_markup(no_color=False, configs={}) is True
assert module.should_do_markup(configs={}, json_enabled=False) is True
def test_should_do_markup_prefers_no_color_value_to_config_value():
def test_should_do_markup_prefers_json_enabled_value_to_config_value():
flexmock(module.os.environ).should_receive('get').and_return(None)
flexmock(module).should_receive('interactive_console').never()
assert module.should_do_markup(no_color=True, configs={'foo.yaml': {'color': True}}) is False
assert (
module.should_do_markup(configs={'foo.yaml': {'color': True}}, json_enabled=True) is False
)
def test_should_do_markup_prefers_config_value_to_environment_variables():
@@ -98,7 +104,9 @@ def test_should_do_markup_prefers_config_value_to_environment_variables():
flexmock(module).should_receive('to_bool').and_return(True)
flexmock(module).should_receive('interactive_console').never()
assert module.should_do_markup(no_color=False, configs={'foo.yaml': {'color': False}}) is False
assert (
module.should_do_markup(configs={'foo.yaml': {'color': False}}, json_enabled=False) is False
)
def test_should_do_markup_prefers_no_color_value_to_environment_variables():
@@ -106,14 +114,14 @@ def test_should_do_markup_prefers_no_color_value_to_environment_variables():
flexmock(module).should_receive('to_bool').and_return(True)
flexmock(module).should_receive('interactive_console').never()
assert module.should_do_markup(no_color=True, configs={}) is False
assert module.should_do_markup(configs={}, json_enabled=False) is False
def test_should_do_markup_respects_interactive_console_value():
flexmock(module.os.environ).should_receive('get').and_return(None)
flexmock(module).should_receive('interactive_console').and_return(True)
assert module.should_do_markup(no_color=False, configs={}) is True
assert module.should_do_markup(configs={}, json_enabled=False) is True
def test_should_do_markup_prefers_PY_COLORS_to_interactive_console_value():
@@ -124,7 +132,7 @@ def test_should_do_markup_prefers_PY_COLORS_to_interactive_console_value():
flexmock(module).should_receive('to_bool').and_return(True)
flexmock(module).should_receive('interactive_console').never()
assert module.should_do_markup(no_color=False, configs={}) is True
assert module.should_do_markup(configs={}, json_enabled=False) is True
def test_should_do_markup_prefers_NO_COLOR_to_interactive_console_value():
@@ -132,7 +140,7 @@ def test_should_do_markup_prefers_NO_COLOR_to_interactive_console_value():
flexmock(module.os.environ).should_receive('get').with_args('NO_COLOR', None).and_return('True')
flexmock(module).should_receive('interactive_console').never()
assert module.should_do_markup(no_color=False, configs={}) is False
assert module.should_do_markup(configs={}, json_enabled=False) is False
def test_should_do_markup_respects_NO_COLOR_environment_variable():
@@ -140,7 +148,7 @@ def test_should_do_markup_respects_NO_COLOR_environment_variable():
flexmock(module.os.environ).should_receive('get').with_args('PY_COLORS', None).and_return(None)
flexmock(module).should_receive('interactive_console').never()
assert module.should_do_markup(no_color=False, configs={}) is False
assert module.should_do_markup(configs={}, json_enabled=False) is False
def test_should_do_markup_ignores_empty_NO_COLOR_environment_variable():
@@ -148,7 +156,7 @@ def test_should_do_markup_ignores_empty_NO_COLOR_environment_variable():
flexmock(module.os.environ).should_receive('get').with_args('PY_COLORS', None).and_return(None)
flexmock(module).should_receive('interactive_console').and_return(True)
assert module.should_do_markup(no_color=False, configs={}) is True
assert module.should_do_markup(configs={}, json_enabled=False) is True
def test_should_do_markup_prefers_NO_COLOR_to_PY_COLORS():
@@ -160,7 +168,7 @@ def test_should_do_markup_prefers_NO_COLOR_to_PY_COLORS():
)
flexmock(module).should_receive('interactive_console').never()
assert module.should_do_markup(no_color=False, configs={}) is False
assert module.should_do_markup(configs={}, json_enabled=False) is False
def test_multi_stream_handler_logs_to_handler_for_log_level():