Repository: krayzpipes/txt-ferret

Issue:
Simplify config override
Using an extra switch to override the default config with a custom config causes confusion. It is easy to dump the existing config and add to it.

- Remove the 'config override' option
- If a user defines a custom configuration, then ONLY values in that custom config can be used.
- For the time being, require the custom config to have all the same settings as the default config.

Comments:

Patch:
diff --git a/README.md b/README.md
index 04d548a..1725ebe 100644
--- a/README.md
+++ b/README.md
@@ -303,6 +303,9 @@ sanity check which can be paired with a DLP solution. Here are some things it wa
 
 ## Releases
 
+#### Version 0.1.0 - 2019-07-30
+- Removed the `config-override` option
+
 #### Version 0.0.4 - 2019-06-09
 - Added bulk file scanning by the `--bulk` switch.
 - Added multiprocessing for bulk scanning.
diff --git a/setup.py b/setup.py
index c16247c..85ebb7f 100644
--- a/setup.py
+++ b/setup.py
@@ -14,7 +14,7 @@ from setuptools import setup, find_packages
 from codecs import open
 from os import path
 
-__version__ = "0.0.4"
+__version__ = "0.1.0"
 description = "Scan text files for sensitive (or non-sensitive) data."
 
 here = path.abspath(path.dirname(__file__))
diff --git a/src/txtferret/_config.py b/src/txtferret/_config.py
index f8c1723..5a8ce23 100644
--- a/src/txtferret/_config.py
+++ b/src/txtferret/_config.py
@@ -46,7 +46,7 @@ def _load_default_config(config_string=None):
     return yaml.safe_load(default_yaml_config)
 
 
-def load_config(yaml_file=None, default_override=False, config_=None):
+def load_config(yaml_file=None, config_=None, user_config_func=None):
     """Return dict containing config YAML file content.
 
     If not YAML file is explicitly passed as an argument, this function
@@ -54,51 +54,30 @@ def load_config(yaml_file=None, default_override=False, config_=None):
     config file.
 
     :param yaml_file: YAMl file name containing config information.
-    :param default_override: If set to 'True', this will result in
-        the final returned config dict containing only user-defined
-        filters. The defaults will be completely overridden.
     :param config_: Used for tests.
 
     :return: dict with the final configuration.
     """
     # Load the default config as the final config, we will make
     # adjustments as we look at the user-defined config.
-    working_config = config_ or _load_default_config()
 
-    # Return default config if no file is defined by user or settings
-    # introduced through CLI switches.
     if yaml_file is None:
-        return working_config
-
-    # Mix in the user config if present and return it.
-    # If default_override is True, we should return filters ONLY
-    # defined by the user.
-    return _add_user_config_file(
-        config_=working_config, yaml_file=yaml_file, default_override=default_override
-    )
-
-
-def _add_user_config_file(
-    config_=None,
-    yaml_file=None,
-    default_override=None,
-    _user_config=None,
-    validator=None,
-):
-    """Return dict containing default config + user defined config.
+        default_config = config_ or _load_default_config()
+        return default_config
+
+    _user_config_load = user_config_func or _get_user_config_file
+
+    return _user_config_load(yaml_file=yaml_file)
 
-    If default_override is set to 'True', then only return the
-    user-defined filters.
 
-    :param config_: dict containing config file content.
+def _get_user_config_file(yaml_file=None, _user_config=None, validator=None):
+    """Return dict containing default config + user defined config.
+
     :param yaml_file: File name of user-defined configuration.
-    :param default_override: If set to True, will only return filters
-        defined by the user. Default filters will not be returned.
     :param _user_config: Configuration used for tests.
     :param validator: Used to pass in validation stubs during tests.
 
