From 9901ccd538b4a6b911e7563179fc8d69d53b3a8a Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 28 Feb 2021 17:01:30 -0500 Subject: [PATCH] Defer config_override unpacking to dict *after* base config is loaded store cli overrides without unpacking just yet move deserialize_config_args to config module delete custom Action class for config operations apply [k,v] -> {k, v} for each override update test data update import --- jrnl/args.py | 37 +------------------------------------ jrnl/config.py | 23 +++++++++++++++++++++++ jrnl/override.py | 3 ++- tests/test_override.py | 10 +++++----- tests/test_parse_args.py | 12 ++++++------ 5 files changed, 37 insertions(+), 48 deletions(-) diff --git a/jrnl/args.py b/jrnl/args.py index 061ba192..c8bd7743 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -4,8 +4,6 @@ import argparse import re import textwrap -import yaml -from yaml.loader import FullLoader from .commands import postconfig_decrypt from .commands import postconfig_encrypt @@ -18,39 +16,6 @@ from .plugins import EXPORT_FORMATS from .plugins import IMPORT_FORMATS from .plugins import util -YAML_SEPARATOR = ": " - - -def deserialize_config_args(input: list) -> dict: - - """ - - Convert a two-element list of configuration key-value pair into a flat dict - - :param input: list of configuration keys in dot-notation and their respective values. - :type input: list - :return: A single level dict of the configuration keys in dot-notation and their respective desired values - :rtype: dict - """ - - assert len(input) == 2 - - # yaml compatible strings are of the form Key:Value - yamlstr = YAML_SEPARATOR.join(input) - runtime_modifications = yaml.load(yamlstr, Loader=FullLoader) - - return runtime_modifications - - -class ConfigurationAction(argparse.Action): - def __init__(self, **kwargs) -> None: - super().__init__(**kwargs) - - def __call__(self, parser, namespace, values, option_strings=None) -> None: - cfg_overrides = getattr(namespace, self.dest, []) - cfg_overrides.append(deserialize_config_args(values)) - setattr(namespace, self.dest, cfg_overrides) - class WrappingFormatter(argparse.RawTextHelpFormatter): """Used in help screen""" @@ -356,7 +321,7 @@ def parse_args(args=[]): config_overrides.add_argument( "--config-override", dest="config_override", - action=ConfigurationAction, + action="append", type=str, nargs=2, default=[], diff --git a/jrnl/config.py b/jrnl/config.py index a5a1d1cc..7d8539c7 100644 --- a/jrnl/config.py +++ b/jrnl/config.py @@ -19,6 +19,29 @@ XDG_RESOURCE = "jrnl" DEFAULT_JOURNAL_NAME = "journal.txt" DEFAULT_JOURNAL_KEY = "default" +YAML_SEPARATOR = ": " + + +def deserialize_config_args(input: list) -> dict: + + """ + + Convert a two-element list of configuration key-value pair into a flat dict + + :param input: list of configuration keys in dot-notation and their respective values. + :type input: list + :return: A single level dict of the configuration keys in dot-notation and their respective desired values + :rtype: dict + """ + + assert len(input) == 2 + + # yaml compatible strings are of the form Key:Value + yamlstr = YAML_SEPARATOR.join(input) + runtime_modifications = yaml.load(yamlstr, Loader=yaml.FullLoader) + + return runtime_modifications + def save_config(config): config["version"] = __version__ diff --git a/jrnl/override.py b/jrnl/override.py index 8852d511..3d60513c 100644 --- a/jrnl/override.py +++ b/jrnl/override.py @@ -1,4 +1,4 @@ -from .config import update_config +from .config import update_config, deserialize_config_args # import logging def apply_overrides(overrides: list, base_config: dict) -> dict: @@ -14,6 +14,7 @@ def apply_overrides(overrides: list, base_config: dict) -> dict: cfg_with_overrides = base_config.copy() for pairs in overrides: + pairs = deserialize_config_args(pairs) key_as_dots, override_value = _get_key_and_value_from_pair(pairs) keys = _convert_dots_to_list(key_as_dots) cfg_with_overrides = _recursively_apply( diff --git a/tests/test_override.py b/tests/test_override.py index 6f99c17f..32ec0595 100644 --- a/tests/test_override.py +++ b/tests/test_override.py @@ -21,13 +21,13 @@ def minimal_config(): def test_apply_override(minimal_config): - overrides = [{"editor": "nano"}] + overrides = [["editor", "nano"]] apply_overrides(overrides, minimal_config) assert minimal_config["editor"] == "nano" def test_override_dot_notation(minimal_config): - overrides = [{"colors.body": "blue"}] + overrides = [["colors.body", "blue"]] cfg = apply_overrides(overrides=overrides, base_config=minimal_config) assert cfg["colors"] == {"body": "blue", "date": "green"} @@ -35,9 +35,9 @@ def test_override_dot_notation(minimal_config): def test_multiple_overrides(minimal_config): overrides = [ - {"colors.title": "magenta"}, - {"editor": "nano"}, - {"journals.burner": "/tmp/journals/burner.jrnl"}, + ["colors.title", "magenta"], + ["editor", "nano"], + ["journals.burner", "/tmp/journals/burner.jrnl"], ] # as returned by parse_args, saved in parser.config_override cfg = apply_overrides(overrides, minimal_config) diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index 2ce0b6a9..a97fa511 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -3,7 +3,7 @@ import shlex import pytest from jrnl.args import parse_args -from jrnl.args import deserialize_config_args +from jrnl.config import deserialize_config_args def cli_as_dict(str): @@ -210,12 +210,12 @@ def test_version_alone(): def test_editor_override(): parsed_args = cli_as_dict('--config-override editor "nano"') - assert parsed_args == expected_args(config_override=[{"editor": "nano"}]) + assert parsed_args == expected_args(config_override=[["editor", "nano"]]) def test_color_override(): assert cli_as_dict("--config-override colors.body blue") == expected_args( - config_override=[{"colors.body": "blue"}] + config_override=[["colors.body", "blue"]] ) @@ -225,9 +225,9 @@ def test_multiple_overrides(): ) assert parsed_args == expected_args( config_override=[ - {"colors.title": "green"}, - {"editor": "nano"}, - {"journal.scratchpad": "/tmp/scratchpad"}, + ["colors.title", "green"], + ["editor", "nano"], + ["journal.scratchpad", "/tmp/scratchpad"], ] )