-    :return: dict containing the default + user + cli-defined
-        configuration.
+    :return: dict containing the user-defined configuration file.
     """
     user_defined_config = _user_config or _load_config(yaml_file)
 
@@ -106,20 +85,7 @@ def _add_user_config_file(
 
     _validator(user_defined_config)
 
-    if "filters" in user_defined_config:
-        if default_override:
-            # Remove default filters completely.
-            config_["filters"] = user_defined_config["filters"]
-        else:
-            # Add user filters to default filters.
-            for filter_ in user_defined_config["filters"]:
-                config_["filters"].append(filter_)
-
-    if "settings" in user_defined_config:
-        for key, value in user_defined_config["settings"].items():
-            config_["settings"][key] = value
-
-    return config_
+    return user_defined_config
 
 
 def save_config(data, file_name):
diff --git a/src/txtferret/cli.py b/src/txtferret/cli.py
index 59b76c8..a13eecd 100644
--- a/src/txtferret/cli.py
+++ b/src/txtferret/cli.py
@@ -57,8 +57,7 @@ def prep_config(loader=None, **cli_kwargs):
     """Return a final config file to be sent to TxtFerret."""
     _loader = loader or load_config
     file_name = cli_kwargs["config_file"]
-    override = cli_kwargs["config_override"]
-    config = _loader(yaml_file=file_name, default_override=override)
+    config = _loader(yaml_file=file_name)
     config["cli_kwargs"] = {**cli_kwargs}
     return config
 
@@ -150,12 +149,6 @@ def cli():
 @click.option(
     "--config-file", "-c", default=None, help="Load user-defined config file."
 )
-@click.option(
-    "--config-override",
-    "-co",
-    is_flag=True,
-    help="Delete default filters and only use user-defined filters from config file.",
-)
 @click.option(
     "--delimiter",
     "-d",


Test patch:
diff --git a/tests/_config/test_config.py b/tests/_config/test_config.py
index f4822fb..657f63e 100644
--- a/tests/_config/test_config.py
+++ b/tests/_config/test_config.py
@@ -6,7 +6,7 @@ from txtferret._config import (
     _load_config,
     _load_default_config,
     load_config,
-    _add_user_config_file,
+    _get_user_config_file,
     save_config,
     subset_check,
     validate_config,
@@ -15,6 +15,7 @@ from txtferret._config import (
 
 # Test _load_default_config function
 
+
 def test_load_default_config():
     config_string = """
     settings:
@@ -30,6 +31,28 @@ def test_load_default_config():
 # TODO: test _load_config
 
 
+def test_load_config_no_custom_config():
+    def stub_func(yaml_file=None):
+        return {"dont": "return_me"}
+
+    rv = load_config(
+        yaml_file=None, config_={"mytest": "config"}, user_config_func=stub_func
+    )
+
+    assert {"mytest": "config"} == rv, "dict should be the same"
+
+
+def test_load_config_return_custom_config():
+    def stub_func(yaml_file=None):
+        return {"my": "config"}
+
+    jv = load_config(
+        yaml_file="something", config_={"dont": "return_me"}, user_config_func=stub_func
+    )
+
+    assert {"my": "config"} == jv, "returned the wrong dict"
+
+
 @pytest.fixture(scope="module")
 def user_config():
     config = {
@@ -55,7 +78,7 @@ def user_config():
 
 
 @pytest.fixture(scope="module")
-def default_config():
+def custom_config():
     config = {
         "filters": [
             {
@@ -78,7 +101,7 @@ def default_config():
     return config
 
 
-# Test _add_user_config_file function
+# Test _get_user_config_file function
 
 
 @pytest.fixture(scope="module")
@@ -97,83 +120,25 @@ def validator_raise():
     return validator_func
 
 
-def test_add_user_config_file_no_user_config(default_config, validator_true):
-    config_copy = copy.deepcopy(default_config)
-    rv = _add_user_config_file(
-        config_=config_copy,
+def test_get_user_config_file_valid(validator_true):
+    rv = _get_user_config_file(
         yaml_file=None,
-        default_override=False,
-        _user_config={"fake_key", "fake_value"},
+        _user_config={"fake_key": "fake_value"},
         validator=validator_true,
     )
-    assert default_config == rv, "Dicts should be the same."
+    assert {"fake_key": "fake_value"} == rv, "Dicts should be the same."
 
 
-def test_add_user_config_file_default_override_with_user_config(
-    default_config, user_config, validator_true
-):
-    config_copy = copy.deepcopy(default_config)
-    expected_config = copy.deepcopy(default_config)
-    expected_config["filters"] = copy.deepcopy(user_config["filters"])
-    rv = _add_user_config_file(
-        config_=config_copy,
-        yaml_file=None,
-        default_override=True,
-        _user_config=user_config,
-        validator=validator_true,
-    )
-    assert (
-        expected_config["filters"] == rv["filters"]
-    ), "Expected default filters to be replaced by user-defined filters."
-    assert expected_config == rv, "Only the filters should have been changed."
-
-
-def test_add_user_config_file_no_default_override_with_user_config(
-    default_config, user_config, validator_true
-):
-    config_copy = copy.deepcopy(default_config)
-    expected_config = copy.deepcopy(default_config)
-    user_filters = copy.deepcopy(user_config["filters"])
-    expected_config["filters"] += user_filters
-    rv = _add_user_config_file(
-        config_=config_copy,
-        yaml_file=None,
-        default_override=False,
-        _user_config=user_config,
-        validator=validator_true,
-    )
-    assert (
-        expected_config["filters"] == rv["filters"]
-    ), "Expected both default and user filters in the final dict."
-    assert expected_config == rv, "Only the filters should have been changed."
-
-
-def test_add_user_config_file_change_settings(validator_true):
-    original_config = {"settings": {"key_1": "original_value_1"}}
-    user_config= {"settings": {"key_1": "user_value_1"}}
-    rv = _add_user_config_file(
-        config_=original_config,
-        yaml_file=None,
-        default_override=False,
-        _user_config=user_config,
-        validator=validator_true,
-    )
-    assert original_config == user_config, "Expected user settings to override default."
-
-
-def test_add_user_config_file_validation_failed(validator_raise):
+def test_get_user_config_file_validation_failed(validator_raise):
     with pytest.raises(ValueError):
-        _ = _add_user_config_file(
-            config_={"key": "value"},
-            yaml_file=None,
-            default_override=False,
-            _user_config={"who": "cares"},
-            validator=validator_raise,
+        _ = _get_user_config_file(
+            yaml_file=None, _user_config={"who": "cares"}, validator=validator_raise
         )
 
 
 # Testing the subset_check function
 
+
 def test_subset_check_it_is_subset():
     rv = subset_check(subset={"hello"}, set_={"hello", "world"})
     assert rv == True, "Return value should be True."
@@ -194,4 +159,4 @@ def test_subset_check_is_not_subset():
 
 # Test validate_config function
 
-# TODO: continue writing tests.
\ No newline at end of file
+# TODO: continue writing tests.
diff --git a/tests/cli/test_cli.py b/tests/cli/test_cli.py
index bd0137e..5e2c62f 100644
--- a/tests/cli/test_cli.py
+++ b/tests/cli/test_cli.py
@@ -1,50 +1,29 @@
-
 from txtferret.cli import prep_config, bootstrap, get_totals
 
 
 def test_prep_config():
+    def stub_loader(yaml_file=None):
+        return {"yaml_file": yaml_file}
 
-    def stub_loader(yaml_file=None, default_override=False):
-        return {
-            "yaml_file": yaml_file,
-            "config_override": default_override,
-        }
-
-    fake_cli_kwargs = {
-        "config_file": "my_test_file",
-        "config_override": True,
-    }
+    fake_cli_kwargs = {"config_file": "my_test_file"}
 
-    final_config = {
-        "cli_kwargs": {**fake_cli_kwargs},
-        "yaml_file": "my_test_file",
-        "config_override": True,
-    }
+    final_config = {"cli_kwargs": {**fake_cli_kwargs}, "yaml_file": "my_test_file"}
 
     assert prep_config(loader=stub_loader, **fake_cli_kwargs) == final_config
 
 
 def test_bootstrap():
-
     class StubClass:
         def __init__(self, _config):
             pass
+
         def scan_file(self):
             pass
+
         def summary(self):
-            return {
-                "file_name": "hello.txt",
-                "failures": 5,
-                "passes": 5,
-                "time": 28,
-            }
-
-    expected = {
-        "file_name": "hello.txt",
-        "failures": 5,
-        "passes": 5,
-        "time": 28,
-    }
+            return {"file_name": "hello.txt", "failures": 5, "passes": 5, "time": 28}
+
+    expected = {"file_name": "hello.txt", "failures": 5, "passes": 5, "time": 28}
 
     config = None
 
@@ -52,9 +31,6 @@ def test_bootstrap():
 
 
 def test_get_totals():
-    results = [
-        {"failures": 2, "passes": 5},
-        {"failures": 3, "passes": 10},
-    ]
+    results = [{"failures": 2, "passes": 5}, {"failures": 3, "passes": 10}]
 
     assert get_totals(results) == (5, 15)