From 110e2b9022b8c3a892e3776ea17b1ccf337306ac Mon Sep 17 00:00:00 2001 From: sugas182 Date: Tue, 19 Jan 2021 09:03:43 -0500 Subject: [PATCH 01/82] add test and argument handler for runtime override of configurations. --- jrnl/args.py | 20 ++++++++++++++++++++ tests/test_parse_args.py | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/jrnl/args.py b/jrnl/args.py index f934ca16..cab41001 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -2,8 +2,10 @@ # License: https://www.gnu.org/licenses/gpl-3.0.html import argparse +from jrnl import config import re import textwrap +import json from .commands import postconfig_decrypt from .commands import postconfig_encrypt @@ -314,6 +316,24 @@ def parse_args(args=[]): help=argparse.SUPPRESS, ) + overrides = parser.add_argument_group("Config file overrides",textwrap.dedent('These are one-off overrides of the config file options')) + overrides.add_argument( + "--override", + dest="config_override", + action="store", + type=json.loads, + nargs="?", + default={}, + metavar="CONFIG_KV_PAIR", + help=""" + Override configured key-value pairs with CONFIG_KV_PAIR for this command invocation only. + + For example, to use a different editor for this jrnl entry, call: + jrnl --override '{"editor": "nano"}' + + """ + ) + # Handle '-123' as a shortcut for '-n 123' num = re.compile(r"^-(\d+)$") args = [num.sub(r"-n \1", arg) for arg in args] diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index 252638c9..fa367462 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -35,6 +35,7 @@ def expected_args(**kwargs): "strict": False, "tags": False, "text": [], + "config_override":{} } return {**default_args, **kwargs} @@ -204,6 +205,10 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) +def test_editor_override(): + from jrnl.commands import postconfig_override + + assert cli_as_dict("--override '{\"editor\": \"nano\"}'") == expected_args(config_override={'editor':'nano'}) # @see https://github.com/jrnl-org/jrnl/issues/520 @pytest.mark.parametrize( From 744824ddee6cbe452d80e10d2ae9f040b4f5a6d8 Mon Sep 17 00:00:00 2001 From: sugas182 Date: Tue, 19 Jan 2021 21:08:04 -0500 Subject: [PATCH 02/82] identify location to apply override in "main" --- jrnl/jrnl.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index 257358c4..c8e4ff0b 100644 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -49,6 +49,10 @@ def run(args): args=args, config=config, original_config=original_config ) + # Apply config overrides + overrides = args.config_override + #TODO: substitute overriden KV pairs in config dict ONLY AFTER ADDING TESTS + # --- All the standalone commands are now done --- # # Get the journal we're going to be working with From a64fa82a0603f456b812aaee2e35e1ab301b547d Mon Sep 17 00:00:00 2001 From: sugas182 Date: Tue, 19 Jan 2021 21:08:42 -0500 Subject: [PATCH 03/82] update gitignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index afb0d874..5e11d85b 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,8 @@ exp/ _extras/ *.sublime-* site/ + +.vscode/settings.json +coverage.xml +.vscode/launch.json +.coverage \ No newline at end of file From ee7cd44a32b9b21b33a5cf14aaf692c91f3938fb Mon Sep 17 00:00:00 2001 From: sugas182 Date: Tue, 19 Jan 2021 21:15:03 -0500 Subject: [PATCH 04/82] remove unneeded import --- tests/test_parse_args.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index fa367462..858e17d3 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -206,7 +206,7 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) def test_editor_override(): - from jrnl.commands import postconfig_override + assert cli_as_dict("--override '{\"editor\": \"nano\"}'") == expected_args(config_override={'editor':'nano'}) From 53d7d8cea4b9e5da6ec7ad44370ed87eef2440ab Mon Sep 17 00:00:00 2001 From: Suhas Date: Wed, 20 Jan 2021 15:09:45 -0500 Subject: [PATCH 05/82] add jrnl interface test for overriden configurations --- tests/test_config.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tests/test_config.py diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 00000000..af0bc784 --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,25 @@ +import pytest +import pytest_mock +import mock + +import yaml +from jrnl.args import parse_args +from jrnl.jrnl import run +from jrnl import install + +@pytest.fixture() +def minimal_config(): + with open('features/data/configs/editor.yaml','r') as cfg_file: + yield yaml.load(cfg_file.read()) + +from jrnl import jrnl +@mock.patch.object(jrnl,'write_mode') +@mock.patch.object(install,'load_or_install_jrnl') +def test_override_configured_editor(mock_load_or_install, mock_write_mode, minimal_config): + mock_load_or_install.return_value = minimal_config + cli_args = ['--override','{\"editor\": \"nano\"}' ] + parser = parse_args(cli_args) + assert parser.config_override.__len__() == 1 + with mock.patch('subprocess.call'): + res = run(parser) + assert res==None \ No newline at end of file From 554d25ae175152a127e002214f9b4e44b9642143 Mon Sep 17 00:00:00 2001 From: Suhas Date: Wed, 20 Jan 2021 15:11:48 -0500 Subject: [PATCH 06/82] trivial whitespace change --- tests/test_parse_args.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index 858e17d3..b0de80a3 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -206,7 +206,6 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) def test_editor_override(): - assert cli_as_dict("--override '{\"editor\": \"nano\"}'") == expected_args(config_override={'editor':'nano'}) From 5fe6caf805ff1282f94685b52477de9935df65f7 Mon Sep 17 00:00:00 2001 From: Suhas Date: Wed, 20 Jan 2021 15:12:30 -0500 Subject: [PATCH 07/82] implement runtime override --- jrnl/jrnl.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index c8e4ff0b..3f3216f8 100644 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -52,7 +52,9 @@ def run(args): # Apply config overrides overrides = args.config_override #TODO: substitute overriden KV pairs in config dict ONLY AFTER ADDING TESTS - + for k in overrides: + logging.debug("Overriding %s from %s to %s"%(k,config[k],overrides[k])) + config[k] = overrides[k] # --- All the standalone commands are now done --- # # Get the journal we're going to be working with From c4b3d511818bcd11421d4a41d041b364bea79229 Mon Sep 17 00:00:00 2001 From: Suhas Date: Wed, 20 Jan 2021 21:35:26 -0500 Subject: [PATCH 08/82] make format --- jrnl/args.py | 7 +++++-- jrnl/jrnl.py | 6 +++--- tests/test_config.py | 28 +++++++++++++++++----------- tests/test_parse_args.py | 8 ++++++-- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/jrnl/args.py b/jrnl/args.py index cab41001..761007a3 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -316,7 +316,10 @@ def parse_args(args=[]): help=argparse.SUPPRESS, ) - overrides = parser.add_argument_group("Config file overrides",textwrap.dedent('These are one-off overrides of the config file options')) + overrides = parser.add_argument_group( + "Config file overrides", + textwrap.dedent("These are one-off overrides of the config file options"), + ) overrides.add_argument( "--override", dest="config_override", @@ -331,7 +334,7 @@ def parse_args(args=[]): For example, to use a different editor for this jrnl entry, call: jrnl --override '{"editor": "nano"}' - """ + """, ) # Handle '-123' as a shortcut for '-n 123' diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index 3f3216f8..e58cc956 100644 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -51,9 +51,9 @@ def run(args): # Apply config overrides overrides = args.config_override - #TODO: substitute overriden KV pairs in config dict ONLY AFTER ADDING TESTS - for k in overrides: - logging.debug("Overriding %s from %s to %s"%(k,config[k],overrides[k])) + # TODO: substitute overriden KV pairs in config dict ONLY AFTER ADDING TESTS + for k in overrides: + logging.debug("Overriding %s from %s to %s" % (k, config[k], overrides[k])) config[k] = overrides[k] # --- All the standalone commands are now done --- # diff --git a/tests/test_config.py b/tests/test_config.py index af0bc784..083f3fe6 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,25 +1,31 @@ -import pytest -import pytest_mock +import pytest +import pytest_mock import mock import yaml from jrnl.args import parse_args -from jrnl.jrnl import run -from jrnl import install +from jrnl.jrnl import run +from jrnl import install + @pytest.fixture() def minimal_config(): - with open('features/data/configs/editor.yaml','r') as cfg_file: + with open("features/data/configs/editor.yaml", "r") as cfg_file: yield yaml.load(cfg_file.read()) + from jrnl import jrnl -@mock.patch.object(jrnl,'write_mode') -@mock.patch.object(install,'load_or_install_jrnl') -def test_override_configured_editor(mock_load_or_install, mock_write_mode, minimal_config): + + +@mock.patch.object(jrnl, "write_mode") +@mock.patch.object(install, "load_or_install_jrnl") +def test_override_configured_editor( + mock_load_or_install, mock_write_mode, minimal_config +): mock_load_or_install.return_value = minimal_config - cli_args = ['--override','{\"editor\": \"nano\"}' ] + cli_args = ["--override", '{"editor": "nano"}'] parser = parse_args(cli_args) assert parser.config_override.__len__() == 1 - with mock.patch('subprocess.call'): + with mock.patch("subprocess.call"): res = run(parser) - assert res==None \ No newline at end of file + assert res == None diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index b0de80a3..ee67ba65 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -35,7 +35,7 @@ def expected_args(**kwargs): "strict": False, "tags": False, "text": [], - "config_override":{} + "config_override": {}, } return {**default_args, **kwargs} @@ -205,9 +205,13 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) + def test_editor_override(): - assert cli_as_dict("--override '{\"editor\": \"nano\"}'") == expected_args(config_override={'editor':'nano'}) + assert cli_as_dict('--override \'{"editor": "nano"}\'') == expected_args( + config_override={"editor": "nano"} + ) + # @see https://github.com/jrnl-org/jrnl/issues/520 @pytest.mark.parametrize( From 9e2b7dd0c1b65e37f352be08fa1d9888b300f8a3 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 21 Jan 2021 22:47:29 -0500 Subject: [PATCH 09/82] refactor override unittest --- tests/test_config.py | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index 083f3fe6..21dcc521 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,3 +1,4 @@ +from typing import Any import pytest import pytest_mock import mock @@ -5,27 +6,49 @@ import mock import yaml from jrnl.args import parse_args from jrnl.jrnl import run -from jrnl import install +from jrnl import install, editor @pytest.fixture() def minimal_config(): with open("features/data/configs/editor.yaml", "r") as cfg_file: - yield yaml.load(cfg_file.read()) + cfg = yaml.load(cfg_file.read()) + yield cfg + +@pytest.fixture() +def expected_override(minimal_config): + exp_out_cfg = minimal_config.copy() + exp_out_cfg['editor'] = 'nano' + exp_out_cfg['journal'] = 'features/journals/simple.journal' + yield exp_out_cfg from jrnl import jrnl -@mock.patch.object(jrnl, "write_mode") + +@mock.patch('sys.stdin.isatty') @mock.patch.object(install, "load_or_install_jrnl") +@mock.patch('subprocess.call') def test_override_configured_editor( - mock_load_or_install, mock_write_mode, minimal_config + mock_subprocess_call, + mock_load_or_install, + mock_isatty, + minimal_config, + expected_override, + capsys ): mock_load_or_install.return_value = minimal_config + mock_isatty.return_value = True + cli_args = ["--override", '{"editor": "nano"}'] parser = parse_args(cli_args) assert parser.config_override.__len__() == 1 - with mock.patch("subprocess.call"): - res = run(parser) - assert res == None + def mock_editor_launch(editor): + print("%s launched! Success!"%editor) + with mock.patch.object(jrnl,'_write_in_editor', side_effect=mock_editor_launch(parser.config_override['editor']), return_value = 'note_contents') as mock_write_in_editor: + run(parser) + mock_write_in_editor.assert_called_once_with(expected_override) + + + From 692a979efe8b4d8720478b68d3483e2a21ac90da Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 21 Jan 2021 22:47:46 -0500 Subject: [PATCH 10/82] clean up unused import --- jrnl/args.py | 1 - 1 file changed, 1 deletion(-) diff --git a/jrnl/args.py b/jrnl/args.py index 761007a3..61ffb4b2 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -2,7 +2,6 @@ # License: https://www.gnu.org/licenses/gpl-3.0.html import argparse -from jrnl import config import re import textwrap import json From 2fc19c41b9bff9f887d34cfea15b5221d5416a45 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 21 Jan 2021 22:48:01 -0500 Subject: [PATCH 11/82] start writing integration test --- features/overrides.feature | 6 ++++++ features/steps/core.py | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 features/overrides.feature diff --git a/features/overrides.feature b/features/overrides.feature new file mode 100644 index 00000000..e8e5b6da --- /dev/null +++ b/features/overrides.feature @@ -0,0 +1,6 @@ +Feature: Implementing Runtime Overrides for Select Configuration Keys + +Scenario: Override configured editor with built-in input === editor:'' +Given we use the config "editor-args.yaml" +When we run "jrnl --override '{\"editor\": \"\"}'" +Then the editor "" should have been called \ No newline at end of file diff --git a/features/steps/core.py b/features/steps/core.py index abac4917..d39b43f4 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -212,7 +212,9 @@ def open_editor_and_enter(context, method, text=""): # fmt: on - +@then("the editor {editor} should have been called") +def editor_override(context, editor): + @then("the editor should have been called") @then("the editor should have been called with {num} arguments") def count_editor_args(context, num=None): From 12d2f48f97ac11e9a507259185ddde80cf38a2e6 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sat, 23 Jan 2021 11:07:51 -0500 Subject: [PATCH 12/82] add linewrap override scenario --- features/overrides.feature | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/features/overrides.feature b/features/overrides.feature index e8e5b6da..cdc30614 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -2,5 +2,30 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys Scenario: Override configured editor with built-in input === editor:'' Given we use the config "editor-args.yaml" -When we run "jrnl --override '{\"editor\": \"\"}'" -Then the editor "" should have been called \ No newline at end of file +When we run "jrnl --override '{\"editor\": \"\""}'" +Then the editor "" should have been called + +Scenario: Override configured editor with 'nano' +Given we use the config "editor.yaml" +When we run "jrnl --override '{\"editor\": \"nano\"}'" +Then the editor "nano" should have been called + +Scenario: Override configured linewrap with a value of 23 +Given we use the config "editor.yaml" +When we run "jrnl -2 --override '{"linewrap": 23}' --format fancy" +Then the output should be +""" +┎─────╮2013-06-09 15:39 +┃ My ╘═══════════════╕ +┃ fir st ent ry. │ +┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +┃ Everything is │ +┃ alright │ +┖─────────────────────┘ +┎─────╮2013-06-10 15:40 +┃ Lif ╘═══════════════╕ +┃ e is goo d. │ +┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +┃ But I'm better. │ +┖─────────────────────┘ +""" \ No newline at end of file From 43b8407ad53dfc398d9f08853c33d9fa74985681 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sat, 23 Jan 2021 11:08:01 -0500 Subject: [PATCH 13/82] implement editor override step --- features/steps/core.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/features/steps/core.py b/features/steps/core.py index d39b43f4..e6c88609 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -215,6 +215,29 @@ def open_editor_and_enter(context, method, text=""): @then("the editor {editor} should have been called") def editor_override(context, editor): + def _mock_editor(command_and_journal_file): + editor = command_and_journal_file[0] + context.tmpfile = command_and_journal_file[-1] + print("%s has been launched"%editor) + return tmpfile + + try : + # fmt: off + # see: https://github.com/psf/black/issues/664 + with \ + patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ + patch("sys.stdin.isatty", return_value=True), \ + patch("jrnl.time.parse", side_effect=_mock_time_parse(context)), \ + patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ + patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ + : + cli(['--override','{"editor": "%s"}'%editor]) + context.exit_status = 0 + context.editor = mock_editor + assert mock_editor.assert_called_once_with(editor, context.tmpfile) + except SystemExit as e: + context.exit_status = e.code + @then("the editor should have been called") @then("the editor should have been called with {num} arguments") def count_editor_args(context, num=None): From 263c79cea6acdec0e6a64bb5cc7d5d63daf78f11 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sat, 23 Jan 2021 11:13:06 -0500 Subject: [PATCH 14/82] add dev dependencies on pytest -mock and -cov --- poetry.lock | 252 ++++++++++++++++++++++++++++++++++++------------- pyproject.toml | 4 +- 2 files changed, 192 insertions(+), 64 deletions(-) diff --git a/poetry.lock b/poetry.lock index fc0f5895..541f7e3a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -127,6 +127,17 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "coverage" +version = "5.3.1" +description = "Code coverage measurement for Python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +toml = ["toml"] + [[package]] name = "cryptography" version = "3.3.1" @@ -156,18 +167,19 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "importlib-metadata" -version = "3.1.1" +version = "3.4.0" description = "Read metadata from Python packages" category = "main" optional = false python-versions = ">=3.6" [package.dependencies] +typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -204,8 +216,8 @@ i18n = ["Babel (>=0.8)"] [[package]] name = "joblib" -version = "0.17.0" -description = "Lightweight pipelining: using Python functions as pipeline jobs." +version = "1.0.0" +description = "Lightweight pipelining with Python functions" category = "dev" optional = false python-versions = ">=3.6" @@ -295,6 +307,19 @@ Markdown = ">=3.2.1" PyYAML = ">=3.10" tornado = ">=5.0" +[[package]] +name = "mock" +version = "4.0.3" +description = "Rolling backport of unittest.mock for all Pythons" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.extras] +build = ["twine", "wheel", "blurb"] +docs = ["sphinx"] +test = ["pytest (<5.4)", "pytest-cov"] + [[package]] name = "mypy-extensions" version = "0.4.3" @@ -338,7 +363,7 @@ pyparsing = ">=2.0.2" [[package]] name = "parse" -version = "1.18.0" +version = "1.19.0" description = "parse() is the opposite of format()" category = "dev" optional = false @@ -444,6 +469,35 @@ toml = "*" [package.extras] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +[[package]] +name = "pytest-cov" +version = "2.11.1" +description = "Pytest plugin for measuring coverage." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +coverage = ">=5.2.1" +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests (==2.0.2)", "six", "pytest-xdist", "virtualenv"] + +[[package]] +name = "pytest-mock" +version = "3.5.1" +description = "Thin-wrapper around the mock package for easier use with pytest" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +pytest = ">=5.0" + +[package.extras] +dev = ["pre-commit", "tox", "pytest-asyncio"] + [[package]] name = "python-dateutil" version = "2.8.1" @@ -481,11 +535,11 @@ python-versions = "*" [[package]] name = "pyyaml" -version = "5.3.1" +version = "5.4.1" description = "YAML parser and emitter for Python" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [[package]] name = "regex" @@ -541,18 +595,19 @@ python-versions = ">= 3.5" [[package]] name = "tqdm" -version = "4.54.1" +version = "4.56.0" description = "Fast, Extensible Progress Meter" category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" [package.extras] -dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown", "wheel"] +dev = ["py-make (>=0.1.0)", "twine", "wheel"] +telegram = ["requests"] [[package]] name = "typed-ast" -version = "1.4.1" +version = "1.4.2" description = "a fork of Python 2 and 3 ast modules with type comment support" category = "dev" optional = false @@ -562,7 +617,7 @@ python-versions = "*" name = "typing-extensions" version = "3.7.4.3" description = "Backported and Experimental Type Hints for Python 3.5+" -category = "dev" +category = "main" optional = false python-versions = "*" @@ -616,7 +671,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake [metadata] lock-version = "1.1" python-versions = ">=3.7.0, <3.10" -content-hash = "1757c9f22bd1c3e2e4c6b7785d4c8e14a670334a21ab5de2137faf0fd10819b9" +content-hash = "fb7f55245f566cc5dcb849ce3a2f186e2ed090c802e6a2aba84fb70359ed69ea" [metadata.files] ansiwrap = [ @@ -695,6 +750,57 @@ colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] +coverage = [ + {file = "coverage-5.3.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:fabeeb121735d47d8eab8671b6b031ce08514c86b7ad8f7d5490a7b6dcd6267d"}, + {file = "coverage-5.3.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:7e4d159021c2029b958b2363abec4a11db0ce8cd43abb0d9ce44284cb97217e7"}, + {file = "coverage-5.3.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:378ac77af41350a8c6b8801a66021b52da8a05fd77e578b7380e876c0ce4f528"}, + {file = "coverage-5.3.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e448f56cfeae7b1b3b5bcd99bb377cde7c4eb1970a525c770720a352bc4c8044"}, + {file = "coverage-5.3.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:cc44e3545d908ecf3e5773266c487ad1877be718d9dc65fc7eb6e7d14960985b"}, + {file = "coverage-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:08b3ba72bd981531fd557f67beee376d6700fba183b167857038997ba30dd297"}, + {file = "coverage-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:8dacc4073c359f40fcf73aede8428c35f84639baad7e1b46fce5ab7a8a7be4bb"}, + {file = "coverage-5.3.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ee2f1d1c223c3d2c24e3afbb2dd38be3f03b1a8d6a83ee3d9eb8c36a52bee899"}, + {file = "coverage-5.3.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9a9d4ff06804920388aab69c5ea8a77525cf165356db70131616acd269e19b36"}, + {file = "coverage-5.3.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:782a5c7df9f91979a7a21792e09b34a658058896628217ae6362088b123c8500"}, + {file = "coverage-5.3.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:fda29412a66099af6d6de0baa6bd7c52674de177ec2ad2630ca264142d69c6c7"}, + {file = "coverage-5.3.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:f2c6888eada180814b8583c3e793f3f343a692fc802546eed45f40a001b1169f"}, + {file = "coverage-5.3.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8f33d1156241c43755137288dea619105477961cfa7e47f48dbf96bc2c30720b"}, + {file = "coverage-5.3.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b239711e774c8eb910e9b1ac719f02f5ae4bf35fa0420f438cdc3a7e4e7dd6ec"}, + {file = "coverage-5.3.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:f54de00baf200b4539a5a092a759f000b5f45fd226d6d25a76b0dff71177a714"}, + {file = "coverage-5.3.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:be0416074d7f253865bb67630cf7210cbc14eb05f4099cc0f82430135aaa7a3b"}, + {file = "coverage-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:c46643970dff9f5c976c6512fd35768c4a3819f01f61169d8cdac3f9290903b7"}, + {file = "coverage-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9a4f66259bdd6964d8cf26142733c81fb562252db74ea367d9beb4f815478e72"}, + {file = "coverage-5.3.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c6e5174f8ca585755988bc278c8bb5d02d9dc2e971591ef4a1baabdf2d99589b"}, + {file = "coverage-5.3.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3911c2ef96e5ddc748a3c8b4702c61986628bb719b8378bf1e4a6184bbd48fe4"}, + {file = "coverage-5.3.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c5ec71fd4a43b6d84ddb88c1df94572479d9a26ef3f150cef3dacefecf888105"}, + {file = "coverage-5.3.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f51dbba78d68a44e99d484ca8c8f604f17e957c1ca09c3ebc2c7e3bbd9ba0448"}, + {file = "coverage-5.3.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:a2070c5affdb3a5e751f24208c5c4f3d5f008fa04d28731416e023c93b275277"}, + {file = "coverage-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:535dc1e6e68fad5355f9984d5637c33badbdc987b0c0d303ee95a6c979c9516f"}, + {file = "coverage-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:a4857f7e2bc6921dbd487c5c88b84f5633de3e7d416c4dc0bb70256775551a6c"}, + {file = "coverage-5.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fac3c432851038b3e6afe086f777732bcf7f6ebbfd90951fa04ee53db6d0bcdd"}, + {file = "coverage-5.3.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:cd556c79ad665faeae28020a0ab3bda6cd47d94bec48e36970719b0b86e4dcf4"}, + {file = "coverage-5.3.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a66ca3bdf21c653e47f726ca57f46ba7fc1f260ad99ba783acc3e58e3ebdb9ff"}, + {file = "coverage-5.3.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ab110c48bc3d97b4d19af41865e14531f300b482da21783fdaacd159251890e8"}, + {file = "coverage-5.3.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e52d3d95df81c8f6b2a1685aabffadf2d2d9ad97203a40f8d61e51b70f191e4e"}, + {file = "coverage-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:fa10fee7e32213f5c7b0d6428ea92e3a3fdd6d725590238a3f92c0de1c78b9d2"}, + {file = "coverage-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ce6f3a147b4b1a8b09aae48517ae91139b1b010c5f36423fa2b866a8b23df879"}, + {file = "coverage-5.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:93a280c9eb736a0dcca19296f3c30c720cb41a71b1f9e617f341f0a8e791a69b"}, + {file = "coverage-5.3.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:3102bb2c206700a7d28181dbe04d66b30780cde1d1c02c5f3c165cf3d2489497"}, + {file = "coverage-5.3.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8ffd4b204d7de77b5dd558cdff986a8274796a1e57813ed005b33fd97e29f059"}, + {file = "coverage-5.3.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a607ae05b6c96057ba86c811d9c43423f35e03874ffb03fbdcd45e0637e8b631"}, + {file = "coverage-5.3.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:3a3c3f8863255f3c31db3889f8055989527173ef6192a283eb6f4db3c579d830"}, + {file = "coverage-5.3.1-cp38-cp38-win32.whl", hash = "sha256:ff1330e8bc996570221b450e2d539134baa9465f5cb98aff0e0f73f34172e0ae"}, + {file = "coverage-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:3498b27d8236057def41de3585f317abae235dd3a11d33e01736ffedb2ef8606"}, + {file = "coverage-5.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ceb499d2b3d1d7b7ba23abe8bf26df5f06ba8c71127f188333dddcf356b4b63f"}, + {file = "coverage-5.3.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:3b14b1da110ea50c8bcbadc3b82c3933974dbeea1832e814aab93ca1163cd4c1"}, + {file = "coverage-5.3.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:76b2775dda7e78680d688daabcb485dc87cf5e3184a0b3e012e1d40e38527cc8"}, + {file = "coverage-5.3.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:cef06fb382557f66d81d804230c11ab292d94b840b3cb7bf4450778377b592f4"}, + {file = "coverage-5.3.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f61319e33222591f885c598e3e24f6a4be3533c1d70c19e0dc59e83a71ce27d"}, + {file = "coverage-5.3.1-cp39-cp39-win32.whl", hash = "sha256:cc6f8246e74dd210d7e2b56c76ceaba1cc52b025cd75dbe96eb48791e0250e98"}, + {file = "coverage-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:2757fa64e11ec12220968f65d086b7a29b6583d16e9a544c889b22ba98555ef1"}, + {file = "coverage-5.3.1-pp36-none-any.whl", hash = "sha256:723d22d324e7997a651478e9c5a3120a0ecbc9a7e94071f7e1954562a8806cf3"}, + {file = "coverage-5.3.1-pp37-none-any.whl", hash = "sha256:c89b558f8a9a5a6f2cfc923c304d49f0ce629c3bd85cb442ca258ec20366394c"}, + {file = "coverage-5.3.1.tar.gz", hash = "sha256:38f16b1317b8dd82df67ed5daa5f5e7c959e46579840d77a67a4ceb9cef0a50b"}, +] cryptography = [ {file = "cryptography-3.3.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:c366df0401d1ec4e548bebe8f91d55ebcc0ec3137900d214dd7aac8427ef3030"}, {file = "cryptography-3.3.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9f6b0492d111b43de5f70052e24c1f0951cb9e6022188ebcb1cc3a3d301469b0"}, @@ -715,8 +821,8 @@ future = [ {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, ] importlib-metadata = [ - {file = "importlib_metadata-3.1.1-py3-none-any.whl", hash = "sha256:6112e21359ef8f344e7178aa5b72dc6e62b38b0d008e6d3cb212c5b84df72013"}, - {file = "importlib_metadata-3.1.1.tar.gz", hash = "sha256:b0c2d3b226157ae4517d9625decf63591461c66b3a808c2666d538946519d170"}, + {file = "importlib_metadata-3.4.0-py3-none-any.whl", hash = "sha256:ace61d5fc652dc280e7b6b4ff732a9c2d40db2c0f92bc6cb74e07b73d53a1771"}, + {file = "importlib_metadata-3.4.0.tar.gz", hash = "sha256:fa5daa4477a7414ae34e95942e4dd07f62adf589143c875c133c1e53c4eff38d"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -731,8 +837,8 @@ jinja2 = [ {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, ] joblib = [ - {file = "joblib-0.17.0-py3-none-any.whl", hash = "sha256:698c311779f347cf6b7e6b8a39bb682277b8ee4aba8cf9507bc0cf4cd4737b72"}, - {file = "joblib-0.17.0.tar.gz", hash = "sha256:9e284edd6be6b71883a63c9b7f124738a3c16195513ad940eae7e3438de885d5"}, + {file = "joblib-1.0.0-py3-none-any.whl", hash = "sha256:75ead23f13484a2a414874779d69ade40d4fa1abe62b222a23cd50d4bc822f6f"}, + {file = "joblib-1.0.0.tar.gz", hash = "sha256:7ad866067ac1fdec27d51c8678ea760601b70e32ff1881d4dc8e1171f2b64b24"}, ] keyring = [ {file = "keyring-21.8.0-py3-none-any.whl", hash = "sha256:4be9cbaaaf83e61d6399f733d113ede7d1c73bc75cb6aeb64eee0f6ac39b30ea"}, @@ -788,6 +894,10 @@ mkdocs = [ {file = "mkdocs-1.1.2-py3-none-any.whl", hash = "sha256:096f52ff52c02c7e90332d2e53da862fde5c062086e1b5356a6e392d5d60f5e9"}, {file = "mkdocs-1.1.2.tar.gz", hash = "sha256:f0b61e5402b99d7789efa032c7a74c90a20220a9c81749da06dbfbcbd52ffb39"}, ] +mock = [ + {file = "mock-4.0.3-py3-none-any.whl", hash = "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62"}, + {file = "mock-4.0.3.tar.gz", hash = "sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc"}, +] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, @@ -800,7 +910,7 @@ packaging = [ {file = "packaging-20.8.tar.gz", hash = "sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093"}, ] parse = [ - {file = "parse-1.18.0.tar.gz", hash = "sha256:91666032d6723dc5905248417ef0dc9e4c51df9526aaeef271eacad6491f06a4"}, + {file = "parse-1.19.0.tar.gz", hash = "sha256:9ff82852bcb65d139813e2a5197627a94966245c897796760a3a2a8eb66f020b"}, ] parse-type = [ {file = "parse_type-0.5.2-py2.py3-none-any.whl", hash = "sha256:089a471b06327103865dfec2dd844230c3c658a4a1b5b4c8b6c16c8f77577f9e"}, @@ -838,6 +948,14 @@ pytest = [ {file = "pytest-6.2.1-py3-none-any.whl", hash = "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8"}, {file = "pytest-6.2.1.tar.gz", hash = "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306"}, ] +pytest-cov = [ + {file = "pytest-cov-2.11.1.tar.gz", hash = "sha256:359952d9d39b9f822d9d29324483e7ba04a3a17dd7d05aa6beb7ea01e359e5f7"}, + {file = "pytest_cov-2.11.1-py2.py3-none-any.whl", hash = "sha256:bdb9fdb0b85a7cc825269a4c56b48ccaa5c7e365054b6038772c32ddcdc969da"}, +] +pytest-mock = [ + {file = "pytest-mock-3.5.1.tar.gz", hash = "sha256:a1e2aba6af9560d313c642dae7e00a2a12b022b80301d9d7fc8ec6858e1dd9fc"}, + {file = "pytest_mock-3.5.1-py3-none-any.whl", hash = "sha256:379b391cfad22422ea2e252bdfc008edd08509029bcde3c25b2c0bd741e0424e"}, +] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, @@ -855,19 +973,27 @@ pyxdg = [ {file = "pyxdg-0.27.tar.gz", hash = "sha256:80bd93aae5ed82435f20462ea0208fb198d8eec262e831ee06ce9ddb6b91c5a5"}, ] pyyaml = [ - {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, - {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, - {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, - {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, - {file = "PyYAML-5.3.1-cp39-cp39-win32.whl", hash = "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a"}, - {file = "PyYAML-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e"}, - {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, + {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, + {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, + {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, + {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, + {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, + {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, + {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, + {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, + {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, + {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, ] regex = [ {file = "regex-2020.11.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85"}, @@ -972,40 +1098,40 @@ tornado = [ {file = "tornado-6.1.tar.gz", hash = "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791"}, ] tqdm = [ - {file = "tqdm-4.54.1-py2.py3-none-any.whl", hash = "sha256:d4f413aecb61c9779888c64ddf0c62910ad56dcbe857d8922bb505d4dbff0df1"}, - {file = "tqdm-4.54.1.tar.gz", hash = "sha256:38b658a3e4ecf9b4f6f8ff75ca16221ae3378b2e175d846b6b33ea3a20852cf5"}, + {file = "tqdm-4.56.0-py2.py3-none-any.whl", hash = "sha256:4621f6823bab46a9cc33d48105753ccbea671b68bab2c50a9f0be23d4065cb5a"}, + {file = "tqdm-4.56.0.tar.gz", hash = "sha256:fe3d08dd00a526850568d542ff9de9bbc2a09a791da3c334f3213d8d0bbbca65"}, ] typed-ast = [ - {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, - {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, - {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, - {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, - {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, - {file = "typed_ast-1.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f"}, - {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, - {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, - {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, - {file = "typed_ast-1.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298"}, - {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, - {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, - {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, - {file = "typed_ast-1.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d"}, - {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, - {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, - {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, - {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c"}, - {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072"}, - {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91"}, - {file = "typed_ast-1.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d"}, - {file = "typed_ast-1.4.1-cp39-cp39-win32.whl", hash = "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395"}, - {file = "typed_ast-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c"}, - {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, + {file = "typed_ast-1.4.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:7703620125e4fb79b64aa52427ec192822e9f45d37d4b6625ab37ef403e1df70"}, + {file = "typed_ast-1.4.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c9aadc4924d4b5799112837b226160428524a9a45f830e0d0f184b19e4090487"}, + {file = "typed_ast-1.4.2-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:9ec45db0c766f196ae629e509f059ff05fc3148f9ffd28f3cfe75d4afb485412"}, + {file = "typed_ast-1.4.2-cp35-cp35m-win32.whl", hash = "sha256:85f95aa97a35bdb2f2f7d10ec5bbdac0aeb9dafdaf88e17492da0504de2e6400"}, + {file = "typed_ast-1.4.2-cp35-cp35m-win_amd64.whl", hash = "sha256:9044ef2df88d7f33692ae3f18d3be63dec69c4fb1b5a4a9ac950f9b4ba571606"}, + {file = "typed_ast-1.4.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c1c876fd795b36126f773db9cbb393f19808edd2637e00fd6caba0e25f2c7b64"}, + {file = "typed_ast-1.4.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5dcfc2e264bd8a1db8b11a892bd1647154ce03eeba94b461effe68790d8b8e07"}, + {file = "typed_ast-1.4.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8db0e856712f79c45956da0c9a40ca4246abc3485ae0d7ecc86a20f5e4c09abc"}, + {file = "typed_ast-1.4.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:d003156bb6a59cda9050e983441b7fa2487f7800d76bdc065566b7d728b4581a"}, + {file = "typed_ast-1.4.2-cp36-cp36m-win32.whl", hash = "sha256:4c790331247081ea7c632a76d5b2a265e6d325ecd3179d06e9cf8d46d90dd151"}, + {file = "typed_ast-1.4.2-cp36-cp36m-win_amd64.whl", hash = "sha256:d175297e9533d8d37437abc14e8a83cbc68af93cc9c1c59c2c292ec59a0697a3"}, + {file = "typed_ast-1.4.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf54cfa843f297991b7388c281cb3855d911137223c6b6d2dd82a47ae5125a41"}, + {file = "typed_ast-1.4.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:b4fcdcfa302538f70929eb7b392f536a237cbe2ed9cba88e3bf5027b39f5f77f"}, + {file = "typed_ast-1.4.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:987f15737aba2ab5f3928c617ccf1ce412e2e321c77ab16ca5a293e7bbffd581"}, + {file = "typed_ast-1.4.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:37f48d46d733d57cc70fd5f30572d11ab8ed92da6e6b28e024e4a3edfb456e37"}, + {file = "typed_ast-1.4.2-cp37-cp37m-win32.whl", hash = "sha256:36d829b31ab67d6fcb30e185ec996e1f72b892255a745d3a82138c97d21ed1cd"}, + {file = "typed_ast-1.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:8368f83e93c7156ccd40e49a783a6a6850ca25b556c0fa0240ed0f659d2fe496"}, + {file = "typed_ast-1.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:963c80b583b0661918718b095e02303d8078950b26cc00b5e5ea9ababe0de1fc"}, + {file = "typed_ast-1.4.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e683e409e5c45d5c9082dc1daf13f6374300806240719f95dc783d1fc942af10"}, + {file = "typed_ast-1.4.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:84aa6223d71012c68d577c83f4e7db50d11d6b1399a9c779046d75e24bed74ea"}, + {file = "typed_ast-1.4.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:a38878a223bdd37c9709d07cd357bb79f4c760b29210e14ad0fb395294583787"}, + {file = "typed_ast-1.4.2-cp38-cp38-win32.whl", hash = "sha256:a2c927c49f2029291fbabd673d51a2180038f8cd5a5b2f290f78c4516be48be2"}, + {file = "typed_ast-1.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:c0c74e5579af4b977c8b932f40a5464764b2f86681327410aa028a22d2f54937"}, + {file = "typed_ast-1.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:07d49388d5bf7e863f7fa2f124b1b1d89d8aa0e2f7812faff0a5658c01c59aa1"}, + {file = "typed_ast-1.4.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:240296b27397e4e37874abb1df2a608a92df85cf3e2a04d0d4d61055c8305ba6"}, + {file = "typed_ast-1.4.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:d746a437cdbca200622385305aedd9aef68e8a645e385cc483bdc5e488f07166"}, + {file = "typed_ast-1.4.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:14bf1522cdee369e8f5581238edac09150c765ec1cb33615855889cf33dcb92d"}, + {file = "typed_ast-1.4.2-cp39-cp39-win32.whl", hash = "sha256:cc7b98bf58167b7f2db91a4327da24fb93368838eb84a44c472283778fc2446b"}, + {file = "typed_ast-1.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:7147e2a76c75f0f64c4319886e7639e490fee87c9d25cb1d4faef1d8cf83a440"}, + {file = "typed_ast-1.4.2.tar.gz", hash = "sha256:9fc0b3cb5d1720e7141d103cf4819aea239f7d136acf9ee4a69b047b7986175a"}, ] typing-extensions = [ {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, diff --git a/pyproject.toml b/pyproject.toml index 0bf1460e..ddf8b2ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,7 @@ pyyaml = ">=5.1" # dayone-only deps pytz = ">=2020" # https://pythonhosted.org/pytz/#issues-limitations tzlocal = ">2.0, <3.0" # https://github.com/regebro/tzlocal/blob/master/CHANGES.txt +mock = "^4.0.3" [tool.poetry.dev-dependencies] behave = "^1.2" @@ -45,8 +46,9 @@ black = {version = "^20.8b1",allow-prereleases = true} toml = ">=0.10" pyflakes = ">=2.2.0" pytest = ">=6.2" +pytest-mock = "^3.5.1" +pytest-cov = "^2.11.1" yq = ">=2.11" - [tool.poetry.scripts] jrnl = 'jrnl.cli:cli' From 77646eaa1a2fa6907affca325e4824a36790f4fc Mon Sep 17 00:00:00 2001 From: Suhas Date: Sat, 23 Jan 2021 11:18:13 -0500 Subject: [PATCH 15/82] make format --- features/steps/core.py | 49 ++++++++++++++++++++++-------------------- tests/test_config.py | 38 +++++++++++++++++--------------- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index e6c88609..bee060f7 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -212,32 +212,35 @@ def open_editor_and_enter(context, method, text=""): # fmt: on + @then("the editor {editor} should have been called") -def editor_override(context, editor): - - def _mock_editor(command_and_journal_file): +def editor_override(context, editor): + def _mock_editor(command_and_journal_file): editor = command_and_journal_file[0] - context.tmpfile = command_and_journal_file[-1] - print("%s has been launched"%editor) + tmpfile = command_and_journal_file[-1] + context.tmpfile = tmpfile + print("%s has been launched" % editor) return tmpfile - - try : - # fmt: off - # see: https://github.com/psf/black/issues/664 - with \ - patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ - patch("sys.stdin.isatty", return_value=True), \ - patch("jrnl.time.parse", side_effect=_mock_time_parse(context)), \ - patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ - patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ - : - cli(['--override','{"editor": "%s"}'%editor]) - context.exit_status = 0 - context.editor = mock_editor - assert mock_editor.assert_called_once_with(editor, context.tmpfile) - except SystemExit as e: - context.exit_status = e.code - + + # fmt: off + # see: https://github.com/psf/black/issues/664 + with \ + patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ + patch("sys.stdin.isatty", return_value=True), \ + patch("jrnl.time.parse", side_effect=_mock_time_parse(context)), \ + patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ + patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ + : + try : + cli(['--override','{"editor": "%s"}'%editor]) + context.exit_status = 0 + context.editor = mock_editor + assert mock_editor.assert_called_once_with(editor, context.tmpfile) + except SystemExit as e: + context.exit_status = e.code + # fmt: on + + @then("the editor should have been called") @then("the editor should have been called with {num} arguments") def count_editor_args(context, num=None): diff --git a/tests/test_config.py b/tests/test_config.py index 21dcc521..19ef3172 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -12,31 +12,31 @@ from jrnl import install, editor @pytest.fixture() def minimal_config(): with open("features/data/configs/editor.yaml", "r") as cfg_file: - cfg = yaml.load(cfg_file.read()) - yield cfg + cfg = yaml.load(cfg_file.read()) + yield cfg + @pytest.fixture() def expected_override(minimal_config): exp_out_cfg = minimal_config.copy() - exp_out_cfg['editor'] = 'nano' - exp_out_cfg['journal'] = 'features/journals/simple.journal' + exp_out_cfg["editor"] = "nano" + exp_out_cfg["journal"] = "features/journals/simple.journal" yield exp_out_cfg from jrnl import jrnl - -@mock.patch('sys.stdin.isatty') +@mock.patch("sys.stdin.isatty") @mock.patch.object(install, "load_or_install_jrnl") -@mock.patch('subprocess.call') +@mock.patch("subprocess.call") def test_override_configured_editor( mock_subprocess_call, - mock_load_or_install, - mock_isatty, - minimal_config, + mock_load_or_install, + mock_isatty, + minimal_config, expected_override, - capsys + capsys, ): mock_load_or_install.return_value = minimal_config mock_isatty.return_value = True @@ -44,11 +44,15 @@ def test_override_configured_editor( cli_args = ["--override", '{"editor": "nano"}'] parser = parse_args(cli_args) assert parser.config_override.__len__() == 1 - def mock_editor_launch(editor): - print("%s launched! Success!"%editor) - with mock.patch.object(jrnl,'_write_in_editor', side_effect=mock_editor_launch(parser.config_override['editor']), return_value = 'note_contents') as mock_write_in_editor: + + def mock_editor_launch(editor): + print("%s launched! Success!" % editor) + + with mock.patch.object( + jrnl, + "_write_in_editor", + side_effect=mock_editor_launch(parser.config_override["editor"]), + return_value="note_contents", + ) as mock_write_in_editor: run(parser) mock_write_in_editor.assert_called_once_with(expected_override) - - - From b82391deaaa6b7e1eaed6a431cabdbc0583bee46 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sat, 23 Jan 2021 12:16:07 -0500 Subject: [PATCH 16/82] remove unused imports --- tests/test_config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index 19ef3172..1f7672cc 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,12 +1,12 @@ -from typing import Any + import pytest -import pytest_mock + import mock import yaml from jrnl.args import parse_args from jrnl.jrnl import run -from jrnl import install, editor +from jrnl import install @pytest.fixture() From 1bd275bf5482514765f5654432f8f5483d172001 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sat, 23 Jan 2021 12:18:28 -0500 Subject: [PATCH 17/82] make format --- tests/test_config.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_config.py b/tests/test_config.py index 1f7672cc..64c66b9f 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,4 +1,3 @@ - import pytest import mock From 1a8bcfca6433420152e6890d75ec955b75dfea1e Mon Sep 17 00:00:00 2001 From: Suhas Date: Sat, 23 Jan 2021 21:30:33 -0500 Subject: [PATCH 18/82] rename --override to --config-override --- features/overrides.feature | 6 +++--- features/steps/core.py | 2 +- jrnl/args.py | 4 ++-- tests/test_config.py | 2 +- tests/test_parse_args.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/features/overrides.feature b/features/overrides.feature index cdc30614..07aa45d2 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -2,17 +2,17 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys Scenario: Override configured editor with built-in input === editor:'' Given we use the config "editor-args.yaml" -When we run "jrnl --override '{\"editor\": \"\""}'" +When we run "jrnl --config-override '{\"editor\": \"\""}'" Then the editor "" should have been called Scenario: Override configured editor with 'nano' Given we use the config "editor.yaml" -When we run "jrnl --override '{\"editor\": \"nano\"}'" +When we run "jrnl --config-override '{\"editor\": \"nano\"}'" Then the editor "nano" should have been called Scenario: Override configured linewrap with a value of 23 Given we use the config "editor.yaml" -When we run "jrnl -2 --override '{"linewrap": 23}' --format fancy" +When we run "jrnl -2 --config-override '{"linewrap": 23}' --format fancy" Then the output should be """ ┎─────╮2013-06-09 15:39 diff --git a/features/steps/core.py b/features/steps/core.py index bee060f7..2e037018 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -232,7 +232,7 @@ def editor_override(context, editor): patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ : try : - cli(['--override','{"editor": "%s"}'%editor]) + cli(['--config-override','{"editor": "%s"}'%editor]) context.exit_status = 0 context.editor = mock_editor assert mock_editor.assert_called_once_with(editor, context.tmpfile) diff --git a/jrnl/args.py b/jrnl/args.py index 61ffb4b2..efbe8138 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -320,7 +320,7 @@ def parse_args(args=[]): textwrap.dedent("These are one-off overrides of the config file options"), ) overrides.add_argument( - "--override", + "--config-override", dest="config_override", action="store", type=json.loads, @@ -331,7 +331,7 @@ def parse_args(args=[]): Override configured key-value pairs with CONFIG_KV_PAIR for this command invocation only. For example, to use a different editor for this jrnl entry, call: - jrnl --override '{"editor": "nano"}' + jrnl --config-override '{"editor": "nano"}' """, ) diff --git a/tests/test_config.py b/tests/test_config.py index 64c66b9f..f094313c 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -40,7 +40,7 @@ def test_override_configured_editor( mock_load_or_install.return_value = minimal_config mock_isatty.return_value = True - cli_args = ["--override", '{"editor": "nano"}'] + cli_args = ["--config-override", '{"editor": "nano"}'] parser = parse_args(cli_args) assert parser.config_override.__len__() == 1 diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index ee67ba65..5520e3d6 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -208,7 +208,7 @@ def test_version_alone(): def test_editor_override(): - assert cli_as_dict('--override \'{"editor": "nano"}\'') == expected_args( + assert cli_as_dict('--config-override \'{"editor": "nano"}\'') == expected_args( config_override={"editor": "nano"} ) From 9676290c2745970c454dfd67299835b5acbdd20e Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 24 Jan 2021 07:17:53 -0500 Subject: [PATCH 19/82] move override implementation into own module --- jrnl/jrnl.py | 7 +++---- jrnl/override.py | 8 ++++++++ tests/test_override.py | 27 +++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 jrnl/override.py create mode 100644 tests/test_override.py diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index e58cc956..f04dc471 100644 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -51,10 +51,9 @@ def run(args): # Apply config overrides overrides = args.config_override - # TODO: substitute overriden KV pairs in config dict ONLY AFTER ADDING TESTS - for k in overrides: - logging.debug("Overriding %s from %s to %s" % (k, config[k], overrides[k])) - config[k] = overrides[k] + from .override import apply_overrides + config = apply_overrides(overrides,config) + # --- All the standalone commands are now done --- # # Get the journal we're going to be working with diff --git a/jrnl/override.py b/jrnl/override.py new file mode 100644 index 00000000..09de4258 --- /dev/null +++ b/jrnl/override.py @@ -0,0 +1,8 @@ +import logging +def apply_overrides(overrides: dict, base_config: dict) -> dict: + config = base_config.copy() + for k in overrides: + logging.debug("Overriding %s from %s to %s" % (k, config[k], overrides[k])) + config[k] = overrides[k] + + return config \ No newline at end of file diff --git a/tests/test_override.py b/tests/test_override.py new file mode 100644 index 00000000..25f38243 --- /dev/null +++ b/tests/test_override.py @@ -0,0 +1,27 @@ +import pytest + +import mock + +from jrnl.args import parse_args +from jrnl.jrnl import run, search_mode +from jrnl import install +from jrnl.override import apply_overrides +@pytest.fixture() +def minimal_config(): + cfg = { + "colors":{ + "body":"red", + "date":"green" + }, + "default":"/tmp/journal.jrnl", + "editor":"vim" + } + yield cfg + +def test_apply_override(minimal_config): + config = minimal_config.copy() + overrides = { + 'editor':'nano' + } + config = apply_overrides(overrides, config) + assert config['editor']=='nano' \ No newline at end of file From 80d2c609badde4888f3469c0a77396ddd880de64 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 24 Jan 2021 07:18:48 -0500 Subject: [PATCH 20/82] begin TDD of dot notated overrides --- features/overrides.feature | 12 ++++++++++-- jrnl/args.py | 10 ++++++---- tests/test_config.py | 23 +++++++++++++++++++++-- tests/test_parse_args.py | 5 ++++- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/features/overrides.feature b/features/overrides.feature index 07aa45d2..3108b407 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -2,12 +2,12 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys Scenario: Override configured editor with built-in input === editor:'' Given we use the config "editor-args.yaml" -When we run "jrnl --config-override '{\"editor\": \"\""}'" +When we run "jrnl --config-override '{"editor": """}'" Then the editor "" should have been called Scenario: Override configured editor with 'nano' Given we use the config "editor.yaml" -When we run "jrnl --config-override '{\"editor\": \"nano\"}'" +When we run "jrnl --config-override '{"editor": "nano"}'" Then the editor "nano" should have been called Scenario: Override configured linewrap with a value of 23 @@ -28,4 +28,12 @@ Then the output should be ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ ┃ But I'm better. │ ┖─────────────────────┘ +""" + +Scenario: Override color selections with runtime overrides +Given we use the config "no_colors.yaml" +When we run "jrnl --config-override '{"colors.body": "blue"}'" +Then the config should have "colors" set to +""" +'body': 'blue' """ \ No newline at end of file diff --git a/jrnl/args.py b/jrnl/args.py index efbe8138..d991783f 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -315,11 +315,11 @@ def parse_args(args=[]): help=argparse.SUPPRESS, ) - overrides = parser.add_argument_group( + config_overrides = parser.add_argument_group( "Config file overrides", textwrap.dedent("These are one-off overrides of the config file options"), ) - overrides.add_argument( + config_overrides.add_argument( "--config-override", dest="config_override", action="store", @@ -330,9 +330,11 @@ def parse_args(args=[]): help=""" Override configured key-value pairs with CONFIG_KV_PAIR for this command invocation only. - For example, to use a different editor for this jrnl entry, call: + Examples: + - Use a different editor for this jrnl entry, call: jrnl --config-override '{"editor": "nano"}' - + - Override color selections + jrnl --config-override '{"colors.body":"blue", "colors.title": "green"} """, ) diff --git a/tests/test_config.py b/tests/test_config.py index f094313c..d41b2de2 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -4,7 +4,7 @@ import mock import yaml from jrnl.args import parse_args -from jrnl.jrnl import run +from jrnl.jrnl import run, search_mode from jrnl import install @@ -43,7 +43,7 @@ def test_override_configured_editor( cli_args = ["--config-override", '{"editor": "nano"}'] parser = parse_args(cli_args) assert parser.config_override.__len__() == 1 - + assert "editor" in parser.config_override.keys() def mock_editor_launch(editor): print("%s launched! Success!" % editor) @@ -55,3 +55,22 @@ def test_override_configured_editor( ) as mock_write_in_editor: run(parser) mock_write_in_editor.assert_called_once_with(expected_override) + +@pytest.fixture() +def expected_color_override(minimal_config): + exp_out_cfg = minimal_config.copy() + exp_out_cfg["colors"] = {"body": "blue"} + exp_out_cfg["journal"] = "features/journals/simple.journal" + yield exp_out_cfg + +# @mock.patch.object(install,'load_or_install_jrnl') +# @mock.patch('subprocess.call') +# def test_override_configured_colors(mock_load_or_install, mock_subprocess_call, minimal_config, expected_color_override, capsys): +# mock_load_or_install.return_value = minimal_config + +# cli_args=["--config-override",'{"colors.body": "blue"}'] +# parser = parse_args(cli_args) +# assert "colors.body" in parser.config_override.keys() +# run(parser) + + diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index 5520e3d6..b71173aa 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -211,7 +211,10 @@ def test_editor_override(): assert cli_as_dict('--config-override \'{"editor": "nano"}\'') == 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"} + ) # @see https://github.com/jrnl-org/jrnl/issues/520 @pytest.mark.parametrize( From 9bab1aee87a5cbbbb93966394c38271bd7f53abf Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 24 Jan 2021 11:08:11 -0500 Subject: [PATCH 21/82] rewrite behavior scenario --- features/overrides.feature | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/features/overrides.feature b/features/overrides.feature index 3108b407..04281a1c 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -2,7 +2,7 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys Scenario: Override configured editor with built-in input === editor:'' Given we use the config "editor-args.yaml" -When we run "jrnl --config-override '{"editor": """}'" +When we run "jrnl --config-override '{"editor": ""}'" Then the editor "" should have been called Scenario: Override configured editor with 'nano' @@ -31,9 +31,6 @@ Then the output should be """ Scenario: Override color selections with runtime overrides -Given we use the config "no_colors.yaml" -When we run "jrnl --config-override '{"colors.body": "blue"}'" -Then the config should have "colors" set to -""" -'body': 'blue' -""" \ No newline at end of file +Given we use the config "editor.yaml" +When we run "jrnl -1 --config-override '{"colors.body": "blue"}' " +Then the runtime config should have colors.body set to blue From f3d8ed2e45bc4500996e6c82395347efe5eb4219 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 24 Jan 2021 11:08:47 -0500 Subject: [PATCH 22/82] implement recursive config overrides --- jrnl/args.py | 10 +++++----- jrnl/override.py | 25 +++++++++++++++++++++---- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/jrnl/args.py b/jrnl/args.py index d991783f..99489b74 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -330,11 +330,11 @@ def parse_args(args=[]): help=""" Override configured key-value pairs with CONFIG_KV_PAIR for this command invocation only. - Examples: - - Use a different editor for this jrnl entry, call: - jrnl --config-override '{"editor": "nano"}' - - Override color selections - jrnl --config-override '{"colors.body":"blue", "colors.title": "green"} + Examples: \n + \t - Use a different editor for this jrnl entry, call: \n + \t jrnl --config-override '{"editor": "nano"}' \n + \t - Override color selections\n + \t jrnl --config-override '{"colors.body":"blue", "colors.title": "green"} """, ) diff --git a/jrnl/override.py b/jrnl/override.py index 09de4258..8da034f9 100644 --- a/jrnl/override.py +++ b/jrnl/override.py @@ -1,8 +1,25 @@ -import logging +# import logging def apply_overrides(overrides: dict, base_config: dict) -> dict: config = base_config.copy() - for k in overrides: - logging.debug("Overriding %s from %s to %s" % (k, config[k], overrides[k])) - config[k] = overrides[k] + for k in overrides: + nodes = k.split('.') + config = recursively_apply(config, nodes, overrides[k]) + return config + +def recursively_apply(config: dict, nodes: list, override_value) -> dict: + """Recurse through configuration and apply overrides at the leaf of the config tree + + See: https://stackoverflow.com/a/47276490 for algorithm + + Args: + config (dict): loaded configuration from YAML + nodes (list): vector of override keys; the length of the vector indicates tree depth + override_value (str): runtime override passed from the command-line + """ + key = nodes[0] + config[key] = override_value \ + if len(nodes) == 1 \ + else \ + recursively_apply(config[key] if key in config else {}, nodes[1:], override_value) return config \ No newline at end of file From 2d7ff736961fef076490a449f735a596ec0dec43 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 24 Jan 2021 11:09:23 -0500 Subject: [PATCH 23/82] clean up unittests --- tests/test_config.py | 4 ++-- tests/test_override.py | 28 +++++++++++++++++++++------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index d41b2de2..17fc409d 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -4,14 +4,14 @@ import mock import yaml from jrnl.args import parse_args -from jrnl.jrnl import run, search_mode +from jrnl.jrnl import run from jrnl import install @pytest.fixture() def minimal_config(): with open("features/data/configs/editor.yaml", "r") as cfg_file: - cfg = yaml.load(cfg_file.read()) + cfg = yaml.load(cfg_file.read(), Loader=yaml.FullLoader) yield cfg diff --git a/tests/test_override.py b/tests/test_override.py index 25f38243..680cb872 100644 --- a/tests/test_override.py +++ b/tests/test_override.py @@ -1,11 +1,6 @@ import pytest -import mock - -from jrnl.args import parse_args -from jrnl.jrnl import run, search_mode -from jrnl import install -from jrnl.override import apply_overrides +from jrnl.override import apply_overrides, recursively_apply @pytest.fixture() def minimal_config(): cfg = { @@ -24,4 +19,23 @@ def test_apply_override(minimal_config): 'editor':'nano' } config = apply_overrides(overrides, config) - assert config['editor']=='nano' \ No newline at end of file + assert config['editor']=='nano' + +def test_override_dot_notation(minimal_config): + cfg = minimal_config.copy() + overrides = { + "colors.body": "blue" + } + cfg = apply_overrides(overrides=overrides, base_config=cfg) + assert cfg["colors"] == {"body": "blue", "date":"green"} + +def test_recursive_override(minimal_config): + + cfg = { + "colors": { + "body": "red", + "title": "green" + } + } + cfg = recursively_apply(cfg,["colors",'body'],"blue") + assert cfg["colors"]["body"] == "blue" \ No newline at end of file From 99030c46236767b600c2fb6cb6adabe07698eb52 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 24 Jan 2021 11:09:45 -0500 Subject: [PATCH 24/82] iterate on behave step --- features/steps/core.py | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index 2e037018..457f34fc 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -13,11 +13,13 @@ from behave import given from behave import then from behave import when import keyring +import mock import toml import yaml +from yaml.loader import FullLoader import jrnl.time -from jrnl import Journal +from jrnl import Journal, override from jrnl import __version__ from jrnl import plugins from jrnl.cli import cli @@ -211,8 +213,34 @@ def open_editor_and_enter(context, method, text=""): context.exit_status = e.code # fmt: on - - + +@then("the runtime config should have {key_as_dots} set to {override_value}") +def config_override(context, key_as_dots:str, override_value: str): + with open(context.config_path) as f: + loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) + loaded_cfg['journal']='features/journals/simple.journal' + base_cfg = loaded_cfg.copy() + def _mock_callback(**args): + print("callback executed") + # fmt: off + try: + with \ + mock.patch.object(jrnl.override,"recursively_apply",wraps=jrnl.override.recursively_apply) as mock_recurse, \ + patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ + patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ + : + cli(['-1','--config-override', '{"%s": "%s"}'%(key_as_dots,override_value)]) + # mock_recurse.assert_any_call(base_cfg,key_as_dots.split('.'),override_value) + keys_list = key_as_dots.split('.') + callList = [ + (base_cfg,keys_list,override_value), + (base_cfg,keys_list[1], override_value) + ] + mock_recurse.call_args_list + + except SystemExit as e : + context.exit_status = e.code + # fmt: on @then("the editor {editor} should have been called") def editor_override(context, editor): def _mock_editor(command_and_journal_file): From b92dd7edc7c191f501a3dec63857c9ae79c3a2c1 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 24 Jan 2021 11:10:00 -0500 Subject: [PATCH 25/82] make format --- features/steps/core.py | 13 +++++++--- jrnl/jrnl.py | 5 ++-- jrnl/override.py | 33 +++++++++++++------------ tests/test_config.py | 17 +++++++------ tests/test_override.py | 53 +++++++++++++++++----------------------- tests/test_parse_args.py | 11 ++++++--- 6 files changed, 69 insertions(+), 63 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index 457f34fc..ed38f570 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -213,15 +213,18 @@ def open_editor_and_enter(context, method, text=""): context.exit_status = e.code # fmt: on - + + @then("the runtime config should have {key_as_dots} set to {override_value}") -def config_override(context, key_as_dots:str, override_value: str): +def config_override(context, key_as_dots: str, override_value: str): with open(context.config_path) as f: loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) - loaded_cfg['journal']='features/journals/simple.journal' + loaded_cfg["journal"] = "features/journals/simple.journal" base_cfg = loaded_cfg.copy() - def _mock_callback(**args): + + def _mock_callback(**args): print("callback executed") + # fmt: off try: with \ @@ -241,6 +244,8 @@ def config_override(context, key_as_dots:str, override_value: str): except SystemExit as e : context.exit_status = e.code # fmt: on + + @then("the editor {editor} should have been called") def editor_override(context, editor): def _mock_editor(command_and_journal_file): diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index f04dc471..fdc8c87b 100644 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -52,8 +52,9 @@ def run(args): # Apply config overrides overrides = args.config_override from .override import apply_overrides - config = apply_overrides(overrides,config) - + + config = apply_overrides(overrides, config) + # --- All the standalone commands are now done --- # # Get the journal we're going to be working with diff --git a/jrnl/override.py b/jrnl/override.py index 8da034f9..fcc2cbf9 100644 --- a/jrnl/override.py +++ b/jrnl/override.py @@ -1,25 +1,28 @@ -# import logging +# import logging def apply_overrides(overrides: dict, base_config: dict) -> dict: - config = base_config.copy() - for k in overrides: - nodes = k.split('.') - config = recursively_apply(config, nodes, overrides[k]) - return config + config = base_config.copy() + for k in overrides: + nodes = k.split(".") + config = recursively_apply(config, nodes, overrides[k]) + return config def recursively_apply(config: dict, nodes: list, override_value) -> dict: - """Recurse through configuration and apply overrides at the leaf of the config tree - + """Recurse through configuration and apply overrides at the leaf of the config tree + See: https://stackoverflow.com/a/47276490 for algorithm Args: config (dict): loaded configuration from YAML - nodes (list): vector of override keys; the length of the vector indicates tree depth + nodes (list): vector of override keys; the length of the vector indicates tree depth override_value (str): runtime override passed from the command-line """ - key = nodes[0] - config[key] = override_value \ - if len(nodes) == 1 \ - else \ - recursively_apply(config[key] if key in config else {}, nodes[1:], override_value) - return config \ No newline at end of file + key = nodes[0] + config[key] = ( + override_value + if len(nodes) == 1 + else recursively_apply( + config[key] if key in config else {}, nodes[1:], override_value + ) + ) + return config diff --git a/tests/test_config.py b/tests/test_config.py index 17fc409d..d83d654d 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -43,7 +43,8 @@ def test_override_configured_editor( cli_args = ["--config-override", '{"editor": "nano"}'] parser = parse_args(cli_args) assert parser.config_override.__len__() == 1 - assert "editor" in parser.config_override.keys() + assert "editor" in parser.config_override.keys() + def mock_editor_launch(editor): print("%s launched! Success!" % editor) @@ -56,21 +57,21 @@ def test_override_configured_editor( run(parser) mock_write_in_editor.assert_called_once_with(expected_override) + @pytest.fixture() -def expected_color_override(minimal_config): - exp_out_cfg = minimal_config.copy() +def expected_color_override(minimal_config): + exp_out_cfg = minimal_config.copy() exp_out_cfg["colors"] = {"body": "blue"} exp_out_cfg["journal"] = "features/journals/simple.journal" yield exp_out_cfg + # @mock.patch.object(install,'load_or_install_jrnl') # @mock.patch('subprocess.call') -# def test_override_configured_colors(mock_load_or_install, mock_subprocess_call, minimal_config, expected_color_override, capsys): +# def test_override_configured_colors(mock_load_or_install, mock_subprocess_call, minimal_config, expected_color_override, capsys): # mock_load_or_install.return_value = minimal_config - + # cli_args=["--config-override",'{"colors.body": "blue"}'] # parser = parse_args(cli_args) -# assert "colors.body" in parser.config_override.keys() +# assert "colors.body" in parser.config_override.keys() # run(parser) - - diff --git a/tests/test_override.py b/tests/test_override.py index 680cb872..307173a4 100644 --- a/tests/test_override.py +++ b/tests/test_override.py @@ -1,41 +1,34 @@ import pytest from jrnl.override import apply_overrides, recursively_apply + + @pytest.fixture() -def minimal_config(): - cfg = { - "colors":{ - "body":"red", - "date":"green" - }, - "default":"/tmp/journal.jrnl", - "editor":"vim" +def minimal_config(): + cfg = { + "colors": {"body": "red", "date": "green"}, + "default": "/tmp/journal.jrnl", + "editor": "vim", } - yield cfg + yield cfg -def test_apply_override(minimal_config): + +def test_apply_override(minimal_config): config = minimal_config.copy() - overrides = { - 'editor':'nano' - } + overrides = {"editor": "nano"} config = apply_overrides(overrides, config) - assert config['editor']=='nano' + assert config["editor"] == "nano" -def test_override_dot_notation(minimal_config): - cfg = minimal_config.copy() - overrides = { - "colors.body": "blue" - } + +def test_override_dot_notation(minimal_config): + cfg = minimal_config.copy() + overrides = {"colors.body": "blue"} cfg = apply_overrides(overrides=overrides, base_config=cfg) - assert cfg["colors"] == {"body": "blue", "date":"green"} + assert cfg["colors"] == {"body": "blue", "date": "green"} -def test_recursive_override(minimal_config): - - cfg = { - "colors": { - "body": "red", - "title": "green" - } - } - cfg = recursively_apply(cfg,["colors",'body'],"blue") - assert cfg["colors"]["body"] == "blue" \ No newline at end of file + +def test_recursive_override(minimal_config): + + cfg = {"colors": {"body": "red", "title": "green"}} + cfg = recursively_apply(cfg, ["colors", "body"], "blue") + assert cfg["colors"]["body"] == "blue" diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index b71173aa..f713d90b 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -211,10 +211,13 @@ def test_editor_override(): assert cli_as_dict('--config-override \'{"editor": "nano"}\'') == 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"} - ) + + +def test_color_override(): + assert cli_as_dict( + '--config-override \'{"colors.body": "blue"}\'' + ) == expected_args(config_override={"colors.body": "blue"}) + # @see https://github.com/jrnl-org/jrnl/issues/520 @pytest.mark.parametrize( From ededf23afa106e562a565f4f7a82bf5894157e5f Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 24 Jan 2021 16:07:57 -0500 Subject: [PATCH 26/82] cleanup --- features/steps/core.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/features/steps/core.py b/features/steps/core.py index ed38f570..5dfdf0f1 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -16,10 +16,10 @@ import keyring import mock import toml import yaml -from yaml.loader import FullLoader + import jrnl.time -from jrnl import Journal, override +from jrnl import Journal from jrnl import __version__ from jrnl import plugins from jrnl.cli import cli @@ -220,7 +220,7 @@ def config_override(context, key_as_dots: str, override_value: str): with open(context.config_path) as f: loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) loaded_cfg["journal"] = "features/journals/simple.journal" - base_cfg = loaded_cfg.copy() + # base_cfg = loaded_cfg.copy() def _mock_callback(**args): print("callback executed") @@ -233,13 +233,8 @@ def config_override(context, key_as_dots: str, override_value: str): patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ : cli(['-1','--config-override', '{"%s": "%s"}'%(key_as_dots,override_value)]) - # mock_recurse.assert_any_call(base_cfg,key_as_dots.split('.'),override_value) - keys_list = key_as_dots.split('.') - callList = [ - (base_cfg,keys_list,override_value), - (base_cfg,keys_list[1], override_value) - ] - mock_recurse.call_args_list + mock_recurse.assert_called() + except SystemExit as e : context.exit_status = e.code From d348dbd55e96fa91bb19b132c3e1811414a86968 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 24 Jan 2021 19:12:59 -0500 Subject: [PATCH 27/82] move override behave tests out of core --- features/overrides.feature | 2 +- features/steps/core.py | 55 +------------------------ features/steps/override.py | 82 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 55 deletions(-) create mode 100644 features/steps/override.py diff --git a/features/overrides.feature b/features/overrides.feature index 04281a1c..07dd5a24 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -32,5 +32,5 @@ Then the output should be Scenario: Override color selections with runtime overrides Given we use the config "editor.yaml" -When we run "jrnl -1 --config-override '{"colors.body": "blue"}' " +When we run jrnl with "-1 --config-override '{"colors.body": "blue"}' " Then the runtime config should have colors.body set to blue diff --git a/features/steps/core.py b/features/steps/core.py index 5dfdf0f1..5f87ab73 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -14,6 +14,7 @@ from behave import then from behave import when import keyring import mock + import toml import yaml @@ -215,60 +216,6 @@ def open_editor_and_enter(context, method, text=""): # fmt: on -@then("the runtime config should have {key_as_dots} set to {override_value}") -def config_override(context, key_as_dots: str, override_value: str): - with open(context.config_path) as f: - loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) - loaded_cfg["journal"] = "features/journals/simple.journal" - # base_cfg = loaded_cfg.copy() - - def _mock_callback(**args): - print("callback executed") - - # fmt: off - try: - with \ - mock.patch.object(jrnl.override,"recursively_apply",wraps=jrnl.override.recursively_apply) as mock_recurse, \ - patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ - patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ - : - cli(['-1','--config-override', '{"%s": "%s"}'%(key_as_dots,override_value)]) - mock_recurse.assert_called() - - - except SystemExit as e : - context.exit_status = e.code - # fmt: on - - -@then("the editor {editor} should have been called") -def editor_override(context, editor): - def _mock_editor(command_and_journal_file): - editor = command_and_journal_file[0] - tmpfile = command_and_journal_file[-1] - context.tmpfile = tmpfile - print("%s has been launched" % editor) - return tmpfile - - # fmt: off - # see: https://github.com/psf/black/issues/664 - with \ - patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ - patch("sys.stdin.isatty", return_value=True), \ - patch("jrnl.time.parse", side_effect=_mock_time_parse(context)), \ - patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ - patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ - : - try : - cli(['--config-override','{"editor": "%s"}'%editor]) - context.exit_status = 0 - context.editor = mock_editor - assert mock_editor.assert_called_once_with(editor, context.tmpfile) - except SystemExit as e: - context.exit_status = e.code - # fmt: on - - @then("the editor should have been called") @then("the editor should have been called with {num} arguments") def count_editor_args(context, num=None): diff --git a/features/steps/override.py b/features/steps/override.py new file mode 100644 index 00000000..b1ddb31a --- /dev/null +++ b/features/steps/override.py @@ -0,0 +1,82 @@ +from jrnl.os_compat import split_args +from unittest import mock + +# from __future__ import with_statement +from jrnl.args import parse_args +import os +from behave import given, when, then +import yaml +from yaml.loader import FullLoader + +import jrnl +from jrnl.override import apply_overrides, _recursively_apply +from jrnl.cli import cli +from jrnl.jrnl import run + + +@given("we use the config {config_file}") +def load_config(context, config_file): + filepath = os.path.join("features/configs", config_file) + context.config_path = os.path.abspath(filepath) + with open(context.config_path) as cfg: + context.config = yaml.load(cfg, Loader=FullLoader) + + +@when("we run jrnl with {args}") +def run_command(context, args): + context.args = split_args("%s" % args) + context.parser = parse_args(context.args) + + +@then("the runtime config should have {key_as_dots} set to {override_value}") +def config_override(context, key_as_dots: str, override_value: str): + with open(context.config_path) as f: + loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) + loaded_cfg["journal"] = "features/journals/simple.journal" + # base_cfg = loaded_cfg.copy() + + def _mock_callback(**args): + print("callback executed") + + # fmt: off + try: + with \ + mock.patch.object(jrnl.override,"recursively_apply",wraps=jrnl.override.recursively_apply) as mock_recurse, \ + mock.patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ + mock.patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ + : + cli(['-1','--config-override', '{"%s": "%s"}'%(key_as_dots,override_value)]) + mock_recurse.assert_called() + + + except SystemExit as e : + context.exit_status = e.code + # fmt: on + + +@then("the editor {editor} should have been called") +def editor_override(context, editor): + def _mock_editor(command_and_journal_file): + editor = command_and_journal_file[0] + tmpfile = command_and_journal_file[-1] + context.tmpfile = tmpfile + print("%s has been launched" % editor) + return tmpfile + + # fmt: off + # see: https://github.com/psf/black/issues/664 + with \ + mock.patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ + mock.patch("sys.stdin.isatty", return_value=True), \ + mock.patch("jrnl.time.parse"), \ + mock.patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ + mock.patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ + : + try : + cli(['--config-override','{"editor": "%s"}'%editor]) + context.exit_status = 0 + context.editor = mock_editor + assert mock_editor.assert_called_once_with(editor, context.tmpfile) + except SystemExit as e: + context.exit_status = e.code + # fmt: on From 9540d349649fd02ebf8767fb5ee4dfc4b5b94a9c Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 24 Jan 2021 19:14:46 -0500 Subject: [PATCH 28/82] refactor recursive code --- jrnl/override.py | 23 +++++++++++++++-------- tests/test_override.py | 6 ++++++ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/jrnl/override.py b/jrnl/override.py index fcc2cbf9..10ba6c8d 100644 --- a/jrnl/override.py +++ b/jrnl/override.py @@ -10,7 +10,7 @@ def apply_overrides(overrides: dict, base_config: dict) -> dict: def recursively_apply(config: dict, nodes: list, override_value) -> dict: """Recurse through configuration and apply overrides at the leaf of the config tree - See: https://stackoverflow.com/a/47276490 for algorithm + Credit to iJames on SO: https://stackoverflow.com/a/47276490 for algorithm Args: config (dict): loaded configuration from YAML @@ -18,11 +18,18 @@ def recursively_apply(config: dict, nodes: list, override_value) -> dict: override_value (str): runtime override passed from the command-line """ key = nodes[0] - config[key] = ( - override_value - if len(nodes) == 1 - else recursively_apply( - config[key] if key in config else {}, nodes[1:], override_value - ) - ) + if len(nodes) == 1: + config[key] = override_value + else: + next_key = nodes[1:] + _recursively_apply(_get_config_node(config, key), next_key, override_value) + return config + + +def _get_config_node(config: dict, key: str): + if key in config: + pass + else: + config[key] = None + return config[key] diff --git a/tests/test_override.py b/tests/test_override.py index 307173a4..13f4eb82 100644 --- a/tests/test_override.py +++ b/tests/test_override.py @@ -32,3 +32,9 @@ def test_recursive_override(minimal_config): cfg = {"colors": {"body": "red", "title": "green"}} cfg = recursively_apply(cfg, ["colors", "body"], "blue") assert cfg["colors"]["body"] == "blue" + + +def test_get_config_node(minimal_config): + assert len(minimal_config.keys()) == 3 + assert _get_config_node(minimal_config, "editor") == "vim" + assert _get_config_node(minimal_config, "display_format") == None From c31fa084f32dc12ef8b545b5af77bdcb44ad0ffc Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 24 Jan 2021 19:15:04 -0500 Subject: [PATCH 29/82] make format --- jrnl/override.py | 4 ++-- tests/test_override.py | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/jrnl/override.py b/jrnl/override.py index 10ba6c8d..a330b7a9 100644 --- a/jrnl/override.py +++ b/jrnl/override.py @@ -3,11 +3,11 @@ def apply_overrides(overrides: dict, base_config: dict) -> dict: config = base_config.copy() for k in overrides: nodes = k.split(".") - config = recursively_apply(config, nodes, overrides[k]) + config = _recursively_apply(config, nodes, overrides[k]) return config -def recursively_apply(config: dict, nodes: list, override_value) -> dict: +def _recursively_apply(config: dict, nodes: list, override_value) -> dict: """Recurse through configuration and apply overrides at the leaf of the config tree Credit to iJames on SO: https://stackoverflow.com/a/47276490 for algorithm diff --git a/tests/test_override.py b/tests/test_override.py index 13f4eb82..c6dc97a3 100644 --- a/tests/test_override.py +++ b/tests/test_override.py @@ -1,6 +1,6 @@ import pytest -from jrnl.override import apply_overrides, recursively_apply +from jrnl.override import apply_overrides, _recursively_apply, _get_config_node @pytest.fixture() @@ -27,10 +27,9 @@ def test_override_dot_notation(minimal_config): assert cfg["colors"] == {"body": "blue", "date": "green"} -def test_recursive_override(minimal_config): - +def test_recursively_apply(): cfg = {"colors": {"body": "red", "title": "green"}} - cfg = recursively_apply(cfg, ["colors", "body"], "blue") + cfg = _recursively_apply(cfg, ["colors", "body"], "blue") assert cfg["colors"]["body"] == "blue" From c8b737e4596be5303c7081f568fe7bc580254aba Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 06:56:12 -0500 Subject: [PATCH 30/82] code cleanup --- features/data/configs/tiny.yaml | 6 ++++++ features/overrides.feature | 4 ++-- features/steps/core.py | 1 - features/steps/override.py | 25 ++++++++++++++++--------- 4 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 features/data/configs/tiny.yaml diff --git a/features/data/configs/tiny.yaml b/features/data/configs/tiny.yaml new file mode 100644 index 00000000..bbcb4847 --- /dev/null +++ b/features/data/configs/tiny.yaml @@ -0,0 +1,6 @@ +journals: + default: /tmp/journal.jrnl +colors: + body: none + title: green +editor: "vim" diff --git a/features/overrides.feature b/features/overrides.feature index 07dd5a24..7739f339 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -31,6 +31,6 @@ Then the output should be """ Scenario: Override color selections with runtime overrides -Given we use the config "editor.yaml" -When we run jrnl with "-1 --config-override '{"colors.body": "blue"}' " +Given we use the config "tiny.yaml" +When we run jrnl with -1 --config-override '{"colors.body": "blue"}' Then the runtime config should have colors.body set to blue diff --git a/features/steps/core.py b/features/steps/core.py index 5f87ab73..abf66bb4 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -13,7 +13,6 @@ from behave import given from behave import then from behave import when import keyring -import mock import toml import yaml diff --git a/features/steps/override.py b/features/steps/override.py index b1ddb31a..dccc10fb 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -1,3 +1,5 @@ +from jrnl import override +from jrnl.jrnl import run from jrnl.os_compat import split_args from unittest import mock @@ -9,27 +11,29 @@ import yaml from yaml.loader import FullLoader import jrnl -from jrnl.override import apply_overrides, _recursively_apply from jrnl.cli import cli -from jrnl.jrnl import run @given("we use the config {config_file}") def load_config(context, config_file): filepath = os.path.join("features/configs", config_file) context.config_path = os.path.abspath(filepath) - with open(context.config_path) as cfg: - context.config = yaml.load(cfg, Loader=FullLoader) + @when("we run jrnl with {args}") def run_command(context, args): context.args = split_args("%s" % args) context.parser = parse_args(context.args) + with open(context.config_path,'r') as f: + cfg = yaml.load(f,Loader=FullLoader) + context.cfg = cfg @then("the runtime config should have {key_as_dots} set to {override_value}") def config_override(context, key_as_dots: str, override_value: str): + key_as_vec = key_as_dots.split('.') + with open(context.config_path) as f: loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) loaded_cfg["journal"] = "features/journals/simple.journal" @@ -41,14 +45,17 @@ def config_override(context, key_as_dots: str, override_value: str): # fmt: off try: with \ - mock.patch.object(jrnl.override,"recursively_apply",wraps=jrnl.override.recursively_apply) as mock_recurse, \ + mock.patch.object(jrnl.override,"_recursively_apply",wraps=jrnl.override._recursively_apply) as mock_recurse, \ mock.patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ mock.patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ : - cli(['-1','--config-override', '{"%s": "%s"}'%(key_as_dots,override_value)]) - mock_recurse.assert_called() - - + run(context.parser) + call_list = [ + mock.call(context.cfg, key_as_vec, override_value), + mock.call(context.cfg[key_as_vec[0]], key_as_vec[1], override_value) + ] + assert mock_recurse.call_count == 2 + mock_recurse.assert_has_calls(call_list, any_order=False) except SystemExit as e : context.exit_status = e.code # fmt: on From e173e12edfb847aadcec478faf8b0b2a0bcb745a Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 06:59:00 -0500 Subject: [PATCH 31/82] remove unused import --- features/steps/override.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/features/steps/override.py b/features/steps/override.py index dccc10fb..1b10e787 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -1,4 +1,4 @@ -from jrnl import override + from jrnl.jrnl import run from jrnl.os_compat import split_args from unittest import mock @@ -18,21 +18,20 @@ from jrnl.cli import cli def load_config(context, config_file): filepath = os.path.join("features/configs", config_file) context.config_path = os.path.abspath(filepath) - @when("we run jrnl with {args}") def run_command(context, args): context.args = split_args("%s" % args) context.parser = parse_args(context.args) - with open(context.config_path,'r') as f: - cfg = yaml.load(f,Loader=FullLoader) - context.cfg = cfg + with open(context.config_path, "r") as f: + cfg = yaml.load(f, Loader=FullLoader) + context.cfg = cfg @then("the runtime config should have {key_as_dots} set to {override_value}") def config_override(context, key_as_dots: str, override_value: str): - key_as_vec = key_as_dots.split('.') + key_as_vec = key_as_dots.split(".") with open(context.config_path) as f: loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) From 5da5027af220b01ebeee5a7b977a268fc86acc34 Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 07:10:56 -0500 Subject: [PATCH 32/82] update test config --- features/data/configs/tiny.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/features/data/configs/tiny.yaml b/features/data/configs/tiny.yaml index bbcb4847..e9da7943 100644 --- a/features/data/configs/tiny.yaml +++ b/features/data/configs/tiny.yaml @@ -4,3 +4,4 @@ colors: body: none title: green editor: "vim" +encrypt: false From 9f8be334fd95ef911ac67f7ee2e0e0022ab282ab Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 07:11:17 -0500 Subject: [PATCH 33/82] rewrite test for better mock call expect --- features/steps/override.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/features/steps/override.py b/features/steps/override.py index 1b10e787..13ca921f 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -32,11 +32,14 @@ def run_command(context, args): @then("the runtime config should have {key_as_dots} set to {override_value}") def config_override(context, key_as_dots: str, override_value: str): key_as_vec = key_as_dots.split(".") - + expected_call_args_list = [ + (context.cfg, key_as_vec, override_value), + (context.cfg[key_as_vec[0]], key_as_vec[1], override_value) + ] with open(context.config_path) as f: loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) loaded_cfg["journal"] = "features/journals/simple.journal" - # base_cfg = loaded_cfg.copy() + def _mock_callback(**args): print("callback executed") @@ -45,16 +48,15 @@ def config_override(context, key_as_dots: str, override_value: str): try: with \ mock.patch.object(jrnl.override,"_recursively_apply",wraps=jrnl.override._recursively_apply) as mock_recurse, \ + mock.patch('jrnl.install.load_or_install_jrnl', return_value=context.cfg), \ mock.patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ mock.patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ : run(context.parser) - call_list = [ - mock.call(context.cfg, key_as_vec, override_value), - mock.call(context.cfg[key_as_vec[0]], key_as_vec[1], override_value) - ] + assert mock_recurse.call_count == 2 - mock_recurse.assert_has_calls(call_list, any_order=False) + mock_recurse.call_args_list = expected_call_args_list + except SystemExit as e : context.exit_status = e.code # fmt: on From 27a370ce86b2567a17d4e5006747b036963f7e1b Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 07:11:45 -0500 Subject: [PATCH 34/82] make format --- features/steps/override.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/features/steps/override.py b/features/steps/override.py index 13ca921f..a90ea686 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -1,4 +1,3 @@ - from jrnl.jrnl import run from jrnl.os_compat import split_args from unittest import mock @@ -32,14 +31,13 @@ def run_command(context, args): @then("the runtime config should have {key_as_dots} set to {override_value}") def config_override(context, key_as_dots: str, override_value: str): key_as_vec = key_as_dots.split(".") - expected_call_args_list = [ - (context.cfg, key_as_vec, override_value), - (context.cfg[key_as_vec[0]], key_as_vec[1], override_value) - ] + expected_call_args_list = [ + (context.cfg, key_as_vec, override_value), + (context.cfg[key_as_vec[0]], key_as_vec[1], override_value), + ] with open(context.config_path) as f: loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) loaded_cfg["journal"] = "features/journals/simple.journal" - def _mock_callback(**args): print("callback executed") From fe4f18951f12789fe7935716f21211aee111e657 Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 07:21:05 -0500 Subject: [PATCH 35/82] binary search misbehaving windows test --- features/overrides.feature | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/overrides.feature b/features/overrides.feature index 7739f339..51ce11d2 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -10,6 +10,7 @@ Given we use the config "editor.yaml" When we run "jrnl --config-override '{"editor": "nano"}'" Then the editor "nano" should have been called +@skip_win Scenario: Override configured linewrap with a value of 23 Given we use the config "editor.yaml" When we run "jrnl -2 --config-override '{"linewrap": 23}' --format fancy" @@ -30,6 +31,7 @@ Then the output should be ┖─────────────────────┘ """ +@skip_win Scenario: Override color selections with runtime overrides Given we use the config "tiny.yaml" When we run jrnl with -1 --config-override '{"colors.body": "blue"}' From bd61a78fbabc92089e6d3154e5422895e9c8fc93 Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 08:52:50 -0500 Subject: [PATCH 36/82] unittest multiple overrides --- features/steps/override.py | 2 +- tests/test_override.py | 17 ++++++++++++++++- tests/test_parse_args.py | 11 +++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/features/steps/override.py b/features/steps/override.py index a90ea686..6ecbc8dc 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -52,7 +52,7 @@ def config_override(context, key_as_dots: str, override_value: str): : run(context.parser) - assert mock_recurse.call_count == 2 + assert mock_recurse.call_count >= 2 mock_recurse.call_args_list = expected_call_args_list except SystemExit as e : diff --git a/tests/test_override.py b/tests/test_override.py index c6dc97a3..0290385a 100644 --- a/tests/test_override.py +++ b/tests/test_override.py @@ -9,6 +9,10 @@ def minimal_config(): "colors": {"body": "red", "date": "green"}, "default": "/tmp/journal.jrnl", "editor": "vim", + "journals": { + "default": "/tmp/journals/journal.jrnl" + } + } yield cfg @@ -26,6 +30,17 @@ def test_override_dot_notation(minimal_config): cfg = apply_overrides(overrides=overrides, base_config=cfg) assert cfg["colors"] == {"body": "blue", "date": "green"} +def test_multiple_overrides(minimal_config): + overrides = { + "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.copy()) + assert cfg["editor"] == "nano" + assert cfg["colors"]["title"] == "magenta" + assert "burner" in cfg["journals"] + assert cfg["journals"]["burner"] == "/tmp/journals/burner.jrnl" def test_recursively_apply(): cfg = {"colors": {"body": "red", "title": "green"}} @@ -34,6 +49,6 @@ def test_recursively_apply(): def test_get_config_node(minimal_config): - assert len(minimal_config.keys()) == 3 + assert len(minimal_config.keys()) == 4 assert _get_config_node(minimal_config, "editor") == "vim" assert _get_config_node(minimal_config, "display_format") == None diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index f713d90b..67931892 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -1,3 +1,4 @@ +from features.steps.override import config_override import shlex import pytest @@ -218,6 +219,16 @@ def test_color_override(): '--config-override \'{"colors.body": "blue"}\'' ) == expected_args(config_override={"colors.body": "blue"}) +def test_multiple_overrides(): + assert cli_as_dict( + '--config-override \'{"colors.title": "green", "editor":"", "journal.scratchpad": "/tmp/scratchpad"}\'' + ) == expected_args( + config_override={ + "colors.title": "green", + "journal.scratchpad": "/tmp/scratchpad", + "editor": "" + } + ) # @see https://github.com/jrnl-org/jrnl/issues/520 @pytest.mark.parametrize( From ba8db5ddf62bc3ed8264132b44c8743a6b2678e7 Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 08:53:20 -0500 Subject: [PATCH 37/82] uncomment dot notation unittest --- tests/test_config.py | 50 ++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index d83d654d..2c8a5eff 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -10,16 +10,25 @@ from jrnl import install @pytest.fixture() def minimal_config(): - with open("features/data/configs/editor.yaml", "r") as cfg_file: - cfg = yaml.load(cfg_file.read(), Loader=yaml.FullLoader) + cfg = { + "colors": {"body": "red", "date": "green"}, + "default": "/tmp/journal.jrnl", + "editor": "vim", + "encrypt": False, + "journals": { + "default": "/tmp/journals/journal.jrnl" + } + + } yield cfg + @pytest.fixture() def expected_override(minimal_config): exp_out_cfg = minimal_config.copy() exp_out_cfg["editor"] = "nano" - exp_out_cfg["journal"] = "features/journals/simple.journal" + exp_out_cfg["journal"] = "/tmp/journals/journal.jrnl" yield exp_out_cfg @@ -61,17 +70,32 @@ def test_override_configured_editor( @pytest.fixture() def expected_color_override(minimal_config): exp_out_cfg = minimal_config.copy() - exp_out_cfg["colors"] = {"body": "blue"} - exp_out_cfg["journal"] = "features/journals/simple.journal" + exp_out_cfg["colors"]["body"] = "blue" + exp_out_cfg["journal"] = "/tmp/journals/journal.jrnl" yield exp_out_cfg -# @mock.patch.object(install,'load_or_install_jrnl') -# @mock.patch('subprocess.call') -# def test_override_configured_colors(mock_load_or_install, mock_subprocess_call, minimal_config, expected_color_override, capsys): -# mock_load_or_install.return_value = minimal_config +@mock.patch("sys.stdin.isatty") +@mock.patch("jrnl.install.load_or_install_jrnl", wraps=jrnl.install.load_or_install_jrnl) +@mock.patch("subprocess.call") +def test_override_configured_colors( + mock_isatty, + mock_load_or_install, + mock_subprocess_call, + minimal_config, + expected_color_override, + capsys, +): + mock_load_or_install.return_value = minimal_config -# cli_args=["--config-override",'{"colors.body": "blue"}'] -# parser = parse_args(cli_args) -# assert "colors.body" in parser.config_override.keys() -# run(parser) + cli_args = ["--config-override", '{"colors.body": "blue"}'] + parser = parse_args(cli_args) + assert "colors.body" in parser.config_override.keys() + with mock.patch.object( + jrnl, + "_write_in_editor", + side_effect= print("side effect!"), + return_value="note_contents", + ) as mock_write_in_editor: + run(parser) + mock_write_in_editor.assert_called_once_with(expected_color_override) From 7a54e6f45808639922c1454b02d5985388d7f17d Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 08:53:35 -0500 Subject: [PATCH 38/82] add multiple override scenario spec --- features/overrides.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/overrides.feature b/features/overrides.feature index 51ce11d2..0aa84d8c 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -36,3 +36,10 @@ Scenario: Override color selections with runtime overrides Given we use the config "tiny.yaml" When we run jrnl with -1 --config-override '{"colors.body": "blue"}' Then the runtime config should have colors.body set to blue + +@skip_win +Scenario: Apply multiple config overrides +Given we use the config "tiny.yaml" +When we run jrnl with -1 --config-override '{"colors.body": "green", "editor": "nano"}' +Then the runtime config should have colors.body set to green +And the runtime config should have editor set to nano From f1b260655d29ed187702e291ddba40452fd785a5 Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 08:55:27 -0500 Subject: [PATCH 39/82] make format --- tests/test_config.py | 20 ++++++++------------ tests/test_override.py | 21 ++++++++++----------- tests/test_parse_args.py | 6 ++++-- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index 2c8a5eff..20e1236a 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,11 +1,12 @@ import pytest - import mock import yaml + from jrnl.args import parse_args from jrnl.jrnl import run from jrnl import install +from jrnl import jrnl @pytest.fixture() @@ -15,15 +16,11 @@ def minimal_config(): "default": "/tmp/journal.jrnl", "editor": "vim", "encrypt": False, - "journals": { - "default": "/tmp/journals/journal.jrnl" - } - + "journals": {"default": "/tmp/journals/journal.jrnl"}, } yield cfg - @pytest.fixture() def expected_override(minimal_config): exp_out_cfg = minimal_config.copy() @@ -32,9 +29,6 @@ def expected_override(minimal_config): yield exp_out_cfg -from jrnl import jrnl - - @mock.patch("sys.stdin.isatty") @mock.patch.object(install, "load_or_install_jrnl") @mock.patch("subprocess.call") @@ -70,13 +64,15 @@ def test_override_configured_editor( @pytest.fixture() def expected_color_override(minimal_config): exp_out_cfg = minimal_config.copy() - exp_out_cfg["colors"]["body"] = "blue" + exp_out_cfg["colors"]["body"] = "blue" exp_out_cfg["journal"] = "/tmp/journals/journal.jrnl" yield exp_out_cfg @mock.patch("sys.stdin.isatty") -@mock.patch("jrnl.install.load_or_install_jrnl", wraps=jrnl.install.load_or_install_jrnl) +@mock.patch( + "jrnl.install.load_or_install_jrnl", wraps=jrnl.install.load_or_install_jrnl +) @mock.patch("subprocess.call") def test_override_configured_colors( mock_isatty, @@ -94,7 +90,7 @@ def test_override_configured_colors( with mock.patch.object( jrnl, "_write_in_editor", - side_effect= print("side effect!"), + side_effect=print("side effect!"), return_value="note_contents", ) as mock_write_in_editor: run(parser) diff --git a/tests/test_override.py b/tests/test_override.py index 0290385a..5303d78c 100644 --- a/tests/test_override.py +++ b/tests/test_override.py @@ -9,10 +9,7 @@ def minimal_config(): "colors": {"body": "red", "date": "green"}, "default": "/tmp/journal.jrnl", "editor": "vim", - "journals": { - "default": "/tmp/journals/journal.jrnl" - } - + "journals": {"default": "/tmp/journals/journal.jrnl"}, } yield cfg @@ -30,18 +27,20 @@ def test_override_dot_notation(minimal_config): cfg = apply_overrides(overrides=overrides, base_config=cfg) assert cfg["colors"] == {"body": "blue", "date": "green"} -def test_multiple_overrides(minimal_config): - overrides = { - "colors.title": "magenta", - "editor": "nano", - "journals.burner": "/tmp/journals/burner.jrnl" - } # as returned by parse_args, saved in parser.config_override + +def test_multiple_overrides(minimal_config): + overrides = { + "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.copy()) - assert cfg["editor"] == "nano" + assert cfg["editor"] == "nano" assert cfg["colors"]["title"] == "magenta" assert "burner" in cfg["journals"] assert cfg["journals"]["burner"] == "/tmp/journals/burner.jrnl" + def test_recursively_apply(): cfg = {"colors": {"body": "red", "title": "green"}} cfg = _recursively_apply(cfg, ["colors", "body"], "blue") diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index 67931892..6ce40338 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -219,17 +219,19 @@ def test_color_override(): '--config-override \'{"colors.body": "blue"}\'' ) == expected_args(config_override={"colors.body": "blue"}) -def test_multiple_overrides(): + +def test_multiple_overrides(): assert cli_as_dict( '--config-override \'{"colors.title": "green", "editor":"", "journal.scratchpad": "/tmp/scratchpad"}\'' ) == expected_args( config_override={ "colors.title": "green", "journal.scratchpad": "/tmp/scratchpad", - "editor": "" + "editor": "", } ) + # @see https://github.com/jrnl-org/jrnl/issues/520 @pytest.mark.parametrize( "cli", From 3ea043899a9a25737de4fa966f851c204af6dc6a Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 09:57:19 -0500 Subject: [PATCH 40/82] make format --- tests/test_override.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_override.py b/tests/test_override.py index 5303d78c..b7bc0a4a 100644 --- a/tests/test_override.py +++ b/tests/test_override.py @@ -34,6 +34,7 @@ def test_multiple_overrides(minimal_config): "editor": "nano", "journals.burner": "/tmp/journals/burner.jrnl", } # as returned by parse_args, saved in parser.config_override + cfg = apply_overrides(overrides, minimal_config.copy()) assert cfg["editor"] == "nano" assert cfg["colors"]["title"] == "magenta" From 432e76698e81adbc951842100a2ac948e715dc70 Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 20:32:42 -0500 Subject: [PATCH 41/82] update unittests for new syntax --- tests/test_config.py | 5 +++-- tests/test_parse_args.py | 36 +++++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index 20e1236a..fa0009a1 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,3 +1,4 @@ +import shlex import pytest import mock @@ -43,7 +44,7 @@ def test_override_configured_editor( mock_load_or_install.return_value = minimal_config mock_isatty.return_value = True - cli_args = ["--config-override", '{"editor": "nano"}'] + cli_args = shlex.split('--config-override editor:"nano"') parser = parse_args(cli_args) assert parser.config_override.__len__() == 1 assert "editor" in parser.config_override.keys() @@ -84,7 +85,7 @@ def test_override_configured_colors( ): mock_load_or_install.return_value = minimal_config - cli_args = ["--config-override", '{"colors.body": "blue"}'] + cli_args = shlex.split('--config-override colors.body:blue') parser = parse_args(cli_args) assert "colors.body" in parser.config_override.keys() with mock.patch.object( diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index 6ce40338..e1df5c29 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -36,7 +36,7 @@ def expected_args(**kwargs): "strict": False, "tags": False, "text": [], - "config_override": {}, + "config_override": None, } return {**default_args, **kwargs} @@ -206,28 +206,46 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) +@pytest.mark.parametrize( + "input_str", + [ + 'editor:"nano", colors.title:blue, default:"/tmp/egg.txt"', + 'editor:"vi -c startinsert", colors.title:blue, default:"/tmp/egg.txt"', + 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"' + ] +) +def test_deserialize_config_args(input_str): + from jrnl.args import deserialize_config_args + + runtime_config = deserialize_config_args(input_str) + assert runtime_config.__class__ == dict + assert "editor" in runtime_config.keys() + assert "colors.title" in runtime_config.keys() + assert "default" in runtime_config.keys() def test_editor_override(): - assert cli_as_dict('--config-override \'{"editor": "nano"}\'') == expected_args( + parsed_args = cli_as_dict('--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"}\'' + '--config-override colors.body:blue' ) == expected_args(config_override={"colors.body": "blue"}) def test_multiple_overrides(): - assert cli_as_dict( - '--config-override \'{"colors.title": "green", "editor":"", "journal.scratchpad": "/tmp/scratchpad"}\'' - ) == expected_args( + parsed_args = cli_as_dict( + '--config-override colors.title:green,editor:"nano",journal.scratchpad:"/tmp/scratchpad"' + ) + assert parsed_args == expected_args( config_override={ - "colors.title": "green", - "journal.scratchpad": "/tmp/scratchpad", - "editor": "", + 'colors.title': 'green', + 'journal.scratchpad': '/tmp/scratchpad', + 'editor': 'nano', } ) From 0b61c6d699cb44cef9968f3ee1728db4cf718d42 Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 20:33:01 -0500 Subject: [PATCH 42/82] update integ tests for new syntax --- features/overrides.feature | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/features/overrides.feature b/features/overrides.feature index 0aa84d8c..3ad42b60 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -2,18 +2,23 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys Scenario: Override configured editor with built-in input === editor:'' Given we use the config "editor-args.yaml" -When we run "jrnl --config-override '{"editor": ""}'" +When we run jrnl with --config-override editor:"" Then the editor "" should have been called -Scenario: Override configured editor with 'nano' +Scenario Outline: Override configured editor Given we use the config "editor.yaml" -When we run "jrnl --config-override '{"editor": "nano"}'" -Then the editor "nano" should have been called +When we run jrnl with --config-override editor:"" +Then the editor "" should have been called +Examples: Editor Commands +|editor| +|nano| +|vi -c startinsert| +|code -w - | @skip_win Scenario: Override configured linewrap with a value of 23 Given we use the config "editor.yaml" -When we run "jrnl -2 --config-override '{"linewrap": 23}' --format fancy" +When we run "jrnl -2 --config-override linewrap:23 --format fancy" Then the output should be """ ┎─────╮2013-06-09 15:39 @@ -34,12 +39,12 @@ Then the output should be @skip_win Scenario: Override color selections with runtime overrides Given we use the config "tiny.yaml" -When we run jrnl with -1 --config-override '{"colors.body": "blue"}' +When we run jrnl with -1 --config-override colors.body:blue' Then the runtime config should have colors.body set to blue @skip_win Scenario: Apply multiple config overrides Given we use the config "tiny.yaml" -When we run jrnl with -1 --config-override '{"colors.body": "green", "editor": "nano"}' +When we run jrnl with -1 --config-override colors.body:green,editor:"nano" Then the runtime config should have colors.body set to green And the runtime config should have editor set to nano From 1578fef220a2406685d0a057d9aa41ed9babda55 Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 21:02:39 -0500 Subject: [PATCH 43/82] update gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5e11d85b..629a9504 100644 --- a/.gitignore +++ b/.gitignore @@ -58,4 +58,5 @@ site/ .vscode/settings.json coverage.xml .vscode/launch.json -.coverage \ No newline at end of file +.coverage +.vscode/tasks.json \ No newline at end of file From 9ac21b84481727b295855ac76fcc9c1c250b08a5 Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 21:03:19 -0500 Subject: [PATCH 44/82] guard override application --- jrnl/jrnl.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index fdc8c87b..25fd191a 100644 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -16,6 +16,7 @@ from .editor import get_text_from_editor from .editor import get_text_from_stdin from .exception import UserAbort from . import time +from .override import apply_overrides def run(args): @@ -51,9 +52,8 @@ def run(args): # Apply config overrides overrides = args.config_override - from .override import apply_overrides - - config = apply_overrides(overrides, config) + if overrides: + config = apply_overrides(overrides, config) # --- All the standalone commands are now done --- # From bf891095255149f352ecb9fef74835418e21c236 Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 21:04:10 -0500 Subject: [PATCH 45/82] deserialize function as return type --- jrnl/args.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/jrnl/args.py b/jrnl/args.py index 99489b74..2c11952f 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -17,7 +17,14 @@ from .plugins import EXPORT_FORMATS from .plugins import IMPORT_FORMATS from .plugins import util - +def deserialize_config_args(input: str) -> dict: + _kvpairs = input.strip(' ').split(',') + runtime_modifications = {} + for _p in _kvpairs: + l,r = _p.strip().split(':') + runtime_modifications[l] = r + return runtime_modifications + class WrappingFormatter(argparse.RawTextHelpFormatter): """Used in help screen""" @@ -323,9 +330,9 @@ def parse_args(args=[]): "--config-override", dest="config_override", action="store", - type=json.loads, + type=deserialize_config_args, nargs="?", - default={}, + default=None, metavar="CONFIG_KV_PAIR", help=""" Override configured key-value pairs with CONFIG_KV_PAIR for this command invocation only. @@ -342,4 +349,6 @@ def parse_args(args=[]): num = re.compile(r"^-(\d+)$") args = [num.sub(r"-n \1", arg) for arg in args] - return parser.parse_intermixed_args(args) + + parsed_args = parser.parse_intermixed_args(args) + return parsed_args From 3b74c2dec0312331632d00e5a1926fa1138ff6f3 Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 25 Jan 2021 21:04:47 -0500 Subject: [PATCH 46/82] make format --- jrnl/args.py | 15 ++++++++------- tests/test_config.py | 2 +- tests/test_parse_args.py | 28 ++++++++++++++-------------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/jrnl/args.py b/jrnl/args.py index 2c11952f..3d2ecaf9 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -17,14 +17,16 @@ from .plugins import EXPORT_FORMATS from .plugins import IMPORT_FORMATS from .plugins import util -def deserialize_config_args(input: str) -> dict: - _kvpairs = input.strip(' ').split(',') - runtime_modifications = {} - for _p in _kvpairs: - l,r = _p.strip().split(':') + +def deserialize_config_args(input: str) -> dict: + _kvpairs = input.strip(" ").split(",") + runtime_modifications = {} + for _p in _kvpairs: + l, r = _p.strip().split(":") runtime_modifications[l] = r return runtime_modifications - + + class WrappingFormatter(argparse.RawTextHelpFormatter): """Used in help screen""" @@ -349,6 +351,5 @@ def parse_args(args=[]): num = re.compile(r"^-(\d+)$") args = [num.sub(r"-n \1", arg) for arg in args] - parsed_args = parser.parse_intermixed_args(args) return parsed_args diff --git a/tests/test_config.py b/tests/test_config.py index fa0009a1..aa4d7079 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -85,7 +85,7 @@ def test_override_configured_colors( ): mock_load_or_install.return_value = minimal_config - cli_args = shlex.split('--config-override colors.body:blue') + cli_args = shlex.split("--config-override colors.body:blue") parser = parse_args(cli_args) assert "colors.body" in parser.config_override.keys() with mock.patch.object( diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index e1df5c29..5b02fbfc 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -206,35 +206,35 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) + @pytest.mark.parametrize( "input_str", [ 'editor:"nano", colors.title:blue, default:"/tmp/egg.txt"', 'editor:"vi -c startinsert", colors.title:blue, default:"/tmp/egg.txt"', - 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"' - ] + 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"', + ], ) -def test_deserialize_config_args(input_str): - from jrnl.args import deserialize_config_args - +def test_deserialize_config_args(input_str): + from jrnl.args import deserialize_config_args + runtime_config = deserialize_config_args(input_str) assert runtime_config.__class__ == dict assert "editor" in runtime_config.keys() assert "colors.title" in runtime_config.keys() assert "default" in runtime_config.keys() + 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"}) + assert cli_as_dict("--config-override colors.body:blue") == expected_args( + config_override={"colors.body": "blue"} + ) def test_multiple_overrides(): @@ -243,9 +243,9 @@ def test_multiple_overrides(): ) assert parsed_args == expected_args( config_override={ - 'colors.title': 'green', - 'journal.scratchpad': '/tmp/scratchpad', - 'editor': 'nano', + "colors.title": "green", + "journal.scratchpad": "/tmp/scratchpad", + "editor": "nano", } ) From abbb2c502f2a5546fb8f1f8ee4a0812cc2652c3c Mon Sep 17 00:00:00 2001 From: Suhas Date: Wed, 27 Jan 2021 18:09:10 -0500 Subject: [PATCH 47/82] organize deserialization unittests --- tests/test_parse_args.py | 44 +++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index 5b02fbfc..8e314aad 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -4,7 +4,7 @@ import shlex import pytest from jrnl.args import parse_args - +from jrnl.args import deserialize_config_args def cli_as_dict(str): cli = shlex.split(str) @@ -206,24 +206,36 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) +class TestDeserialization: + @pytest.mark.parametrize( + "input_str", + [ + 'editor:"nano", colors.title:blue, default:"/tmp/egg.txt"', + 'editor:"vi -c startinsert", colors.title:blue, default:"/tmp/egg.txt"', + 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"', + ], + ) + def test_deserialize_multiword_strings(self,input_str): + -@pytest.mark.parametrize( - "input_str", - [ - 'editor:"nano", colors.title:blue, default:"/tmp/egg.txt"', - 'editor:"vi -c startinsert", colors.title:blue, default:"/tmp/egg.txt"', - 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"', - ], -) -def test_deserialize_config_args(input_str): - from jrnl.args import deserialize_config_args + runtime_config = deserialize_config_args(input_str) + assert runtime_config.__class__ == dict + assert "editor" in runtime_config.keys() + assert "colors.title" in runtime_config.keys() + assert "default" in runtime_config.keys() - runtime_config = deserialize_config_args(input_str) - assert runtime_config.__class__ == dict - assert "editor" in runtime_config.keys() - assert "colors.title" in runtime_config.keys() - assert "default" in runtime_config.keys() + def test_deserialize_int(self): + input = 'linewrap: 23, default_hour: 19' + runtime_config = deserialize_config_args(input) + assert runtime_config['linewrap'] == 23 + assert runtime_config['default_hour'] == 19 + def test_deserialize_multiple_datatypes(self): + input = 'linewrap: 23, encrypt: false, editor:"vi -c startinsert"' + cfg = deserialize_config_args(input) + assert cfg['encrypt'] == False + assert cfg['linewrap'] == 23 + assert cfg['editor'] == '"vi -c startinsert"' def test_editor_override(): From 0f5dfade18ea3378a441a01530cf1da16644cafa Mon Sep 17 00:00:00 2001 From: Suhas Date: Wed, 27 Jan 2021 18:13:10 -0500 Subject: [PATCH 48/82] better, more specific behave tests --- features/steps/override.py | 81 +++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/features/steps/override.py b/features/steps/override.py index 6ecbc8dc..b0edc864 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -1,3 +1,5 @@ +from tests.test_config import expected_override +from jrnl.editor import get_text_from_stdin from jrnl.jrnl import run from jrnl.os_compat import split_args from unittest import mock @@ -10,7 +12,16 @@ import yaml from yaml.loader import FullLoader import jrnl -from jrnl.cli import cli +def _mock_time_parse(context): + original_parse = jrnl.time.parse + if "now" not in context: + return original_parse + + def wrapper(input, *args, **kwargs): + input = context.now if input == "now" else input + return original_parse(input, *args, **kwargs) + + return wrapper @given("we use the config {config_file}") @@ -31,13 +42,9 @@ def run_command(context, args): @then("the runtime config should have {key_as_dots} set to {override_value}") def config_override(context, key_as_dots: str, override_value: str): key_as_vec = key_as_dots.split(".") - expected_call_args_list = [ - (context.cfg, key_as_vec, override_value), - (context.cfg[key_as_vec[0]], key_as_vec[1], override_value), - ] - with open(context.config_path) as f: - loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) - loaded_cfg["journal"] = "features/journals/simple.journal" + # with open(context.config_path) as f: + # loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) + # loaded_cfg["journal"] = "features/journals/simple.journal" def _mock_callback(**args): print("callback executed") @@ -45,16 +52,20 @@ def config_override(context, key_as_dots: str, override_value: str): # fmt: off try: with \ + mock.patch("jrnl.jrnl.search_mode"), \ mock.patch.object(jrnl.override,"_recursively_apply",wraps=jrnl.override._recursively_apply) as mock_recurse, \ mock.patch('jrnl.install.load_or_install_jrnl', return_value=context.cfg), \ + mock.patch('jrnl.time.parse', side_effect=_mock_time_parse(context)), \ mock.patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ mock.patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ : run(context.parser) - - assert mock_recurse.call_count >= 2 - mock_recurse.call_args_list = expected_call_args_list - + runtime_cfg = mock_recurse.call_args_list[0][0][0] + assert mock_recurse.call_count == key_as_vec.__len__() + for k in key_as_vec: + runtime_cfg = runtime_cfg['%s'%k] + + assert runtime_cfg == override_value except SystemExit as e : context.exit_status = e.code # fmt: on @@ -62,27 +73,49 @@ def config_override(context, key_as_dots: str, override_value: str): @then("the editor {editor} should have been called") def editor_override(context, editor): - def _mock_editor(command_and_journal_file): - editor = command_and_journal_file[0] - tmpfile = command_and_journal_file[-1] - context.tmpfile = tmpfile - print("%s has been launched" % editor) - return tmpfile - + + def _mock_write_in_editor(config): + editor = config['editor'] + journal = '/tmp/journal.jrnl' + context.tmpfile = journal + print("%s has been launched"%editor) + return journal + + # fmt: off # see: https://github.com/psf/black/issues/664 with \ - mock.patch("subprocess.call", side_effect=_mock_editor) as mock_editor, \ + mock.patch("jrnl.jrnl._write_in_editor", side_effect=_mock_write_in_editor(context.cfg)) as mock_write_in_editor, \ mock.patch("sys.stdin.isatty", return_value=True), \ - mock.patch("jrnl.time.parse"), \ + mock.patch("jrnl.time.parse", side_effect = _mock_time_parse(context)), \ mock.patch("jrnl.config.get_config_path", side_effect=lambda: context.config_path), \ mock.patch("jrnl.install.get_config_path", side_effect=lambda: context.config_path) \ : try : - cli(['--config-override','{"editor": "%s"}'%editor]) + run(context.parser) context.exit_status = 0 - context.editor = mock_editor - assert mock_editor.assert_called_once_with(editor, context.tmpfile) + context.editor = mock_write_in_editor + expected_config = context.cfg + expected_config['editor'] = '%s'%editor + expected_config['journal'] ='/tmp/journal.jrnl' + + assert mock_write_in_editor.call_count == 1 + assert mock_write_in_editor.call_args[0][0]['editor']==editor except SystemExit as e: context.exit_status = e.code # fmt: on + +@then("the stdin prompt must be launched") +def override_editor_to_use_stdin(context): + + try: + with \ + mock.patch('sys.stdin.read', return_value='Zwei peanuts walk into a bar und one of zem was a-salted')as mock_stdin_read, \ + mock.patch("jrnl.install.load_or_install_jrnl", return_value=context.cfg), \ + mock.patch("jrnl.Journal.open_journal", spec=False, return_value='/tmp/journal.jrnl'): + run(context.parser) + context.exit_status = 0 + mock_stdin_read.assert_called_once() + + except SystemExit as e : + context.exit_status = e.code \ No newline at end of file From b2a60fd297e620f441d76bbce8e6f38c51f491db Mon Sep 17 00:00:00 2001 From: Suhas Date: Wed, 27 Jan 2021 18:14:00 -0500 Subject: [PATCH 49/82] test different editor launch commands --- features/overrides.feature | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/features/overrides.feature b/features/overrides.feature index 3ad42b60..1f8b3036 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -48,3 +48,12 @@ Given we use the config "tiny.yaml" When we run jrnl with -1 --config-override colors.body:green,editor:"nano" Then the runtime config should have colors.body set to green And the runtime config should have editor set to nano + Scenario Outline: Override configured editor + Given we use the config "tiny.yaml" + When we run jrnl with --config-override editor:"" + Then the editor should have been called + Examples: Editor Commands + | editor | + | nano | + | vi -c startinsert | + | code -w - | From e85300eced5644fd525efdc6f2de5e80e379c6bb Mon Sep 17 00:00:00 2001 From: Suhas Date: Wed, 27 Jan 2021 18:14:08 -0500 Subject: [PATCH 50/82] formatting --- features/overrides.feature | 82 ++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 44 deletions(-) diff --git a/features/overrides.feature b/features/overrides.feature index 1f8b3036..80fdf47c 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -1,53 +1,47 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys -Scenario: Override configured editor with built-in input === editor:'' -Given we use the config "editor-args.yaml" -When we run jrnl with --config-override editor:"" -Then the editor "" should have been called + Scenario: Override configured editor with built-in input === editor:'' + Given we use the config "tiny.yaml" + When we run jrnl with --config-override editor:'' + Then the stdin prompt must be launched -Scenario Outline: Override configured editor -Given we use the config "editor.yaml" -When we run jrnl with --config-override editor:"" -Then the editor "" should have been called -Examples: Editor Commands -|editor| -|nano| -|vi -c startinsert| -|code -w - | + @skip_win + Scenario: Override configured linewrap with a value of 23 + Given we use the config "tiny.yaml" + When we run "jrnl -2 --config-override linewrap:23 --format fancy" + Then the output should be -@skip_win -Scenario: Override configured linewrap with a value of 23 -Given we use the config "editor.yaml" -When we run "jrnl -2 --config-override linewrap:23 --format fancy" -Then the output should be -""" -┎─────╮2013-06-09 15:39 -┃ My ╘═══════════════╕ -┃ fir st ent ry. │ -┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ -┃ Everything is │ -┃ alright │ -┖─────────────────────┘ -┎─────╮2013-06-10 15:40 -┃ Lif ╘═══════════════╕ -┃ e is goo d. │ -┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ -┃ But I'm better. │ -┖─────────────────────┘ -""" + """ + ┎─────╮2013-06-09 15:39 + ┃ My ╘═══════════════╕ + ┃ fir st ent ry. │ + ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ + ┃ Everything is │ + ┃ alright │ + ┖─────────────────────┘ + ┎─────╮2013-06-10 15:40 + ┃ Lif ╘═══════════════╕ + ┃ e is goo d. │ + ┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ + ┃ But I'm better. │ + ┖─────────────────────┘ + """ + + @skip_win + @wip + Scenario: Override color selections with runtime overrides + Given we use the config "tiny.yaml" + When we run jrnl with -1 --config-override colors.body:blue + Then the runtime config should have colors.body set to blue + + @skip_win + Scenario: Apply multiple config overrides + Given we use the config "tiny.yaml" + When we run jrnl with -1 --config-override colors.body:green,editor:"nano" + Then the runtime config should have colors.body set to green + And the runtime config should have editor set to nano -@skip_win -Scenario: Override color selections with runtime overrides -Given we use the config "tiny.yaml" -When we run jrnl with -1 --config-override colors.body:blue' -Then the runtime config should have colors.body set to blue -@skip_win -Scenario: Apply multiple config overrides -Given we use the config "tiny.yaml" -When we run jrnl with -1 --config-override colors.body:green,editor:"nano" -Then the runtime config should have colors.body set to green -And the runtime config should have editor set to nano Scenario Outline: Override configured editor Given we use the config "tiny.yaml" When we run jrnl with --config-override editor:"" From 6daf4fb2eeff9712ac4ba59c012b12d4048b3680 Mon Sep 17 00:00:00 2001 From: Suhas Date: Wed, 27 Jan 2021 18:14:42 -0500 Subject: [PATCH 51/82] handle datatypes in deserialization and update helptext --- jrnl/args.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/jrnl/args.py b/jrnl/args.py index 3d2ecaf9..e1d73a8c 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -23,6 +23,13 @@ def deserialize_config_args(input: str) -> dict: runtime_modifications = {} for _p in _kvpairs: l, r = _p.strip().split(":") + r = r.strip() + if r.isdigit(): + r = int(r) + elif r.lower() == "true": + r = True + elif r.lower() == "false": + r = False runtime_modifications[l] = r return runtime_modifications @@ -341,9 +348,9 @@ def parse_args(args=[]): Examples: \n \t - Use a different editor for this jrnl entry, call: \n - \t jrnl --config-override '{"editor": "nano"}' \n + \t jrnl --config-override editor: "nano" \n \t - Override color selections\n - \t jrnl --config-override '{"colors.body":"blue", "colors.title": "green"} + \t jrnl --config-override colors.body: blue, colors.title: green """, ) From b8b56124eeb5ffad6f32a2f6bf22428b07b63ddb Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 08:36:44 -0500 Subject: [PATCH 52/82] stick to config convention in testbed --- features/data/configs/tiny.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/features/data/configs/tiny.yaml b/features/data/configs/tiny.yaml index e9da7943..578cd234 100644 --- a/features/data/configs/tiny.yaml +++ b/features/data/configs/tiny.yaml @@ -1,7 +1,8 @@ journals: - default: /tmp/journal.jrnl + default: features/journals/simple.journal colors: body: none title: green editor: "vim" encrypt: false +# \ No newline at end of file From 983c9c8c4b720ea75aa281f7de49b8c56c02f1ae Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 08:36:58 -0500 Subject: [PATCH 53/82] update tests ith better verifications --- features/overrides.feature | 1 - features/steps/override.py | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/features/overrides.feature b/features/overrides.feature index 80fdf47c..eef89eec 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -28,7 +28,6 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys """ @skip_win - @wip Scenario: Override color selections with runtime overrides Given we use the config "tiny.yaml" When we run jrnl with -1 --config-override colors.body:blue diff --git a/features/steps/override.py b/features/steps/override.py index b0edc864..df7d444c 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -61,7 +61,7 @@ def config_override(context, key_as_dots: str, override_value: str): : run(context.parser) runtime_cfg = mock_recurse.call_args_list[0][0][0] - assert mock_recurse.call_count == key_as_vec.__len__() + for k in key_as_vec: runtime_cfg = runtime_cfg['%s'%k] @@ -76,7 +76,7 @@ def editor_override(context, editor): def _mock_write_in_editor(config): editor = config['editor'] - journal = '/tmp/journal.jrnl' + journal = 'features/journals/journal.jrnl' context.tmpfile = journal print("%s has been launched"%editor) return journal @@ -97,7 +97,7 @@ def editor_override(context, editor): context.editor = mock_write_in_editor expected_config = context.cfg expected_config['editor'] = '%s'%editor - expected_config['journal'] ='/tmp/journal.jrnl' + expected_config['journal'] ='features/journals/journal.jrnl' assert mock_write_in_editor.call_count == 1 assert mock_write_in_editor.call_args[0][0]['editor']==editor @@ -112,7 +112,7 @@ def override_editor_to_use_stdin(context): with \ mock.patch('sys.stdin.read', return_value='Zwei peanuts walk into a bar und one of zem was a-salted')as mock_stdin_read, \ mock.patch("jrnl.install.load_or_install_jrnl", return_value=context.cfg), \ - mock.patch("jrnl.Journal.open_journal", spec=False, return_value='/tmp/journal.jrnl'): + mock.patch("jrnl.Journal.open_journal", spec=False, return_value='features/journals/journal.jrnl'): run(context.parser) context.exit_status = 0 mock_stdin_read.assert_called_once() From 528ce1efe227273ee4468d70acdbfcfd58396873 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 08:40:28 -0500 Subject: [PATCH 54/82] make format --- features/overrides.feature | 2 +- features/steps/override.py | 53 +++++++++++++++++++++----------------- jrnl/args.py | 11 ++++---- tests/test_config.py | 1 - tests/test_parse_args.py | 25 +++++++++--------- 5 files changed, 48 insertions(+), 44 deletions(-) diff --git a/features/overrides.feature b/features/overrides.feature index eef89eec..ec3a2d1b 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -36,7 +36,7 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys @skip_win Scenario: Apply multiple config overrides Given we use the config "tiny.yaml" - When we run jrnl with -1 --config-override colors.body:green,editor:"nano" + When we run jrnl with -1 --config-override colors.body:green, editor:"nano" Then the runtime config should have colors.body set to green And the runtime config should have editor set to nano diff --git a/features/steps/override.py b/features/steps/override.py index df7d444c..4c241eb4 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -1,5 +1,3 @@ -from tests.test_config import expected_override -from jrnl.editor import get_text_from_stdin from jrnl.jrnl import run from jrnl.os_compat import split_args from unittest import mock @@ -12,16 +10,18 @@ import yaml from yaml.loader import FullLoader import jrnl + + def _mock_time_parse(context): - original_parse = jrnl.time.parse - if "now" not in context: - return original_parse + original_parse = jrnl.time.parse + if "now" not in context: + return original_parse - def wrapper(input, *args, **kwargs): - input = context.now if input == "now" else input - return original_parse(input, *args, **kwargs) + def wrapper(input, *args, **kwargs): + input = context.now if input == "now" else input + return original_parse(input, *args, **kwargs) - return wrapper + return wrapper @given("we use the config {config_file}") @@ -73,15 +73,13 @@ def config_override(context, key_as_dots: str, override_value: str): @then("the editor {editor} should have been called") def editor_override(context, editor): - def _mock_write_in_editor(config): - editor = config['editor'] - journal = 'features/journals/journal.jrnl' + editor = config["editor"] + journal = "features/journals/journal.jrnl" context.tmpfile = journal - print("%s has been launched"%editor) + print("%s has been launched" % editor) return journal - - + # fmt: off # see: https://github.com/psf/black/issues/664 with \ @@ -105,17 +103,24 @@ def editor_override(context, editor): context.exit_status = e.code # fmt: on -@then("the stdin prompt must be launched") -def override_editor_to_use_stdin(context): - try: - with \ - mock.patch('sys.stdin.read', return_value='Zwei peanuts walk into a bar und one of zem was a-salted')as mock_stdin_read, \ - mock.patch("jrnl.install.load_or_install_jrnl", return_value=context.cfg), \ - mock.patch("jrnl.Journal.open_journal", spec=False, return_value='features/journals/journal.jrnl'): +@then("the stdin prompt must be launched") +def override_editor_to_use_stdin(context): + + try: + with mock.patch( + "sys.stdin.read", + return_value="Zwei peanuts walk into a bar und one of zem was a-salted", + ) as mock_stdin_read, mock.patch( + "jrnl.install.load_or_install_jrnl", return_value=context.cfg + ), mock.patch( + "jrnl.Journal.open_journal", + spec=False, + return_value="features/journals/journal.jrnl", + ): run(context.parser) context.exit_status = 0 mock_stdin_read.assert_called_once() - except SystemExit as e : - context.exit_status = e.code \ No newline at end of file + except SystemExit as e: + context.exit_status = e.code diff --git a/jrnl/args.py b/jrnl/args.py index e1d73a8c..f2ea288c 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -4,7 +4,6 @@ import argparse import re import textwrap -import json from .commands import postconfig_decrypt from .commands import postconfig_encrypt @@ -24,11 +23,11 @@ def deserialize_config_args(input: str) -> dict: for _p in _kvpairs: l, r = _p.strip().split(":") r = r.strip() - if r.isdigit(): - r = int(r) - elif r.lower() == "true": - r = True - elif r.lower() == "false": + if r.isdigit(): + r = int(r) + elif r.lower() == "true": + r = True + elif r.lower() == "false": r = False runtime_modifications[l] = r return runtime_modifications diff --git a/tests/test_config.py b/tests/test_config.py index aa4d7079..dc2650a8 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -2,7 +2,6 @@ import shlex import pytest import mock -import yaml from jrnl.args import parse_args from jrnl.jrnl import run diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index 8e314aad..a49c99cb 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -1,4 +1,3 @@ -from features.steps.override import config_override import shlex import pytest @@ -6,6 +5,7 @@ import pytest from jrnl.args import parse_args from jrnl.args import deserialize_config_args + def cli_as_dict(str): cli = shlex.split(str) args = parse_args(cli) @@ -206,6 +206,7 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) + class TestDeserialization: @pytest.mark.parametrize( "input_str", @@ -215,8 +216,7 @@ class TestDeserialization: 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"', ], ) - def test_deserialize_multiword_strings(self,input_str): - + def test_deserialize_multiword_strings(self, input_str): runtime_config = deserialize_config_args(input_str) assert runtime_config.__class__ == dict @@ -224,18 +224,19 @@ class TestDeserialization: assert "colors.title" in runtime_config.keys() assert "default" in runtime_config.keys() - def test_deserialize_int(self): - input = 'linewrap: 23, default_hour: 19' + def test_deserialize_int(self): + input = "linewrap: 23, default_hour: 19" runtime_config = deserialize_config_args(input) - assert runtime_config['linewrap'] == 23 - assert runtime_config['default_hour'] == 19 + assert runtime_config["linewrap"] == 23 + assert runtime_config["default_hour"] == 19 - def test_deserialize_multiple_datatypes(self): + def test_deserialize_multiple_datatypes(self): input = 'linewrap: 23, encrypt: false, editor:"vi -c startinsert"' - cfg = deserialize_config_args(input) - assert cfg['encrypt'] == False - assert cfg['linewrap'] == 23 - assert cfg['editor'] == '"vi -c startinsert"' + cfg = deserialize_config_args(input) + assert cfg["encrypt"] == False + assert cfg["linewrap"] == 23 + assert cfg["editor"] == '"vi -c startinsert"' + def test_editor_override(): From 52e146d12c7308b59f7dca5e28fe85a7e5b06d31 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 08:42:20 -0500 Subject: [PATCH 55/82] space --- features/overrides.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/overrides.feature b/features/overrides.feature index ec3a2d1b..eef89eec 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -36,7 +36,7 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys @skip_win Scenario: Apply multiple config overrides Given we use the config "tiny.yaml" - When we run jrnl with -1 --config-override colors.body:green, editor:"nano" + When we run jrnl with -1 --config-override colors.body:green,editor:"nano" Then the runtime config should have colors.body set to green And the runtime config should have editor set to nano From 31577ad0fc1ace170a1966a323fd0970a0a59484 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 08:51:09 -0500 Subject: [PATCH 56/82] review feedbac --- features/steps/override.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/features/steps/override.py b/features/steps/override.py index 4c241eb4..ac531235 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -42,10 +42,7 @@ def run_command(context, args): @then("the runtime config should have {key_as_dots} set to {override_value}") def config_override(context, key_as_dots: str, override_value: str): key_as_vec = key_as_dots.split(".") - # with open(context.config_path) as f: - # loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) - # loaded_cfg["journal"] = "features/journals/simple.journal" - + def _mock_callback(**args): print("callback executed") From e95ab585cfd4f0be6ba40f62aa2a98d94629eab4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Jan 2021 13:58:06 +0000 Subject: [PATCH 57/82] Bump pytest from 6.2.1 to 6.2.2 Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.1 to 6.2.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/6.2.1...6.2.2) Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 541f7e3a..bdbb15e6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -449,7 +449,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pytest" -version = "6.2.1" +version = "6.2.2" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -945,8 +945,8 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ - {file = "pytest-6.2.1-py3-none-any.whl", hash = "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8"}, - {file = "pytest-6.2.1.tar.gz", hash = "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306"}, + {file = "pytest-6.2.2-py3-none-any.whl", hash = "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839"}, + {file = "pytest-6.2.2.tar.gz", hash = "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9"}, ] pytest-cov = [ {file = "pytest-cov-2.11.1.tar.gz", hash = "sha256:359952d9d39b9f822d9d29324483e7ba04a3a17dd7d05aa6beb7ea01e359e5f7"}, From 5e4eb666204b47be3640799fc40f4c882ba6a245 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Jan 2021 13:58:18 +0000 Subject: [PATCH 58/82] Bump keyring from 21.8.0 to 22.0.1 Bumps [keyring](https://github.com/jaraco/keyring) from 21.8.0 to 22.0.1. - [Release notes](https://github.com/jaraco/keyring/releases) - [Changelog](https://github.com/jaraco/keyring/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/keyring/compare/v21.8.0...v22.0.1) Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 541f7e3a..9ef74f32 100644 --- a/poetry.lock +++ b/poetry.lock @@ -224,7 +224,7 @@ python-versions = ">=3.6" [[package]] name = "keyring" -version = "21.8.0" +version = "22.0.1" description = "Store and access your passwords safely." category = "main" optional = false @@ -238,7 +238,7 @@ SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "pytest-black (>=0.3.7)", "pytest-mypy"] [[package]] name = "livereload" @@ -841,8 +841,8 @@ joblib = [ {file = "joblib-1.0.0.tar.gz", hash = "sha256:7ad866067ac1fdec27d51c8678ea760601b70e32ff1881d4dc8e1171f2b64b24"}, ] keyring = [ - {file = "keyring-21.8.0-py3-none-any.whl", hash = "sha256:4be9cbaaaf83e61d6399f733d113ede7d1c73bc75cb6aeb64eee0f6ac39b30ea"}, - {file = "keyring-21.8.0.tar.gz", hash = "sha256:1746d3ac913d449a090caf11e9e4af00e26c3f7f7e81027872192b2398b98675"}, + {file = "keyring-22.0.1-py3-none-any.whl", hash = "sha256:9f44660a5d4931bdc14c08a1d01ef30b18a7a8147380710d8c9f9531e1f6c3c0"}, + {file = "keyring-22.0.1.tar.gz", hash = "sha256:9acb3e1452edbb7544822b12fd25459078769e560fa51f418b6d00afaa6178df"}, ] livereload = [ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, From 6e0a47ccf71075b0dad6afe3ce8203ea433ea7a7 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 08:58:24 -0500 Subject: [PATCH 59/82] make format --- features/steps/override.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/override.py b/features/steps/override.py index ac531235..d1857b0b 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -42,7 +42,7 @@ def run_command(context, args): @then("the runtime config should have {key_as_dots} set to {override_value}") def config_override(context, key_as_dots: str, override_value: str): key_as_vec = key_as_dots.split(".") - + def _mock_callback(**args): print("callback executed") From c4c4155826ffcee7b1925461b5e7074ef67d37cd Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 09:21:23 -0500 Subject: [PATCH 60/82] skip on win --- features/overrides.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/overrides.feature b/features/overrides.feature index eef89eec..4343cdb1 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -41,6 +41,7 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys And the runtime config should have editor set to nano + @skip_win Scenario Outline: Override configured editor Given we use the config "tiny.yaml" When we run jrnl with --config-override editor:"" From 206336651a9ebe4f60bd8430715a1976b2ad6c26 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 09:26:27 -0500 Subject: [PATCH 61/82] update deps --- poetry.lock | 114 ++++++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/poetry.lock b/poetry.lock index 541f7e3a..df676e25 100644 --- a/poetry.lock +++ b/poetry.lock @@ -129,7 +129,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "5.3.1" +version = "5.4" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -224,7 +224,7 @@ python-versions = ">=3.6" [[package]] name = "keyring" -version = "21.8.0" +version = "22.0.1" description = "Store and access your passwords safely." category = "main" optional = false @@ -238,7 +238,7 @@ SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "pytest-black (>=0.3.7)", "pytest-mypy"] [[package]] name = "livereload" @@ -449,7 +449,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pytest" -version = "6.2.1" +version = "6.2.2" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -751,55 +751,55 @@ colorama = [ {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] coverage = [ - {file = "coverage-5.3.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:fabeeb121735d47d8eab8671b6b031ce08514c86b7ad8f7d5490a7b6dcd6267d"}, - {file = "coverage-5.3.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:7e4d159021c2029b958b2363abec4a11db0ce8cd43abb0d9ce44284cb97217e7"}, - {file = "coverage-5.3.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:378ac77af41350a8c6b8801a66021b52da8a05fd77e578b7380e876c0ce4f528"}, - {file = "coverage-5.3.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e448f56cfeae7b1b3b5bcd99bb377cde7c4eb1970a525c770720a352bc4c8044"}, - {file = "coverage-5.3.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:cc44e3545d908ecf3e5773266c487ad1877be718d9dc65fc7eb6e7d14960985b"}, - {file = "coverage-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:08b3ba72bd981531fd557f67beee376d6700fba183b167857038997ba30dd297"}, - {file = "coverage-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:8dacc4073c359f40fcf73aede8428c35f84639baad7e1b46fce5ab7a8a7be4bb"}, - {file = "coverage-5.3.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ee2f1d1c223c3d2c24e3afbb2dd38be3f03b1a8d6a83ee3d9eb8c36a52bee899"}, - {file = "coverage-5.3.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9a9d4ff06804920388aab69c5ea8a77525cf165356db70131616acd269e19b36"}, - {file = "coverage-5.3.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:782a5c7df9f91979a7a21792e09b34a658058896628217ae6362088b123c8500"}, - {file = "coverage-5.3.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:fda29412a66099af6d6de0baa6bd7c52674de177ec2ad2630ca264142d69c6c7"}, - {file = "coverage-5.3.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:f2c6888eada180814b8583c3e793f3f343a692fc802546eed45f40a001b1169f"}, - {file = "coverage-5.3.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8f33d1156241c43755137288dea619105477961cfa7e47f48dbf96bc2c30720b"}, - {file = "coverage-5.3.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b239711e774c8eb910e9b1ac719f02f5ae4bf35fa0420f438cdc3a7e4e7dd6ec"}, - {file = "coverage-5.3.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:f54de00baf200b4539a5a092a759f000b5f45fd226d6d25a76b0dff71177a714"}, - {file = "coverage-5.3.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:be0416074d7f253865bb67630cf7210cbc14eb05f4099cc0f82430135aaa7a3b"}, - {file = "coverage-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:c46643970dff9f5c976c6512fd35768c4a3819f01f61169d8cdac3f9290903b7"}, - {file = "coverage-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9a4f66259bdd6964d8cf26142733c81fb562252db74ea367d9beb4f815478e72"}, - {file = "coverage-5.3.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c6e5174f8ca585755988bc278c8bb5d02d9dc2e971591ef4a1baabdf2d99589b"}, - {file = "coverage-5.3.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3911c2ef96e5ddc748a3c8b4702c61986628bb719b8378bf1e4a6184bbd48fe4"}, - {file = "coverage-5.3.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c5ec71fd4a43b6d84ddb88c1df94572479d9a26ef3f150cef3dacefecf888105"}, - {file = "coverage-5.3.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f51dbba78d68a44e99d484ca8c8f604f17e957c1ca09c3ebc2c7e3bbd9ba0448"}, - {file = "coverage-5.3.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:a2070c5affdb3a5e751f24208c5c4f3d5f008fa04d28731416e023c93b275277"}, - {file = "coverage-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:535dc1e6e68fad5355f9984d5637c33badbdc987b0c0d303ee95a6c979c9516f"}, - {file = "coverage-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:a4857f7e2bc6921dbd487c5c88b84f5633de3e7d416c4dc0bb70256775551a6c"}, - {file = "coverage-5.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fac3c432851038b3e6afe086f777732bcf7f6ebbfd90951fa04ee53db6d0bcdd"}, - {file = "coverage-5.3.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:cd556c79ad665faeae28020a0ab3bda6cd47d94bec48e36970719b0b86e4dcf4"}, - {file = "coverage-5.3.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a66ca3bdf21c653e47f726ca57f46ba7fc1f260ad99ba783acc3e58e3ebdb9ff"}, - {file = "coverage-5.3.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ab110c48bc3d97b4d19af41865e14531f300b482da21783fdaacd159251890e8"}, - {file = "coverage-5.3.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e52d3d95df81c8f6b2a1685aabffadf2d2d9ad97203a40f8d61e51b70f191e4e"}, - {file = "coverage-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:fa10fee7e32213f5c7b0d6428ea92e3a3fdd6d725590238a3f92c0de1c78b9d2"}, - {file = "coverage-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ce6f3a147b4b1a8b09aae48517ae91139b1b010c5f36423fa2b866a8b23df879"}, - {file = "coverage-5.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:93a280c9eb736a0dcca19296f3c30c720cb41a71b1f9e617f341f0a8e791a69b"}, - {file = "coverage-5.3.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:3102bb2c206700a7d28181dbe04d66b30780cde1d1c02c5f3c165cf3d2489497"}, - {file = "coverage-5.3.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8ffd4b204d7de77b5dd558cdff986a8274796a1e57813ed005b33fd97e29f059"}, - {file = "coverage-5.3.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a607ae05b6c96057ba86c811d9c43423f35e03874ffb03fbdcd45e0637e8b631"}, - {file = "coverage-5.3.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:3a3c3f8863255f3c31db3889f8055989527173ef6192a283eb6f4db3c579d830"}, - {file = "coverage-5.3.1-cp38-cp38-win32.whl", hash = "sha256:ff1330e8bc996570221b450e2d539134baa9465f5cb98aff0e0f73f34172e0ae"}, - {file = "coverage-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:3498b27d8236057def41de3585f317abae235dd3a11d33e01736ffedb2ef8606"}, - {file = "coverage-5.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ceb499d2b3d1d7b7ba23abe8bf26df5f06ba8c71127f188333dddcf356b4b63f"}, - {file = "coverage-5.3.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:3b14b1da110ea50c8bcbadc3b82c3933974dbeea1832e814aab93ca1163cd4c1"}, - {file = "coverage-5.3.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:76b2775dda7e78680d688daabcb485dc87cf5e3184a0b3e012e1d40e38527cc8"}, - {file = "coverage-5.3.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:cef06fb382557f66d81d804230c11ab292d94b840b3cb7bf4450778377b592f4"}, - {file = "coverage-5.3.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f61319e33222591f885c598e3e24f6a4be3533c1d70c19e0dc59e83a71ce27d"}, - {file = "coverage-5.3.1-cp39-cp39-win32.whl", hash = "sha256:cc6f8246e74dd210d7e2b56c76ceaba1cc52b025cd75dbe96eb48791e0250e98"}, - {file = "coverage-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:2757fa64e11ec12220968f65d086b7a29b6583d16e9a544c889b22ba98555ef1"}, - {file = "coverage-5.3.1-pp36-none-any.whl", hash = "sha256:723d22d324e7997a651478e9c5a3120a0ecbc9a7e94071f7e1954562a8806cf3"}, - {file = "coverage-5.3.1-pp37-none-any.whl", hash = "sha256:c89b558f8a9a5a6f2cfc923c304d49f0ce629c3bd85cb442ca258ec20366394c"}, - {file = "coverage-5.3.1.tar.gz", hash = "sha256:38f16b1317b8dd82df67ed5daa5f5e7c959e46579840d77a67a4ceb9cef0a50b"}, + {file = "coverage-5.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:6d9c88b787638a451f41f97446a1c9fd416e669b4d9717ae4615bd29de1ac135"}, + {file = "coverage-5.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:66a5aae8233d766a877c5ef293ec5ab9520929c2578fd2069308a98b7374ea8c"}, + {file = "coverage-5.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9754a5c265f991317de2bac0c70a746efc2b695cf4d49f5d2cddeac36544fb44"}, + {file = "coverage-5.4-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:fbb17c0d0822684b7d6c09915677a32319f16ff1115df5ec05bdcaaee40b35f3"}, + {file = "coverage-5.4-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:b7f7421841f8db443855d2854e25914a79a1ff48ae92f70d0a5c2f8907ab98c9"}, + {file = "coverage-5.4-cp27-cp27m-win32.whl", hash = "sha256:4a780807e80479f281d47ee4af2eb2df3e4ccf4723484f77da0bb49d027e40a1"}, + {file = "coverage-5.4-cp27-cp27m-win_amd64.whl", hash = "sha256:87c4b38288f71acd2106f5d94f575bc2136ea2887fdb5dfe18003c881fa6b370"}, + {file = "coverage-5.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:c6809ebcbf6c1049002b9ac09c127ae43929042ec1f1dbd8bb1615f7cd9f70a0"}, + {file = "coverage-5.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ba7ca81b6d60a9f7a0b4b4e175dcc38e8fef4992673d9d6e6879fd6de00dd9b8"}, + {file = "coverage-5.4-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:89fc12c6371bf963809abc46cced4a01ca4f99cba17be5e7d416ed7ef1245d19"}, + {file = "coverage-5.4-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a8eb7785bd23565b542b01fb39115a975fefb4a82f23d407503eee2c0106247"}, + {file = "coverage-5.4-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:7e40d3f8eb472c1509b12ac2a7e24158ec352fc8567b77ab02c0db053927e339"}, + {file = "coverage-5.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1ccae21a076d3d5f471700f6d30eb486da1626c380b23c70ae32ab823e453337"}, + {file = "coverage-5.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:755c56beeacac6a24c8e1074f89f34f4373abce8b662470d3aa719ae304931f3"}, + {file = "coverage-5.4-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:322549b880b2d746a7672bf6ff9ed3f895e9c9f108b714e7360292aa5c5d7cf4"}, + {file = "coverage-5.4-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:60a3307a84ec60578accd35d7f0c71a3a971430ed7eca6567399d2b50ef37b8c"}, + {file = "coverage-5.4-cp35-cp35m-win32.whl", hash = "sha256:1375bb8b88cb050a2d4e0da901001347a44302aeadb8ceb4b6e5aa373b8ea68f"}, + {file = "coverage-5.4-cp35-cp35m-win_amd64.whl", hash = "sha256:16baa799ec09cc0dcb43a10680573269d407c159325972dd7114ee7649e56c66"}, + {file = "coverage-5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2f2cf7a42d4b7654c9a67b9d091ec24374f7c58794858bff632a2039cb15984d"}, + {file = "coverage-5.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:b62046592b44263fa7570f1117d372ae3f310222af1fc1407416f037fb3af21b"}, + {file = "coverage-5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:812eaf4939ef2284d29653bcfee9665f11f013724f07258928f849a2306ea9f9"}, + {file = "coverage-5.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:859f0add98707b182b4867359e12bde806b82483fb12a9ae868a77880fc3b7af"}, + {file = "coverage-5.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:04b14e45d6a8e159c9767ae57ecb34563ad93440fc1b26516a89ceb5b33c1ad5"}, + {file = "coverage-5.4-cp36-cp36m-win32.whl", hash = "sha256:ebfa374067af240d079ef97b8064478f3bf71038b78b017eb6ec93ede1b6bcec"}, + {file = "coverage-5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:84df004223fd0550d0ea7a37882e5c889f3c6d45535c639ce9802293b39cd5c9"}, + {file = "coverage-5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:1b811662ecf72eb2d08872731636aee6559cae21862c36f74703be727b45df90"}, + {file = "coverage-5.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6b588b5cf51dc0fd1c9e19f622457cc74b7d26fe295432e434525f1c0fae02bc"}, + {file = "coverage-5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:3fe50f1cac369b02d34ad904dfe0771acc483f82a1b54c5e93632916ba847b37"}, + {file = "coverage-5.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:32ab83016c24c5cf3db2943286b85b0a172dae08c58d0f53875235219b676409"}, + {file = "coverage-5.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:68fb816a5dd901c6aff352ce49e2a0ffadacdf9b6fae282a69e7a16a02dad5fb"}, + {file = "coverage-5.4-cp37-cp37m-win32.whl", hash = "sha256:a636160680c6e526b84f85d304e2f0bb4e94f8284dd765a1911de9a40450b10a"}, + {file = "coverage-5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:bb32ca14b4d04e172c541c69eec5f385f9a075b38fb22d765d8b0ce3af3a0c22"}, + {file = "coverage-5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4d7165a4e8f41eca6b990c12ee7f44fef3932fac48ca32cecb3a1b2223c21f"}, + {file = "coverage-5.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:a565f48c4aae72d1d3d3f8e8fb7218f5609c964e9c6f68604608e5958b9c60c3"}, + {file = "coverage-5.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fff1f3a586246110f34dc762098b5afd2de88de507559e63553d7da643053786"}, + {file = "coverage-5.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a839e25f07e428a87d17d857d9935dd743130e77ff46524abb992b962eb2076c"}, + {file = "coverage-5.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:6625e52b6f346a283c3d563d1fd8bae8956daafc64bb5bbd2b8f8a07608e3994"}, + {file = "coverage-5.4-cp38-cp38-win32.whl", hash = "sha256:5bee3970617b3d74759b2d2df2f6a327d372f9732f9ccbf03fa591b5f7581e39"}, + {file = "coverage-5.4-cp38-cp38-win_amd64.whl", hash = "sha256:03ed2a641e412e42cc35c244508cf186015c217f0e4d496bf6d7078ebe837ae7"}, + {file = "coverage-5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:14a9f1887591684fb59fdba8feef7123a0da2424b0652e1b58dd5b9a7bb1188c"}, + {file = "coverage-5.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9564ac7eb1652c3701ac691ca72934dd3009997c81266807aef924012df2f4b3"}, + {file = "coverage-5.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:0f48fc7dc82ee14aeaedb986e175a429d24129b7eada1b7e94a864e4f0644dde"}, + {file = "coverage-5.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:107d327071061fd4f4a2587d14c389a27e4e5c93c7cba5f1f59987181903902f"}, + {file = "coverage-5.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:0cdde51bfcf6b6bd862ee9be324521ec619b20590787d1655d005c3fb175005f"}, + {file = "coverage-5.4-cp39-cp39-win32.whl", hash = "sha256:c67734cff78383a1f23ceba3b3239c7deefc62ac2b05fa6a47bcd565771e5880"}, + {file = "coverage-5.4-cp39-cp39-win_amd64.whl", hash = "sha256:c669b440ce46ae3abe9b2d44a913b5fd86bb19eb14a8701e88e3918902ecd345"}, + {file = "coverage-5.4-pp36-none-any.whl", hash = "sha256:c0ff1c1b4d13e2240821ef23c1efb1f009207cb3f56e16986f713c2b0e7cd37f"}, + {file = "coverage-5.4-pp37-none-any.whl", hash = "sha256:cd601187476c6bed26a0398353212684c427e10a903aeafa6da40c63309d438b"}, + {file = "coverage-5.4.tar.gz", hash = "sha256:6d2e262e5e8da6fa56e774fb8e2643417351427604c2b177f8e8c5f75fc928ca"}, ] cryptography = [ {file = "cryptography-3.3.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:c366df0401d1ec4e548bebe8f91d55ebcc0ec3137900d214dd7aac8427ef3030"}, @@ -841,8 +841,8 @@ joblib = [ {file = "joblib-1.0.0.tar.gz", hash = "sha256:7ad866067ac1fdec27d51c8678ea760601b70e32ff1881d4dc8e1171f2b64b24"}, ] keyring = [ - {file = "keyring-21.8.0-py3-none-any.whl", hash = "sha256:4be9cbaaaf83e61d6399f733d113ede7d1c73bc75cb6aeb64eee0f6ac39b30ea"}, - {file = "keyring-21.8.0.tar.gz", hash = "sha256:1746d3ac913d449a090caf11e9e4af00e26c3f7f7e81027872192b2398b98675"}, + {file = "keyring-22.0.1-py3-none-any.whl", hash = "sha256:9f44660a5d4931bdc14c08a1d01ef30b18a7a8147380710d8c9f9531e1f6c3c0"}, + {file = "keyring-22.0.1.tar.gz", hash = "sha256:9acb3e1452edbb7544822b12fd25459078769e560fa51f418b6d00afaa6178df"}, ] livereload = [ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, @@ -945,8 +945,8 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ - {file = "pytest-6.2.1-py3-none-any.whl", hash = "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8"}, - {file = "pytest-6.2.1.tar.gz", hash = "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306"}, + {file = "pytest-6.2.2-py3-none-any.whl", hash = "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839"}, + {file = "pytest-6.2.2.tar.gz", hash = "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9"}, ] pytest-cov = [ {file = "pytest-cov-2.11.1.tar.gz", hash = "sha256:359952d9d39b9f822d9d29324483e7ba04a3a17dd7d05aa6beb7ea01e359e5f7"}, From 6e09f93f161f6391b994d5fbaa31a1cbb9a29f5a Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 08:36:58 -0500 Subject: [PATCH 62/82] update tests with better verifications make format space review feedbac --- features/overrides.feature | 1 - features/steps/override.py | 62 ++++++++++++++++++++------------------ jrnl/args.py | 11 +++---- tests/test_config.py | 1 - tests/test_parse_args.py | 25 +++++++-------- 5 files changed, 50 insertions(+), 50 deletions(-) diff --git a/features/overrides.feature b/features/overrides.feature index 80fdf47c..eef89eec 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -28,7 +28,6 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys """ @skip_win - @wip Scenario: Override color selections with runtime overrides Given we use the config "tiny.yaml" When we run jrnl with -1 --config-override colors.body:blue diff --git a/features/steps/override.py b/features/steps/override.py index b0edc864..ac531235 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -1,5 +1,3 @@ -from tests.test_config import expected_override -from jrnl.editor import get_text_from_stdin from jrnl.jrnl import run from jrnl.os_compat import split_args from unittest import mock @@ -12,16 +10,18 @@ import yaml from yaml.loader import FullLoader import jrnl + + def _mock_time_parse(context): - original_parse = jrnl.time.parse - if "now" not in context: - return original_parse + original_parse = jrnl.time.parse + if "now" not in context: + return original_parse - def wrapper(input, *args, **kwargs): - input = context.now if input == "now" else input - return original_parse(input, *args, **kwargs) + def wrapper(input, *args, **kwargs): + input = context.now if input == "now" else input + return original_parse(input, *args, **kwargs) - return wrapper + return wrapper @given("we use the config {config_file}") @@ -42,10 +42,7 @@ def run_command(context, args): @then("the runtime config should have {key_as_dots} set to {override_value}") def config_override(context, key_as_dots: str, override_value: str): key_as_vec = key_as_dots.split(".") - # with open(context.config_path) as f: - # loaded_cfg = yaml.load(f, Loader=yaml.FullLoader) - # loaded_cfg["journal"] = "features/journals/simple.journal" - + def _mock_callback(**args): print("callback executed") @@ -61,7 +58,7 @@ def config_override(context, key_as_dots: str, override_value: str): : run(context.parser) runtime_cfg = mock_recurse.call_args_list[0][0][0] - assert mock_recurse.call_count == key_as_vec.__len__() + for k in key_as_vec: runtime_cfg = runtime_cfg['%s'%k] @@ -73,15 +70,13 @@ def config_override(context, key_as_dots: str, override_value: str): @then("the editor {editor} should have been called") def editor_override(context, editor): - def _mock_write_in_editor(config): - editor = config['editor'] - journal = '/tmp/journal.jrnl' + editor = config["editor"] + journal = "features/journals/journal.jrnl" context.tmpfile = journal - print("%s has been launched"%editor) + print("%s has been launched" % editor) return journal - - + # fmt: off # see: https://github.com/psf/black/issues/664 with \ @@ -97,7 +92,7 @@ def editor_override(context, editor): context.editor = mock_write_in_editor expected_config = context.cfg expected_config['editor'] = '%s'%editor - expected_config['journal'] ='/tmp/journal.jrnl' + expected_config['journal'] ='features/journals/journal.jrnl' assert mock_write_in_editor.call_count == 1 assert mock_write_in_editor.call_args[0][0]['editor']==editor @@ -105,17 +100,24 @@ def editor_override(context, editor): context.exit_status = e.code # fmt: on -@then("the stdin prompt must be launched") -def override_editor_to_use_stdin(context): - try: - with \ - mock.patch('sys.stdin.read', return_value='Zwei peanuts walk into a bar und one of zem was a-salted')as mock_stdin_read, \ - mock.patch("jrnl.install.load_or_install_jrnl", return_value=context.cfg), \ - mock.patch("jrnl.Journal.open_journal", spec=False, return_value='/tmp/journal.jrnl'): +@then("the stdin prompt must be launched") +def override_editor_to_use_stdin(context): + + try: + with mock.patch( + "sys.stdin.read", + return_value="Zwei peanuts walk into a bar und one of zem was a-salted", + ) as mock_stdin_read, mock.patch( + "jrnl.install.load_or_install_jrnl", return_value=context.cfg + ), mock.patch( + "jrnl.Journal.open_journal", + spec=False, + return_value="features/journals/journal.jrnl", + ): run(context.parser) context.exit_status = 0 mock_stdin_read.assert_called_once() - except SystemExit as e : - context.exit_status = e.code \ No newline at end of file + except SystemExit as e: + context.exit_status = e.code diff --git a/jrnl/args.py b/jrnl/args.py index e1d73a8c..f2ea288c 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -4,7 +4,6 @@ import argparse import re import textwrap -import json from .commands import postconfig_decrypt from .commands import postconfig_encrypt @@ -24,11 +23,11 @@ def deserialize_config_args(input: str) -> dict: for _p in _kvpairs: l, r = _p.strip().split(":") r = r.strip() - if r.isdigit(): - r = int(r) - elif r.lower() == "true": - r = True - elif r.lower() == "false": + if r.isdigit(): + r = int(r) + elif r.lower() == "true": + r = True + elif r.lower() == "false": r = False runtime_modifications[l] = r return runtime_modifications diff --git a/tests/test_config.py b/tests/test_config.py index aa4d7079..dc2650a8 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -2,7 +2,6 @@ import shlex import pytest import mock -import yaml from jrnl.args import parse_args from jrnl.jrnl import run diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index 8e314aad..a49c99cb 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -1,4 +1,3 @@ -from features.steps.override import config_override import shlex import pytest @@ -6,6 +5,7 @@ import pytest from jrnl.args import parse_args from jrnl.args import deserialize_config_args + def cli_as_dict(str): cli = shlex.split(str) args = parse_args(cli) @@ -206,6 +206,7 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) + class TestDeserialization: @pytest.mark.parametrize( "input_str", @@ -215,8 +216,7 @@ class TestDeserialization: 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"', ], ) - def test_deserialize_multiword_strings(self,input_str): - + def test_deserialize_multiword_strings(self, input_str): runtime_config = deserialize_config_args(input_str) assert runtime_config.__class__ == dict @@ -224,18 +224,19 @@ class TestDeserialization: assert "colors.title" in runtime_config.keys() assert "default" in runtime_config.keys() - def test_deserialize_int(self): - input = 'linewrap: 23, default_hour: 19' + def test_deserialize_int(self): + input = "linewrap: 23, default_hour: 19" runtime_config = deserialize_config_args(input) - assert runtime_config['linewrap'] == 23 - assert runtime_config['default_hour'] == 19 + assert runtime_config["linewrap"] == 23 + assert runtime_config["default_hour"] == 19 - def test_deserialize_multiple_datatypes(self): + def test_deserialize_multiple_datatypes(self): input = 'linewrap: 23, encrypt: false, editor:"vi -c startinsert"' - cfg = deserialize_config_args(input) - assert cfg['encrypt'] == False - assert cfg['linewrap'] == 23 - assert cfg['editor'] == '"vi -c startinsert"' + cfg = deserialize_config_args(input) + assert cfg["encrypt"] == False + assert cfg["linewrap"] == 23 + assert cfg["editor"] == '"vi -c startinsert"' + def test_editor_override(): From 8624fd3e018d6aaf5d2cc6a912f87be9acbba654 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 09:21:23 -0500 Subject: [PATCH 63/82] skip on win --- features/overrides.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/overrides.feature b/features/overrides.feature index eef89eec..4343cdb1 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -41,6 +41,7 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys And the runtime config should have editor set to nano + @skip_win Scenario Outline: Override configured editor Given we use the config "tiny.yaml" When we run jrnl with --config-override editor:"" From e74420bbd5156827b8c9ce37b36663356b287c3f Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 09:26:27 -0500 Subject: [PATCH 64/82] update deps --- poetry.lock | 100 ++++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/poetry.lock b/poetry.lock index b0a7046e..df676e25 100644 --- a/poetry.lock +++ b/poetry.lock @@ -129,7 +129,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "5.3.1" +version = "5.4" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -751,55 +751,55 @@ colorama = [ {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] coverage = [ - {file = "coverage-5.3.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:fabeeb121735d47d8eab8671b6b031ce08514c86b7ad8f7d5490a7b6dcd6267d"}, - {file = "coverage-5.3.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:7e4d159021c2029b958b2363abec4a11db0ce8cd43abb0d9ce44284cb97217e7"}, - {file = "coverage-5.3.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:378ac77af41350a8c6b8801a66021b52da8a05fd77e578b7380e876c0ce4f528"}, - {file = "coverage-5.3.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e448f56cfeae7b1b3b5bcd99bb377cde7c4eb1970a525c770720a352bc4c8044"}, - {file = "coverage-5.3.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:cc44e3545d908ecf3e5773266c487ad1877be718d9dc65fc7eb6e7d14960985b"}, - {file = "coverage-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:08b3ba72bd981531fd557f67beee376d6700fba183b167857038997ba30dd297"}, - {file = "coverage-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:8dacc4073c359f40fcf73aede8428c35f84639baad7e1b46fce5ab7a8a7be4bb"}, - {file = "coverage-5.3.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ee2f1d1c223c3d2c24e3afbb2dd38be3f03b1a8d6a83ee3d9eb8c36a52bee899"}, - {file = "coverage-5.3.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9a9d4ff06804920388aab69c5ea8a77525cf165356db70131616acd269e19b36"}, - {file = "coverage-5.3.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:782a5c7df9f91979a7a21792e09b34a658058896628217ae6362088b123c8500"}, - {file = "coverage-5.3.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:fda29412a66099af6d6de0baa6bd7c52674de177ec2ad2630ca264142d69c6c7"}, - {file = "coverage-5.3.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:f2c6888eada180814b8583c3e793f3f343a692fc802546eed45f40a001b1169f"}, - {file = "coverage-5.3.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8f33d1156241c43755137288dea619105477961cfa7e47f48dbf96bc2c30720b"}, - {file = "coverage-5.3.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b239711e774c8eb910e9b1ac719f02f5ae4bf35fa0420f438cdc3a7e4e7dd6ec"}, - {file = "coverage-5.3.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:f54de00baf200b4539a5a092a759f000b5f45fd226d6d25a76b0dff71177a714"}, - {file = "coverage-5.3.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:be0416074d7f253865bb67630cf7210cbc14eb05f4099cc0f82430135aaa7a3b"}, - {file = "coverage-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:c46643970dff9f5c976c6512fd35768c4a3819f01f61169d8cdac3f9290903b7"}, - {file = "coverage-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9a4f66259bdd6964d8cf26142733c81fb562252db74ea367d9beb4f815478e72"}, - {file = "coverage-5.3.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c6e5174f8ca585755988bc278c8bb5d02d9dc2e971591ef4a1baabdf2d99589b"}, - {file = "coverage-5.3.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3911c2ef96e5ddc748a3c8b4702c61986628bb719b8378bf1e4a6184bbd48fe4"}, - {file = "coverage-5.3.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c5ec71fd4a43b6d84ddb88c1df94572479d9a26ef3f150cef3dacefecf888105"}, - {file = "coverage-5.3.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f51dbba78d68a44e99d484ca8c8f604f17e957c1ca09c3ebc2c7e3bbd9ba0448"}, - {file = "coverage-5.3.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:a2070c5affdb3a5e751f24208c5c4f3d5f008fa04d28731416e023c93b275277"}, - {file = "coverage-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:535dc1e6e68fad5355f9984d5637c33badbdc987b0c0d303ee95a6c979c9516f"}, - {file = "coverage-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:a4857f7e2bc6921dbd487c5c88b84f5633de3e7d416c4dc0bb70256775551a6c"}, - {file = "coverage-5.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fac3c432851038b3e6afe086f777732bcf7f6ebbfd90951fa04ee53db6d0bcdd"}, - {file = "coverage-5.3.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:cd556c79ad665faeae28020a0ab3bda6cd47d94bec48e36970719b0b86e4dcf4"}, - {file = "coverage-5.3.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a66ca3bdf21c653e47f726ca57f46ba7fc1f260ad99ba783acc3e58e3ebdb9ff"}, - {file = "coverage-5.3.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ab110c48bc3d97b4d19af41865e14531f300b482da21783fdaacd159251890e8"}, - {file = "coverage-5.3.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e52d3d95df81c8f6b2a1685aabffadf2d2d9ad97203a40f8d61e51b70f191e4e"}, - {file = "coverage-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:fa10fee7e32213f5c7b0d6428ea92e3a3fdd6d725590238a3f92c0de1c78b9d2"}, - {file = "coverage-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ce6f3a147b4b1a8b09aae48517ae91139b1b010c5f36423fa2b866a8b23df879"}, - {file = "coverage-5.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:93a280c9eb736a0dcca19296f3c30c720cb41a71b1f9e617f341f0a8e791a69b"}, - {file = "coverage-5.3.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:3102bb2c206700a7d28181dbe04d66b30780cde1d1c02c5f3c165cf3d2489497"}, - {file = "coverage-5.3.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8ffd4b204d7de77b5dd558cdff986a8274796a1e57813ed005b33fd97e29f059"}, - {file = "coverage-5.3.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a607ae05b6c96057ba86c811d9c43423f35e03874ffb03fbdcd45e0637e8b631"}, - {file = "coverage-5.3.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:3a3c3f8863255f3c31db3889f8055989527173ef6192a283eb6f4db3c579d830"}, - {file = "coverage-5.3.1-cp38-cp38-win32.whl", hash = "sha256:ff1330e8bc996570221b450e2d539134baa9465f5cb98aff0e0f73f34172e0ae"}, - {file = "coverage-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:3498b27d8236057def41de3585f317abae235dd3a11d33e01736ffedb2ef8606"}, - {file = "coverage-5.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ceb499d2b3d1d7b7ba23abe8bf26df5f06ba8c71127f188333dddcf356b4b63f"}, - {file = "coverage-5.3.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:3b14b1da110ea50c8bcbadc3b82c3933974dbeea1832e814aab93ca1163cd4c1"}, - {file = "coverage-5.3.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:76b2775dda7e78680d688daabcb485dc87cf5e3184a0b3e012e1d40e38527cc8"}, - {file = "coverage-5.3.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:cef06fb382557f66d81d804230c11ab292d94b840b3cb7bf4450778377b592f4"}, - {file = "coverage-5.3.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f61319e33222591f885c598e3e24f6a4be3533c1d70c19e0dc59e83a71ce27d"}, - {file = "coverage-5.3.1-cp39-cp39-win32.whl", hash = "sha256:cc6f8246e74dd210d7e2b56c76ceaba1cc52b025cd75dbe96eb48791e0250e98"}, - {file = "coverage-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:2757fa64e11ec12220968f65d086b7a29b6583d16e9a544c889b22ba98555ef1"}, - {file = "coverage-5.3.1-pp36-none-any.whl", hash = "sha256:723d22d324e7997a651478e9c5a3120a0ecbc9a7e94071f7e1954562a8806cf3"}, - {file = "coverage-5.3.1-pp37-none-any.whl", hash = "sha256:c89b558f8a9a5a6f2cfc923c304d49f0ce629c3bd85cb442ca258ec20366394c"}, - {file = "coverage-5.3.1.tar.gz", hash = "sha256:38f16b1317b8dd82df67ed5daa5f5e7c959e46579840d77a67a4ceb9cef0a50b"}, + {file = "coverage-5.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:6d9c88b787638a451f41f97446a1c9fd416e669b4d9717ae4615bd29de1ac135"}, + {file = "coverage-5.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:66a5aae8233d766a877c5ef293ec5ab9520929c2578fd2069308a98b7374ea8c"}, + {file = "coverage-5.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9754a5c265f991317de2bac0c70a746efc2b695cf4d49f5d2cddeac36544fb44"}, + {file = "coverage-5.4-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:fbb17c0d0822684b7d6c09915677a32319f16ff1115df5ec05bdcaaee40b35f3"}, + {file = "coverage-5.4-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:b7f7421841f8db443855d2854e25914a79a1ff48ae92f70d0a5c2f8907ab98c9"}, + {file = "coverage-5.4-cp27-cp27m-win32.whl", hash = "sha256:4a780807e80479f281d47ee4af2eb2df3e4ccf4723484f77da0bb49d027e40a1"}, + {file = "coverage-5.4-cp27-cp27m-win_amd64.whl", hash = "sha256:87c4b38288f71acd2106f5d94f575bc2136ea2887fdb5dfe18003c881fa6b370"}, + {file = "coverage-5.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:c6809ebcbf6c1049002b9ac09c127ae43929042ec1f1dbd8bb1615f7cd9f70a0"}, + {file = "coverage-5.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ba7ca81b6d60a9f7a0b4b4e175dcc38e8fef4992673d9d6e6879fd6de00dd9b8"}, + {file = "coverage-5.4-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:89fc12c6371bf963809abc46cced4a01ca4f99cba17be5e7d416ed7ef1245d19"}, + {file = "coverage-5.4-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a8eb7785bd23565b542b01fb39115a975fefb4a82f23d407503eee2c0106247"}, + {file = "coverage-5.4-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:7e40d3f8eb472c1509b12ac2a7e24158ec352fc8567b77ab02c0db053927e339"}, + {file = "coverage-5.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1ccae21a076d3d5f471700f6d30eb486da1626c380b23c70ae32ab823e453337"}, + {file = "coverage-5.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:755c56beeacac6a24c8e1074f89f34f4373abce8b662470d3aa719ae304931f3"}, + {file = "coverage-5.4-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:322549b880b2d746a7672bf6ff9ed3f895e9c9f108b714e7360292aa5c5d7cf4"}, + {file = "coverage-5.4-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:60a3307a84ec60578accd35d7f0c71a3a971430ed7eca6567399d2b50ef37b8c"}, + {file = "coverage-5.4-cp35-cp35m-win32.whl", hash = "sha256:1375bb8b88cb050a2d4e0da901001347a44302aeadb8ceb4b6e5aa373b8ea68f"}, + {file = "coverage-5.4-cp35-cp35m-win_amd64.whl", hash = "sha256:16baa799ec09cc0dcb43a10680573269d407c159325972dd7114ee7649e56c66"}, + {file = "coverage-5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2f2cf7a42d4b7654c9a67b9d091ec24374f7c58794858bff632a2039cb15984d"}, + {file = "coverage-5.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:b62046592b44263fa7570f1117d372ae3f310222af1fc1407416f037fb3af21b"}, + {file = "coverage-5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:812eaf4939ef2284d29653bcfee9665f11f013724f07258928f849a2306ea9f9"}, + {file = "coverage-5.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:859f0add98707b182b4867359e12bde806b82483fb12a9ae868a77880fc3b7af"}, + {file = "coverage-5.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:04b14e45d6a8e159c9767ae57ecb34563ad93440fc1b26516a89ceb5b33c1ad5"}, + {file = "coverage-5.4-cp36-cp36m-win32.whl", hash = "sha256:ebfa374067af240d079ef97b8064478f3bf71038b78b017eb6ec93ede1b6bcec"}, + {file = "coverage-5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:84df004223fd0550d0ea7a37882e5c889f3c6d45535c639ce9802293b39cd5c9"}, + {file = "coverage-5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:1b811662ecf72eb2d08872731636aee6559cae21862c36f74703be727b45df90"}, + {file = "coverage-5.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6b588b5cf51dc0fd1c9e19f622457cc74b7d26fe295432e434525f1c0fae02bc"}, + {file = "coverage-5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:3fe50f1cac369b02d34ad904dfe0771acc483f82a1b54c5e93632916ba847b37"}, + {file = "coverage-5.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:32ab83016c24c5cf3db2943286b85b0a172dae08c58d0f53875235219b676409"}, + {file = "coverage-5.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:68fb816a5dd901c6aff352ce49e2a0ffadacdf9b6fae282a69e7a16a02dad5fb"}, + {file = "coverage-5.4-cp37-cp37m-win32.whl", hash = "sha256:a636160680c6e526b84f85d304e2f0bb4e94f8284dd765a1911de9a40450b10a"}, + {file = "coverage-5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:bb32ca14b4d04e172c541c69eec5f385f9a075b38fb22d765d8b0ce3af3a0c22"}, + {file = "coverage-5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4d7165a4e8f41eca6b990c12ee7f44fef3932fac48ca32cecb3a1b2223c21f"}, + {file = "coverage-5.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:a565f48c4aae72d1d3d3f8e8fb7218f5609c964e9c6f68604608e5958b9c60c3"}, + {file = "coverage-5.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fff1f3a586246110f34dc762098b5afd2de88de507559e63553d7da643053786"}, + {file = "coverage-5.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a839e25f07e428a87d17d857d9935dd743130e77ff46524abb992b962eb2076c"}, + {file = "coverage-5.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:6625e52b6f346a283c3d563d1fd8bae8956daafc64bb5bbd2b8f8a07608e3994"}, + {file = "coverage-5.4-cp38-cp38-win32.whl", hash = "sha256:5bee3970617b3d74759b2d2df2f6a327d372f9732f9ccbf03fa591b5f7581e39"}, + {file = "coverage-5.4-cp38-cp38-win_amd64.whl", hash = "sha256:03ed2a641e412e42cc35c244508cf186015c217f0e4d496bf6d7078ebe837ae7"}, + {file = "coverage-5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:14a9f1887591684fb59fdba8feef7123a0da2424b0652e1b58dd5b9a7bb1188c"}, + {file = "coverage-5.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9564ac7eb1652c3701ac691ca72934dd3009997c81266807aef924012df2f4b3"}, + {file = "coverage-5.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:0f48fc7dc82ee14aeaedb986e175a429d24129b7eada1b7e94a864e4f0644dde"}, + {file = "coverage-5.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:107d327071061fd4f4a2587d14c389a27e4e5c93c7cba5f1f59987181903902f"}, + {file = "coverage-5.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:0cdde51bfcf6b6bd862ee9be324521ec619b20590787d1655d005c3fb175005f"}, + {file = "coverage-5.4-cp39-cp39-win32.whl", hash = "sha256:c67734cff78383a1f23ceba3b3239c7deefc62ac2b05fa6a47bcd565771e5880"}, + {file = "coverage-5.4-cp39-cp39-win_amd64.whl", hash = "sha256:c669b440ce46ae3abe9b2d44a913b5fd86bb19eb14a8701e88e3918902ecd345"}, + {file = "coverage-5.4-pp36-none-any.whl", hash = "sha256:c0ff1c1b4d13e2240821ef23c1efb1f009207cb3f56e16986f713c2b0e7cd37f"}, + {file = "coverage-5.4-pp37-none-any.whl", hash = "sha256:cd601187476c6bed26a0398353212684c427e10a903aeafa6da40c63309d438b"}, + {file = "coverage-5.4.tar.gz", hash = "sha256:6d2e262e5e8da6fa56e774fb8e2643417351427604c2b177f8e8c5f75fc928ca"}, ] cryptography = [ {file = "cryptography-3.3.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:c366df0401d1ec4e548bebe8f91d55ebcc0ec3137900d214dd7aac8427ef3030"}, From 54a5a68da9227559391e3db353692338fc44f1db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Jan 2021 13:58:06 +0000 Subject: [PATCH 65/82] Bump pytest from 6.2.1 to 6.2.2 Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.1 to 6.2.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/6.2.1...6.2.2) Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 541f7e3a..bdbb15e6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -449,7 +449,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pytest" -version = "6.2.1" +version = "6.2.2" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -945,8 +945,8 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ - {file = "pytest-6.2.1-py3-none-any.whl", hash = "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8"}, - {file = "pytest-6.2.1.tar.gz", hash = "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306"}, + {file = "pytest-6.2.2-py3-none-any.whl", hash = "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839"}, + {file = "pytest-6.2.2.tar.gz", hash = "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9"}, ] pytest-cov = [ {file = "pytest-cov-2.11.1.tar.gz", hash = "sha256:359952d9d39b9f822d9d29324483e7ba04a3a17dd7d05aa6beb7ea01e359e5f7"}, From 1a99d65ee41c71d68041c8b2021d7be1a5419f93 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 20:38:25 -0500 Subject: [PATCH 66/82] refactor deserialization organize test_parse_args make format --- jrnl/args.py | 34 +++++++++++++++- tests/test_parse_args.py | 83 +++++++++++++++++++++++++--------------- 2 files changed, 84 insertions(+), 33 deletions(-) diff --git a/jrnl/args.py b/jrnl/args.py index f2ea288c..046d29a8 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -18,10 +18,34 @@ from .plugins import util def deserialize_config_args(input: str) -> dict: - _kvpairs = input.strip(" ").split(",") + """Convert a delimited list of configuration key-value pairs into a flat dict + + Example: + An input of + `colors.title: blue, display_format: json, colors.date: green` + will return + ```json + { + 'colors.title': 'blue', + 'display_format': 'json', + 'colors.date': 'green' + } + ``` + + Args: + input (str): list of configuration keys in dot-notation and their respective values. + + Returns: + dict: A single level dict of the configuration keys in dot-notation and their respective desired values + """ + slug_delimiter = "," + key_value_separator = ":" + _kvpairs = _split_at_delimiter( + input, slug_delimiter, " " + ) # Strip away all whitespace in input, not just leading runtime_modifications = {} for _p in _kvpairs: - l, r = _p.strip().split(":") + l, r = _split_at_delimiter(_p, key_value_separator) r = r.strip() if r.isdigit(): r = int(r) @@ -33,6 +57,12 @@ def deserialize_config_args(input: str) -> dict: return runtime_modifications +def _split_at_delimiter( + input: str, slug_delimiter: str, whitespace_to_strip=None +) -> list: + return input.strip(whitespace_to_strip).split(slug_delimiter) + + class WrappingFormatter(argparse.RawTextHelpFormatter): """Used in help screen""" diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index a49c99cb..5c469e47 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -207,37 +207,6 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) -class TestDeserialization: - @pytest.mark.parametrize( - "input_str", - [ - 'editor:"nano", colors.title:blue, default:"/tmp/egg.txt"', - 'editor:"vi -c startinsert", colors.title:blue, default:"/tmp/egg.txt"', - 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"', - ], - ) - def test_deserialize_multiword_strings(self, input_str): - - runtime_config = deserialize_config_args(input_str) - assert runtime_config.__class__ == dict - assert "editor" in runtime_config.keys() - assert "colors.title" in runtime_config.keys() - assert "default" in runtime_config.keys() - - def test_deserialize_int(self): - input = "linewrap: 23, default_hour: 19" - runtime_config = deserialize_config_args(input) - assert runtime_config["linewrap"] == 23 - assert runtime_config["default_hour"] == 19 - - def test_deserialize_multiple_datatypes(self): - input = 'linewrap: 23, encrypt: false, editor:"vi -c startinsert"' - cfg = deserialize_config_args(input) - assert cfg["encrypt"] == False - assert cfg["linewrap"] == 23 - assert cfg["editor"] == '"vi -c startinsert"' - - def test_editor_override(): parsed_args = cli_as_dict('--config-override editor:"nano"') @@ -291,3 +260,55 @@ def test_and_ordering(cli): def test_edit_ordering(cli): result = expected_args(edit=True, text=["second", "@oldtag", "@newtag"]) assert cli_as_dict(cli) == result + + +class TestDeserialization: + @pytest.mark.parametrize( + "input_str", + [ + 'editor:"nano", colors.title:blue, default:"/tmp/egg.txt"', + 'editor:"vi -c startinsert", colors.title:blue, default:"/tmp/egg.txt"', + 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"', + ], + ) + def test_deserialize_multiword_strings(self, input_str): + + runtime_config = deserialize_config_args(input_str) + assert runtime_config.__class__ == dict + assert "editor" in runtime_config.keys() + assert "colors.title" in runtime_config.keys() + assert "default" in runtime_config.keys() + + def test_deserialize_int(self): + input = "linewrap: 23, default_hour: 19" + runtime_config = deserialize_config_args(input) + assert runtime_config["linewrap"] == 23 + assert runtime_config["default_hour"] == 19 + + def test_deserialize_multiple_datatypes(self): + input = ( + 'linewrap: 23, encrypt: false, editor:"vi -c startinsert", highlight: true' + ) + cfg = deserialize_config_args(input) + assert cfg["encrypt"] == False + assert cfg["highlight"] == True + assert cfg["linewrap"] == 23 + assert cfg["editor"] == '"vi -c startinsert"' + + @pytest.mark.parametrize( + "delimiter", + [ + ".", + ":", + ", ", # note the whitespaces + "-|-", # no reason not to handle multi-character delimiters + ], + ) + def test_split_at_delimiter(self, delimiter): + input = delimiter.join( + ["eggs ", "ba con", "ham"] + ) # The whitespaces are deliberate + from jrnl.args import _split_at_delimiter + + assert _split_at_delimiter(input, delimiter) == ["eggs ", "ba con", "ham"] + assert _split_at_delimiter(input, delimiter, " ") == ["eggs ", "ba con", "ham"] From 3731ccbb439ad1b012eefc8a5c7e4fcaf7a5fdf6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Jan 2021 13:58:18 +0000 Subject: [PATCH 67/82] Bump keyring from 21.8.0 to 22.0.1 Bumps [keyring](https://github.com/jaraco/keyring) from 21.8.0 to 22.0.1. - [Release notes](https://github.com/jaraco/keyring/releases) - [Changelog](https://github.com/jaraco/keyring/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/keyring/compare/v21.8.0...v22.0.1) Signed-off-by: dependabot[bot] --- features/steps/override.py | 2 +- poetry.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/features/steps/override.py b/features/steps/override.py index ac531235..d1857b0b 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -42,7 +42,7 @@ def run_command(context, args): @then("the runtime config should have {key_as_dots} set to {override_value}") def config_override(context, key_as_dots: str, override_value: str): key_as_vec = key_as_dots.split(".") - + def _mock_callback(**args): print("callback executed") diff --git a/poetry.lock b/poetry.lock index bdbb15e6..b0a7046e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -224,7 +224,7 @@ python-versions = ">=3.6" [[package]] name = "keyring" -version = "21.8.0" +version = "22.0.1" description = "Store and access your passwords safely." category = "main" optional = false @@ -238,7 +238,7 @@ SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "pytest-black (>=0.3.7)", "pytest-mypy"] [[package]] name = "livereload" @@ -841,8 +841,8 @@ joblib = [ {file = "joblib-1.0.0.tar.gz", hash = "sha256:7ad866067ac1fdec27d51c8678ea760601b70e32ff1881d4dc8e1171f2b64b24"}, ] keyring = [ - {file = "keyring-21.8.0-py3-none-any.whl", hash = "sha256:4be9cbaaaf83e61d6399f733d113ede7d1c73bc75cb6aeb64eee0f6ac39b30ea"}, - {file = "keyring-21.8.0.tar.gz", hash = "sha256:1746d3ac913d449a090caf11e9e4af00e26c3f7f7e81027872192b2398b98675"}, + {file = "keyring-22.0.1-py3-none-any.whl", hash = "sha256:9f44660a5d4931bdc14c08a1d01ef30b18a7a8147380710d8c9f9531e1f6c3c0"}, + {file = "keyring-22.0.1.tar.gz", hash = "sha256:9acb3e1452edbb7544822b12fd25459078769e560fa51f418b6d00afaa6178df"}, ] livereload = [ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, From 9a19c370e362029c5c1e46b1f7beb49243d5296d Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 09:21:23 -0500 Subject: [PATCH 68/82] skip on win --- features/overrides.feature | 1 + poetry.lock | 100 ++++++++++++++++++------------------- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/features/overrides.feature b/features/overrides.feature index eef89eec..4343cdb1 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -41,6 +41,7 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys And the runtime config should have editor set to nano + @skip_win Scenario Outline: Override configured editor Given we use the config "tiny.yaml" When we run jrnl with --config-override editor:"" diff --git a/poetry.lock b/poetry.lock index b0a7046e..df676e25 100644 --- a/poetry.lock +++ b/poetry.lock @@ -129,7 +129,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "5.3.1" +version = "5.4" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -751,55 +751,55 @@ colorama = [ {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] coverage = [ - {file = "coverage-5.3.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:fabeeb121735d47d8eab8671b6b031ce08514c86b7ad8f7d5490a7b6dcd6267d"}, - {file = "coverage-5.3.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:7e4d159021c2029b958b2363abec4a11db0ce8cd43abb0d9ce44284cb97217e7"}, - {file = "coverage-5.3.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:378ac77af41350a8c6b8801a66021b52da8a05fd77e578b7380e876c0ce4f528"}, - {file = "coverage-5.3.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e448f56cfeae7b1b3b5bcd99bb377cde7c4eb1970a525c770720a352bc4c8044"}, - {file = "coverage-5.3.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:cc44e3545d908ecf3e5773266c487ad1877be718d9dc65fc7eb6e7d14960985b"}, - {file = "coverage-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:08b3ba72bd981531fd557f67beee376d6700fba183b167857038997ba30dd297"}, - {file = "coverage-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:8dacc4073c359f40fcf73aede8428c35f84639baad7e1b46fce5ab7a8a7be4bb"}, - {file = "coverage-5.3.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ee2f1d1c223c3d2c24e3afbb2dd38be3f03b1a8d6a83ee3d9eb8c36a52bee899"}, - {file = "coverage-5.3.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9a9d4ff06804920388aab69c5ea8a77525cf165356db70131616acd269e19b36"}, - {file = "coverage-5.3.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:782a5c7df9f91979a7a21792e09b34a658058896628217ae6362088b123c8500"}, - {file = "coverage-5.3.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:fda29412a66099af6d6de0baa6bd7c52674de177ec2ad2630ca264142d69c6c7"}, - {file = "coverage-5.3.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:f2c6888eada180814b8583c3e793f3f343a692fc802546eed45f40a001b1169f"}, - {file = "coverage-5.3.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8f33d1156241c43755137288dea619105477961cfa7e47f48dbf96bc2c30720b"}, - {file = "coverage-5.3.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b239711e774c8eb910e9b1ac719f02f5ae4bf35fa0420f438cdc3a7e4e7dd6ec"}, - {file = "coverage-5.3.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:f54de00baf200b4539a5a092a759f000b5f45fd226d6d25a76b0dff71177a714"}, - {file = "coverage-5.3.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:be0416074d7f253865bb67630cf7210cbc14eb05f4099cc0f82430135aaa7a3b"}, - {file = "coverage-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:c46643970dff9f5c976c6512fd35768c4a3819f01f61169d8cdac3f9290903b7"}, - {file = "coverage-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9a4f66259bdd6964d8cf26142733c81fb562252db74ea367d9beb4f815478e72"}, - {file = "coverage-5.3.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c6e5174f8ca585755988bc278c8bb5d02d9dc2e971591ef4a1baabdf2d99589b"}, - {file = "coverage-5.3.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3911c2ef96e5ddc748a3c8b4702c61986628bb719b8378bf1e4a6184bbd48fe4"}, - {file = "coverage-5.3.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c5ec71fd4a43b6d84ddb88c1df94572479d9a26ef3f150cef3dacefecf888105"}, - {file = "coverage-5.3.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f51dbba78d68a44e99d484ca8c8f604f17e957c1ca09c3ebc2c7e3bbd9ba0448"}, - {file = "coverage-5.3.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:a2070c5affdb3a5e751f24208c5c4f3d5f008fa04d28731416e023c93b275277"}, - {file = "coverage-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:535dc1e6e68fad5355f9984d5637c33badbdc987b0c0d303ee95a6c979c9516f"}, - {file = "coverage-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:a4857f7e2bc6921dbd487c5c88b84f5633de3e7d416c4dc0bb70256775551a6c"}, - {file = "coverage-5.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fac3c432851038b3e6afe086f777732bcf7f6ebbfd90951fa04ee53db6d0bcdd"}, - {file = "coverage-5.3.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:cd556c79ad665faeae28020a0ab3bda6cd47d94bec48e36970719b0b86e4dcf4"}, - {file = "coverage-5.3.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a66ca3bdf21c653e47f726ca57f46ba7fc1f260ad99ba783acc3e58e3ebdb9ff"}, - {file = "coverage-5.3.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ab110c48bc3d97b4d19af41865e14531f300b482da21783fdaacd159251890e8"}, - {file = "coverage-5.3.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e52d3d95df81c8f6b2a1685aabffadf2d2d9ad97203a40f8d61e51b70f191e4e"}, - {file = "coverage-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:fa10fee7e32213f5c7b0d6428ea92e3a3fdd6d725590238a3f92c0de1c78b9d2"}, - {file = "coverage-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ce6f3a147b4b1a8b09aae48517ae91139b1b010c5f36423fa2b866a8b23df879"}, - {file = "coverage-5.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:93a280c9eb736a0dcca19296f3c30c720cb41a71b1f9e617f341f0a8e791a69b"}, - {file = "coverage-5.3.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:3102bb2c206700a7d28181dbe04d66b30780cde1d1c02c5f3c165cf3d2489497"}, - {file = "coverage-5.3.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8ffd4b204d7de77b5dd558cdff986a8274796a1e57813ed005b33fd97e29f059"}, - {file = "coverage-5.3.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a607ae05b6c96057ba86c811d9c43423f35e03874ffb03fbdcd45e0637e8b631"}, - {file = "coverage-5.3.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:3a3c3f8863255f3c31db3889f8055989527173ef6192a283eb6f4db3c579d830"}, - {file = "coverage-5.3.1-cp38-cp38-win32.whl", hash = "sha256:ff1330e8bc996570221b450e2d539134baa9465f5cb98aff0e0f73f34172e0ae"}, - {file = "coverage-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:3498b27d8236057def41de3585f317abae235dd3a11d33e01736ffedb2ef8606"}, - {file = "coverage-5.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ceb499d2b3d1d7b7ba23abe8bf26df5f06ba8c71127f188333dddcf356b4b63f"}, - {file = "coverage-5.3.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:3b14b1da110ea50c8bcbadc3b82c3933974dbeea1832e814aab93ca1163cd4c1"}, - {file = "coverage-5.3.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:76b2775dda7e78680d688daabcb485dc87cf5e3184a0b3e012e1d40e38527cc8"}, - {file = "coverage-5.3.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:cef06fb382557f66d81d804230c11ab292d94b840b3cb7bf4450778377b592f4"}, - {file = "coverage-5.3.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f61319e33222591f885c598e3e24f6a4be3533c1d70c19e0dc59e83a71ce27d"}, - {file = "coverage-5.3.1-cp39-cp39-win32.whl", hash = "sha256:cc6f8246e74dd210d7e2b56c76ceaba1cc52b025cd75dbe96eb48791e0250e98"}, - {file = "coverage-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:2757fa64e11ec12220968f65d086b7a29b6583d16e9a544c889b22ba98555ef1"}, - {file = "coverage-5.3.1-pp36-none-any.whl", hash = "sha256:723d22d324e7997a651478e9c5a3120a0ecbc9a7e94071f7e1954562a8806cf3"}, - {file = "coverage-5.3.1-pp37-none-any.whl", hash = "sha256:c89b558f8a9a5a6f2cfc923c304d49f0ce629c3bd85cb442ca258ec20366394c"}, - {file = "coverage-5.3.1.tar.gz", hash = "sha256:38f16b1317b8dd82df67ed5daa5f5e7c959e46579840d77a67a4ceb9cef0a50b"}, + {file = "coverage-5.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:6d9c88b787638a451f41f97446a1c9fd416e669b4d9717ae4615bd29de1ac135"}, + {file = "coverage-5.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:66a5aae8233d766a877c5ef293ec5ab9520929c2578fd2069308a98b7374ea8c"}, + {file = "coverage-5.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9754a5c265f991317de2bac0c70a746efc2b695cf4d49f5d2cddeac36544fb44"}, + {file = "coverage-5.4-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:fbb17c0d0822684b7d6c09915677a32319f16ff1115df5ec05bdcaaee40b35f3"}, + {file = "coverage-5.4-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:b7f7421841f8db443855d2854e25914a79a1ff48ae92f70d0a5c2f8907ab98c9"}, + {file = "coverage-5.4-cp27-cp27m-win32.whl", hash = "sha256:4a780807e80479f281d47ee4af2eb2df3e4ccf4723484f77da0bb49d027e40a1"}, + {file = "coverage-5.4-cp27-cp27m-win_amd64.whl", hash = "sha256:87c4b38288f71acd2106f5d94f575bc2136ea2887fdb5dfe18003c881fa6b370"}, + {file = "coverage-5.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:c6809ebcbf6c1049002b9ac09c127ae43929042ec1f1dbd8bb1615f7cd9f70a0"}, + {file = "coverage-5.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ba7ca81b6d60a9f7a0b4b4e175dcc38e8fef4992673d9d6e6879fd6de00dd9b8"}, + {file = "coverage-5.4-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:89fc12c6371bf963809abc46cced4a01ca4f99cba17be5e7d416ed7ef1245d19"}, + {file = "coverage-5.4-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a8eb7785bd23565b542b01fb39115a975fefb4a82f23d407503eee2c0106247"}, + {file = "coverage-5.4-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:7e40d3f8eb472c1509b12ac2a7e24158ec352fc8567b77ab02c0db053927e339"}, + {file = "coverage-5.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1ccae21a076d3d5f471700f6d30eb486da1626c380b23c70ae32ab823e453337"}, + {file = "coverage-5.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:755c56beeacac6a24c8e1074f89f34f4373abce8b662470d3aa719ae304931f3"}, + {file = "coverage-5.4-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:322549b880b2d746a7672bf6ff9ed3f895e9c9f108b714e7360292aa5c5d7cf4"}, + {file = "coverage-5.4-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:60a3307a84ec60578accd35d7f0c71a3a971430ed7eca6567399d2b50ef37b8c"}, + {file = "coverage-5.4-cp35-cp35m-win32.whl", hash = "sha256:1375bb8b88cb050a2d4e0da901001347a44302aeadb8ceb4b6e5aa373b8ea68f"}, + {file = "coverage-5.4-cp35-cp35m-win_amd64.whl", hash = "sha256:16baa799ec09cc0dcb43a10680573269d407c159325972dd7114ee7649e56c66"}, + {file = "coverage-5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2f2cf7a42d4b7654c9a67b9d091ec24374f7c58794858bff632a2039cb15984d"}, + {file = "coverage-5.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:b62046592b44263fa7570f1117d372ae3f310222af1fc1407416f037fb3af21b"}, + {file = "coverage-5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:812eaf4939ef2284d29653bcfee9665f11f013724f07258928f849a2306ea9f9"}, + {file = "coverage-5.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:859f0add98707b182b4867359e12bde806b82483fb12a9ae868a77880fc3b7af"}, + {file = "coverage-5.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:04b14e45d6a8e159c9767ae57ecb34563ad93440fc1b26516a89ceb5b33c1ad5"}, + {file = "coverage-5.4-cp36-cp36m-win32.whl", hash = "sha256:ebfa374067af240d079ef97b8064478f3bf71038b78b017eb6ec93ede1b6bcec"}, + {file = "coverage-5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:84df004223fd0550d0ea7a37882e5c889f3c6d45535c639ce9802293b39cd5c9"}, + {file = "coverage-5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:1b811662ecf72eb2d08872731636aee6559cae21862c36f74703be727b45df90"}, + {file = "coverage-5.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6b588b5cf51dc0fd1c9e19f622457cc74b7d26fe295432e434525f1c0fae02bc"}, + {file = "coverage-5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:3fe50f1cac369b02d34ad904dfe0771acc483f82a1b54c5e93632916ba847b37"}, + {file = "coverage-5.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:32ab83016c24c5cf3db2943286b85b0a172dae08c58d0f53875235219b676409"}, + {file = "coverage-5.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:68fb816a5dd901c6aff352ce49e2a0ffadacdf9b6fae282a69e7a16a02dad5fb"}, + {file = "coverage-5.4-cp37-cp37m-win32.whl", hash = "sha256:a636160680c6e526b84f85d304e2f0bb4e94f8284dd765a1911de9a40450b10a"}, + {file = "coverage-5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:bb32ca14b4d04e172c541c69eec5f385f9a075b38fb22d765d8b0ce3af3a0c22"}, + {file = "coverage-5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4d7165a4e8f41eca6b990c12ee7f44fef3932fac48ca32cecb3a1b2223c21f"}, + {file = "coverage-5.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:a565f48c4aae72d1d3d3f8e8fb7218f5609c964e9c6f68604608e5958b9c60c3"}, + {file = "coverage-5.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fff1f3a586246110f34dc762098b5afd2de88de507559e63553d7da643053786"}, + {file = "coverage-5.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a839e25f07e428a87d17d857d9935dd743130e77ff46524abb992b962eb2076c"}, + {file = "coverage-5.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:6625e52b6f346a283c3d563d1fd8bae8956daafc64bb5bbd2b8f8a07608e3994"}, + {file = "coverage-5.4-cp38-cp38-win32.whl", hash = "sha256:5bee3970617b3d74759b2d2df2f6a327d372f9732f9ccbf03fa591b5f7581e39"}, + {file = "coverage-5.4-cp38-cp38-win_amd64.whl", hash = "sha256:03ed2a641e412e42cc35c244508cf186015c217f0e4d496bf6d7078ebe837ae7"}, + {file = "coverage-5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:14a9f1887591684fb59fdba8feef7123a0da2424b0652e1b58dd5b9a7bb1188c"}, + {file = "coverage-5.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9564ac7eb1652c3701ac691ca72934dd3009997c81266807aef924012df2f4b3"}, + {file = "coverage-5.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:0f48fc7dc82ee14aeaedb986e175a429d24129b7eada1b7e94a864e4f0644dde"}, + {file = "coverage-5.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:107d327071061fd4f4a2587d14c389a27e4e5c93c7cba5f1f59987181903902f"}, + {file = "coverage-5.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:0cdde51bfcf6b6bd862ee9be324521ec619b20590787d1655d005c3fb175005f"}, + {file = "coverage-5.4-cp39-cp39-win32.whl", hash = "sha256:c67734cff78383a1f23ceba3b3239c7deefc62ac2b05fa6a47bcd565771e5880"}, + {file = "coverage-5.4-cp39-cp39-win_amd64.whl", hash = "sha256:c669b440ce46ae3abe9b2d44a913b5fd86bb19eb14a8701e88e3918902ecd345"}, + {file = "coverage-5.4-pp36-none-any.whl", hash = "sha256:c0ff1c1b4d13e2240821ef23c1efb1f009207cb3f56e16986f713c2b0e7cd37f"}, + {file = "coverage-5.4-pp37-none-any.whl", hash = "sha256:cd601187476c6bed26a0398353212684c427e10a903aeafa6da40c63309d438b"}, + {file = "coverage-5.4.tar.gz", hash = "sha256:6d2e262e5e8da6fa56e774fb8e2643417351427604c2b177f8e8c5f75fc928ca"}, ] cryptography = [ {file = "cryptography-3.3.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:c366df0401d1ec4e548bebe8f91d55ebcc0ec3137900d214dd7aac8427ef3030"}, From 8ea258c544df34654b15ffc5e3306bd559696b44 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 20:38:25 -0500 Subject: [PATCH 69/82] refactor deserialization organize test_parse_args make format --- jrnl/args.py | 34 +++++++++++++++- tests/test_parse_args.py | 83 +++++++++++++++++++++++++--------------- 2 files changed, 84 insertions(+), 33 deletions(-) diff --git a/jrnl/args.py b/jrnl/args.py index f2ea288c..046d29a8 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -18,10 +18,34 @@ from .plugins import util def deserialize_config_args(input: str) -> dict: - _kvpairs = input.strip(" ").split(",") + """Convert a delimited list of configuration key-value pairs into a flat dict + + Example: + An input of + `colors.title: blue, display_format: json, colors.date: green` + will return + ```json + { + 'colors.title': 'blue', + 'display_format': 'json', + 'colors.date': 'green' + } + ``` + + Args: + input (str): list of configuration keys in dot-notation and their respective values. + + Returns: + dict: A single level dict of the configuration keys in dot-notation and their respective desired values + """ + slug_delimiter = "," + key_value_separator = ":" + _kvpairs = _split_at_delimiter( + input, slug_delimiter, " " + ) # Strip away all whitespace in input, not just leading runtime_modifications = {} for _p in _kvpairs: - l, r = _p.strip().split(":") + l, r = _split_at_delimiter(_p, key_value_separator) r = r.strip() if r.isdigit(): r = int(r) @@ -33,6 +57,12 @@ def deserialize_config_args(input: str) -> dict: return runtime_modifications +def _split_at_delimiter( + input: str, slug_delimiter: str, whitespace_to_strip=None +) -> list: + return input.strip(whitespace_to_strip).split(slug_delimiter) + + class WrappingFormatter(argparse.RawTextHelpFormatter): """Used in help screen""" diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index a49c99cb..5c469e47 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -207,37 +207,6 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) -class TestDeserialization: - @pytest.mark.parametrize( - "input_str", - [ - 'editor:"nano", colors.title:blue, default:"/tmp/egg.txt"', - 'editor:"vi -c startinsert", colors.title:blue, default:"/tmp/egg.txt"', - 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"', - ], - ) - def test_deserialize_multiword_strings(self, input_str): - - runtime_config = deserialize_config_args(input_str) - assert runtime_config.__class__ == dict - assert "editor" in runtime_config.keys() - assert "colors.title" in runtime_config.keys() - assert "default" in runtime_config.keys() - - def test_deserialize_int(self): - input = "linewrap: 23, default_hour: 19" - runtime_config = deserialize_config_args(input) - assert runtime_config["linewrap"] == 23 - assert runtime_config["default_hour"] == 19 - - def test_deserialize_multiple_datatypes(self): - input = 'linewrap: 23, encrypt: false, editor:"vi -c startinsert"' - cfg = deserialize_config_args(input) - assert cfg["encrypt"] == False - assert cfg["linewrap"] == 23 - assert cfg["editor"] == '"vi -c startinsert"' - - def test_editor_override(): parsed_args = cli_as_dict('--config-override editor:"nano"') @@ -291,3 +260,55 @@ def test_and_ordering(cli): def test_edit_ordering(cli): result = expected_args(edit=True, text=["second", "@oldtag", "@newtag"]) assert cli_as_dict(cli) == result + + +class TestDeserialization: + @pytest.mark.parametrize( + "input_str", + [ + 'editor:"nano", colors.title:blue, default:"/tmp/egg.txt"', + 'editor:"vi -c startinsert", colors.title:blue, default:"/tmp/egg.txt"', + 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"', + ], + ) + def test_deserialize_multiword_strings(self, input_str): + + runtime_config = deserialize_config_args(input_str) + assert runtime_config.__class__ == dict + assert "editor" in runtime_config.keys() + assert "colors.title" in runtime_config.keys() + assert "default" in runtime_config.keys() + + def test_deserialize_int(self): + input = "linewrap: 23, default_hour: 19" + runtime_config = deserialize_config_args(input) + assert runtime_config["linewrap"] == 23 + assert runtime_config["default_hour"] == 19 + + def test_deserialize_multiple_datatypes(self): + input = ( + 'linewrap: 23, encrypt: false, editor:"vi -c startinsert", highlight: true' + ) + cfg = deserialize_config_args(input) + assert cfg["encrypt"] == False + assert cfg["highlight"] == True + assert cfg["linewrap"] == 23 + assert cfg["editor"] == '"vi -c startinsert"' + + @pytest.mark.parametrize( + "delimiter", + [ + ".", + ":", + ", ", # note the whitespaces + "-|-", # no reason not to handle multi-character delimiters + ], + ) + def test_split_at_delimiter(self, delimiter): + input = delimiter.join( + ["eggs ", "ba con", "ham"] + ) # The whitespaces are deliberate + from jrnl.args import _split_at_delimiter + + assert _split_at_delimiter(input, delimiter) == ["eggs ", "ba con", "ham"] + assert _split_at_delimiter(input, delimiter, " ") == ["eggs ", "ba con", "ham"] From 3b7e05c69f17a50528fc8caee7a8bb2238e9aeee Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 08:36:58 -0500 Subject: [PATCH 70/82] update tests ith better verifications --- features/steps/override.py | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/features/steps/override.py b/features/steps/override.py index d1857b0b..365e9795 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -71,8 +71,8 @@ def config_override(context, key_as_dots: str, override_value: str): @then("the editor {editor} should have been called") def editor_override(context, editor): def _mock_write_in_editor(config): - editor = config["editor"] - journal = "features/journals/journal.jrnl" + editor = config['editor'] + journal = 'features/journals/journal.jrnl' context.tmpfile = journal print("%s has been launched" % editor) return journal @@ -101,20 +101,11 @@ def editor_override(context, editor): # fmt: on -@then("the stdin prompt must be launched") -def override_editor_to_use_stdin(context): - - try: - with mock.patch( - "sys.stdin.read", - return_value="Zwei peanuts walk into a bar und one of zem was a-salted", - ) as mock_stdin_read, mock.patch( - "jrnl.install.load_or_install_jrnl", return_value=context.cfg - ), mock.patch( - "jrnl.Journal.open_journal", - spec=False, - return_value="features/journals/journal.jrnl", - ): + try: + with \ + mock.patch('sys.stdin.read', return_value='Zwei peanuts walk into a bar und one of zem was a-salted')as mock_stdin_read, \ + mock.patch("jrnl.install.load_or_install_jrnl", return_value=context.cfg), \ + mock.patch("jrnl.Journal.open_journal", spec=False, return_value='features/journals/journal.jrnl'): run(context.parser) context.exit_status = 0 mock_stdin_read.assert_called_once() From adb79328172e0e2ead8b0be6ecf441cc6b75d766 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 08:40:28 -0500 Subject: [PATCH 71/82] make format --- features/overrides.feature | 2 +- features/steps/override.py | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/features/overrides.feature b/features/overrides.feature index 4343cdb1..b5e53a98 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -36,7 +36,7 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys @skip_win Scenario: Apply multiple config overrides Given we use the config "tiny.yaml" - When we run jrnl with -1 --config-override colors.body:green,editor:"nano" + When we run jrnl with -1 --config-override colors.body:green, editor:"nano" Then the runtime config should have colors.body set to green And the runtime config should have editor set to nano diff --git a/features/steps/override.py b/features/steps/override.py index 365e9795..d1857b0b 100644 --- a/features/steps/override.py +++ b/features/steps/override.py @@ -71,8 +71,8 @@ def config_override(context, key_as_dots: str, override_value: str): @then("the editor {editor} should have been called") def editor_override(context, editor): def _mock_write_in_editor(config): - editor = config['editor'] - journal = 'features/journals/journal.jrnl' + editor = config["editor"] + journal = "features/journals/journal.jrnl" context.tmpfile = journal print("%s has been launched" % editor) return journal @@ -101,11 +101,20 @@ def editor_override(context, editor): # fmt: on - try: - with \ - mock.patch('sys.stdin.read', return_value='Zwei peanuts walk into a bar und one of zem was a-salted')as mock_stdin_read, \ - mock.patch("jrnl.install.load_or_install_jrnl", return_value=context.cfg), \ - mock.patch("jrnl.Journal.open_journal", spec=False, return_value='features/journals/journal.jrnl'): +@then("the stdin prompt must be launched") +def override_editor_to_use_stdin(context): + + try: + with mock.patch( + "sys.stdin.read", + return_value="Zwei peanuts walk into a bar und one of zem was a-salted", + ) as mock_stdin_read, mock.patch( + "jrnl.install.load_or_install_jrnl", return_value=context.cfg + ), mock.patch( + "jrnl.Journal.open_journal", + spec=False, + return_value="features/journals/journal.jrnl", + ): run(context.parser) context.exit_status = 0 mock_stdin_read.assert_called_once() From 56255cd69c289b4057547247aa4704b3beb8dc69 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 08:42:20 -0500 Subject: [PATCH 72/82] space --- features/overrides.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/overrides.feature b/features/overrides.feature index b5e53a98..4343cdb1 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -36,7 +36,7 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys @skip_win Scenario: Apply multiple config overrides Given we use the config "tiny.yaml" - When we run jrnl with -1 --config-override colors.body:green, editor:"nano" + When we run jrnl with -1 --config-override colors.body:green,editor:"nano" Then the runtime config should have colors.body set to green And the runtime config should have editor set to nano From ac85511dfebe4b7dd60e63655c75f3a4e84974dc Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 20:58:57 -0500 Subject: [PATCH 73/82] make format --- tests/test_parse_args.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index 3811cd9d..5c469e47 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -206,6 +206,7 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) + def test_editor_override(): parsed_args = cli_as_dict('--config-override editor:"nano"') From dbf4650004824c8bc1de80ee3e5a516afd75c23b Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 21:30:10 -0500 Subject: [PATCH 74/82] document apply_overrides --- jrnl/override.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/jrnl/override.py b/jrnl/override.py index a330b7a9..160bcbcf 100644 --- a/jrnl/override.py +++ b/jrnl/override.py @@ -1,5 +1,14 @@ # import logging def apply_overrides(overrides: dict, base_config: dict) -> dict: + """Unpack parsed overrides in dot-notation and return the "patched" configuration + + Args: + overrides (dict): Single-level dict of config fields in dot-notation and their desired values + base_config (dict): The "saved" configuration, as read from YAML + + Returns: + dict: Updated configuration with applied overrides, in the format of the loaded configuration + """ config = base_config.copy() for k in overrides: nodes = k.split(".") @@ -13,9 +22,9 @@ def _recursively_apply(config: dict, nodes: list, override_value) -> dict: Credit to iJames on SO: https://stackoverflow.com/a/47276490 for algorithm Args: - config (dict): loaded configuration from YAML - nodes (list): vector of override keys; the length of the vector indicates tree depth - override_value (str): runtime override passed from the command-line + config (dict): Configuration to modify + nodes (list): Vector of override keys; the length of the vector indicates tree depth + override_value (str): Runtime override passed from the command-line """ key = nodes[0] if len(nodes) == 1: From 7df83aa44a7c59a21969623b4f6ff8eb713450ab Mon Sep 17 00:00:00 2001 From: Suhas Date: Fri, 29 Jan 2021 20:11:00 -0500 Subject: [PATCH 75/82] update gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 629a9504..374deb4b 100644 --- a/.gitignore +++ b/.gitignore @@ -59,4 +59,5 @@ site/ coverage.xml .vscode/launch.json .coverage -.vscode/tasks.json \ No newline at end of file +.vscode/tasks.json +todo.txt From 40f93a9322cf7eeb41f894e52227d514c4c33906 Mon Sep 17 00:00:00 2001 From: Suhas Date: Fri, 29 Jan 2021 20:11:13 -0500 Subject: [PATCH 76/82] document config-override enhancement --- docs/advanced.md | 22 ++++++++++++++++++++++ docs/recipes.md | 27 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/docs/advanced.md b/docs/advanced.md index 51c4d1af..a778bd29 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -61,6 +61,28 @@ and can be edited with a plain text editor. Or use the built-in prompt or an external editor to compose your entries. +### Modifying Configurations from the Command line + +You can override a configuration field for the current instance of `jrnl` using `--config-override CONFIG_KEY:CONFIG_VALUE` where `CONFIG_KEY` is a valid configuration field, specified in dot-notation and `CONFIG_VALUE` is the (valid) desired override value. + +You can specify multiple overrides as a comma-separated list. +!!! note + These overrides allow you to modify ***any*** field of your jrnl configuration. We trust that you know what you are doing. + +#### Examples: + +``` sh +#Create an entry using the `stdin` prompt, for rapid logging +jrnl --config-override editor:"" + +#Populate a project's log +jrnl --config-override journal:"$(git rev-parse --show-toplevel)/todo.txt" + +#Pass multiple overrides +jrnl --config-override display_format:fancy,linewrap:20,colors.title:green + +``` + ## Multiple journal files You can configure `jrnl`to use with multiple journals (eg. diff --git a/docs/recipes.md b/docs/recipes.md index 14e08e14..ef45666a 100644 --- a/docs/recipes.md +++ b/docs/recipes.md @@ -154,6 +154,33 @@ only field 1. jrnl -on "$(jrnl --short | shuf -n 1 | cut -d' ' -f1,2)" ``` + +### Launch a terminal for rapid logging +You can use this to launch a terminal that is the `jrnl` stdin prompt so you can start typing away immediately. + +```bash +jrnl now --config-override editor:"" +``` + +Bind this to a keyboard shortcut. + +Map `Super+Alt+J` to launch the terminal with jrnl prompt + +- **xbindkeys** +In your `.xbindkeysrc` + +```ini +Mod4+Mod1+j + alacritty -t floating-jrnl -e jrnl now --config-override editor:"", +``` + +- **I3 WM** Launch a floating terminal with the `jrnl` prompt + +```ini +bindsym Mod4+Mod1+j exec --no-startup-id alacritty -t floating-jrnl -e jrnl --config-override editor:"" +for_window[title="floating *"] floating enable +``` + ## External editors Configure your preferred external editor by updating the `editor` option From 6e658c31df5c01848f04fe0afe826fd663c5c51d Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 31 Jan 2021 20:17:02 -0500 Subject: [PATCH 77/82] Simplify config override syntax (#5) * update tests and expected behavior * clean up arg parsing tests * update deserialization * update deserialization * config argparse action * update override application logic * update tests; delete unused imports * override param must be list * update docstring * update test input to SUT * update remaining override unittests * make format * forgot to update CLI syntax --- features/overrides.feature | 10 +++--- jrnl/args.py | 71 ++++++++++++++++---------------------- jrnl/override.py | 21 +++++------ tests/test_config.py | 10 +++--- tests/test_override.py | 14 ++++---- tests/test_parse_args.py | 70 +++++++++++++------------------------ 6 files changed, 82 insertions(+), 114 deletions(-) diff --git a/features/overrides.feature b/features/overrides.feature index 4343cdb1..103a43ac 100644 --- a/features/overrides.feature +++ b/features/overrides.feature @@ -2,13 +2,13 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys Scenario: Override configured editor with built-in input === editor:'' Given we use the config "tiny.yaml" - When we run jrnl with --config-override editor:'' + When we run jrnl with --config-override editor '' Then the stdin prompt must be launched @skip_win Scenario: Override configured linewrap with a value of 23 Given we use the config "tiny.yaml" - When we run "jrnl -2 --config-override linewrap:23 --format fancy" + When we run "jrnl -2 --config-override linewrap 23 --format fancy" Then the output should be """ @@ -30,13 +30,13 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys @skip_win Scenario: Override color selections with runtime overrides Given we use the config "tiny.yaml" - When we run jrnl with -1 --config-override colors.body:blue + When we run jrnl with -1 --config-override colors.body blue Then the runtime config should have colors.body set to blue @skip_win Scenario: Apply multiple config overrides Given we use the config "tiny.yaml" - When we run jrnl with -1 --config-override colors.body:green,editor:"nano" + When we run jrnl with -1 --config-override colors.body green --config-override editor "nano" Then the runtime config should have colors.body set to green And the runtime config should have editor set to nano @@ -44,7 +44,7 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys @skip_win Scenario Outline: Override configured editor Given we use the config "tiny.yaml" - When we run jrnl with --config-override editor:"" + When we run jrnl with --config-override editor "" Then the editor should have been called Examples: Editor Commands | editor | diff --git a/jrnl/args.py b/jrnl/args.py index 046d29a8..fa76ecbe 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -17,20 +17,8 @@ from .plugins import IMPORT_FORMATS from .plugins import util -def deserialize_config_args(input: str) -> dict: - """Convert a delimited list of configuration key-value pairs into a flat dict - - Example: - An input of - `colors.title: blue, display_format: json, colors.date: green` - will return - ```json - { - 'colors.title': 'blue', - 'display_format': 'json', - 'colors.date': 'green' - } - ``` +def deserialize_config_args(input: list) -> dict: + """Convert a two-element list of configuration key-value pair into a flat dict Args: input (str): list of configuration keys in dot-notation and their respective values. @@ -38,29 +26,30 @@ def deserialize_config_args(input: str) -> dict: Returns: dict: A single level dict of the configuration keys in dot-notation and their respective desired values """ - slug_delimiter = "," - key_value_separator = ":" - _kvpairs = _split_at_delimiter( - input, slug_delimiter, " " - ) # Strip away all whitespace in input, not just leading + assert len(input) == 2 runtime_modifications = {} - for _p in _kvpairs: - l, r = _split_at_delimiter(_p, key_value_separator) - r = r.strip() - if r.isdigit(): - r = int(r) - elif r.lower() == "true": - r = True - elif r.lower() == "false": - r = False - runtime_modifications[l] = r + + l = input[0] + r = input[1] + r = r.strip() + if r.isdigit(): + r = int(r) + elif r.lower() == "true": + r = True + elif r.lower() == "false": + r = False + runtime_modifications[l] = r return runtime_modifications -def _split_at_delimiter( - input: str, slug_delimiter: str, whitespace_to_strip=None -) -> list: - return input.strip(whitespace_to_strip).split(slug_delimiter) +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): @@ -361,25 +350,25 @@ def parse_args(args=[]): ) config_overrides = parser.add_argument_group( - "Config file overrides", - textwrap.dedent("These are one-off overrides of the config file options"), + "Config file override", + textwrap.dedent("Apply a one-off override of the config file option"), ) config_overrides.add_argument( "--config-override", dest="config_override", - action="store", - type=deserialize_config_args, - nargs="?", - default=None, + action=ConfigurationAction, + type=str, + nargs=2, + default=[], metavar="CONFIG_KV_PAIR", help=""" - Override configured key-value pairs with CONFIG_KV_PAIR for this command invocation only. + Override configured key-value pair with CONFIG_KV_PAIR for this command invocation only. Examples: \n \t - Use a different editor for this jrnl entry, call: \n \t jrnl --config-override editor: "nano" \n \t - Override color selections\n - \t jrnl --config-override colors.body: blue, colors.title: green + \t jrnl --config-override colors.body blue --config-override colors.title green """, ) diff --git a/jrnl/override.py b/jrnl/override.py index 160bcbcf..01904710 100644 --- a/jrnl/override.py +++ b/jrnl/override.py @@ -1,18 +1,19 @@ # import logging -def apply_overrides(overrides: dict, base_config: dict) -> dict: - """Unpack parsed overrides in dot-notation and return the "patched" configuration +def apply_overrides(overrides: list, base_config: dict) -> dict: + """Unpack CLI provided overrides into the configuration tree. - Args: - overrides (dict): Single-level dict of config fields in dot-notation and their desired values - base_config (dict): The "saved" configuration, as read from YAML - - Returns: - dict: Updated configuration with applied overrides, in the format of the loaded configuration + :param overrides: List of configuration key-value pairs collected from the CLI + :type overrides: list + :param base_config: Configuration Loaded from the saved YAML + :type base_config: dict + :return: Configuration to be used during runtime with the overrides applied + :rtype: dict """ config = base_config.copy() - for k in overrides: + for pairs in overrides: + k, v = list(pairs.items())[0] nodes = k.split(".") - config = _recursively_apply(config, nodes, overrides[k]) + config = _recursively_apply(config, nodes, v) return config diff --git a/tests/test_config.py b/tests/test_config.py index dc2650a8..aa1b01ee 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -43,10 +43,10 @@ def test_override_configured_editor( mock_load_or_install.return_value = minimal_config mock_isatty.return_value = True - cli_args = shlex.split('--config-override editor:"nano"') + cli_args = shlex.split('--config-override editor "nano"') parser = parse_args(cli_args) assert parser.config_override.__len__() == 1 - assert "editor" in parser.config_override.keys() + assert {"editor": "nano"} in parser.config_override def mock_editor_launch(editor): print("%s launched! Success!" % editor) @@ -54,7 +54,7 @@ def test_override_configured_editor( with mock.patch.object( jrnl, "_write_in_editor", - side_effect=mock_editor_launch(parser.config_override["editor"]), + side_effect=mock_editor_launch("TODO: replace"), return_value="note_contents", ) as mock_write_in_editor: run(parser) @@ -84,9 +84,9 @@ def test_override_configured_colors( ): mock_load_or_install.return_value = minimal_config - cli_args = shlex.split("--config-override colors.body:blue") + cli_args = shlex.split("--config-override colors.body blue") parser = parse_args(cli_args) - assert "colors.body" in parser.config_override.keys() + assert {"colors.body": "blue"} in parser.config_override with mock.patch.object( jrnl, "_write_in_editor", diff --git a/tests/test_override.py b/tests/test_override.py index b7bc0a4a..c673f304 100644 --- a/tests/test_override.py +++ b/tests/test_override.py @@ -16,24 +16,24 @@ def minimal_config(): def test_apply_override(minimal_config): config = minimal_config.copy() - overrides = {"editor": "nano"} + overrides = [{"editor": "nano"}] config = apply_overrides(overrides, config) assert config["editor"] == "nano" def test_override_dot_notation(minimal_config): cfg = minimal_config.copy() - overrides = {"colors.body": "blue"} + overrides = [{"colors.body": "blue"}] cfg = apply_overrides(overrides=overrides, base_config=cfg) assert cfg["colors"] == {"body": "blue", "date": "green"} def test_multiple_overrides(minimal_config): - overrides = { - "colors.title": "magenta", - "editor": "nano", - "journals.burner": "/tmp/journals/burner.jrnl", - } # as returned by parse_args, saved in parser.config_override + overrides = [ + {"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.copy()) assert cfg["editor"] == "nano" diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index 5c469e47..feb31d07 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -36,7 +36,7 @@ def expected_args(**kwargs): "strict": False, "tags": False, "text": [], - "config_override": None, + "config_override": [], } return {**default_args, **kwargs} @@ -209,26 +209,26 @@ 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"}) + parsed_args = cli_as_dict('--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"} + assert cli_as_dict("--config-override colors.body blue") == expected_args( + config_override=[{"colors.body": "blue"}] ) def test_multiple_overrides(): parsed_args = cli_as_dict( - '--config-override colors.title:green,editor:"nano",journal.scratchpad:"/tmp/scratchpad"' + '--config-override colors.title green --config-override editor "nano" --config-override journal.scratchpad "/tmp/scratchpad"' ) assert parsed_args == expected_args( - config_override={ - "colors.title": "green", - "journal.scratchpad": "/tmp/scratchpad", - "editor": "nano", - } + config_override=[ + {"colors.title": "green"}, + {"editor": "nano"}, + {"journal.scratchpad": "/tmp/scratchpad"}, + ] ) @@ -266,49 +266,27 @@ class TestDeserialization: @pytest.mark.parametrize( "input_str", [ - 'editor:"nano", colors.title:blue, default:"/tmp/egg.txt"', - 'editor:"vi -c startinsert", colors.title:blue, default:"/tmp/egg.txt"', - 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"', + ["editor", '"nano"'], + ["colors.title", "blue"], + ["default", "/tmp/egg.txt"], ], ) def test_deserialize_multiword_strings(self, input_str): runtime_config = deserialize_config_args(input_str) assert runtime_config.__class__ == dict - assert "editor" in runtime_config.keys() - assert "colors.title" in runtime_config.keys() - assert "default" in runtime_config.keys() - - def test_deserialize_int(self): - input = "linewrap: 23, default_hour: 19" - runtime_config = deserialize_config_args(input) - assert runtime_config["linewrap"] == 23 - assert runtime_config["default_hour"] == 19 + assert input_str[0] in runtime_config.keys() + assert runtime_config[input_str[0]] == input_str[1] def test_deserialize_multiple_datatypes(self): - input = ( - 'linewrap: 23, encrypt: false, editor:"vi -c startinsert", highlight: true' - ) - cfg = deserialize_config_args(input) - assert cfg["encrypt"] == False - assert cfg["highlight"] == True + cfg = deserialize_config_args(["linewrap", "23"]) assert cfg["linewrap"] == 23 + + cfg = deserialize_config_args(["encrypt", "false"]) + assert cfg["encrypt"] == False + + cfg = deserialize_config_args(["editor", '"vi -c startinsert"']) assert cfg["editor"] == '"vi -c startinsert"' - @pytest.mark.parametrize( - "delimiter", - [ - ".", - ":", - ", ", # note the whitespaces - "-|-", # no reason not to handle multi-character delimiters - ], - ) - def test_split_at_delimiter(self, delimiter): - input = delimiter.join( - ["eggs ", "ba con", "ham"] - ) # The whitespaces are deliberate - from jrnl.args import _split_at_delimiter - - assert _split_at_delimiter(input, delimiter) == ["eggs ", "ba con", "ham"] - assert _split_at_delimiter(input, delimiter, " ") == ["eggs ", "ba con", "ham"] + cfg = deserialize_config_args(["highlight", "true"]) + assert cfg["highlight"] == True From e26fd0721bcaa6b72cc4f6958c33b8889237270a Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 31 Jan 2021 20:31:13 -0500 Subject: [PATCH 78/82] update documentation to sphinx style --- jrnl/args.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/jrnl/args.py b/jrnl/args.py index fa76ecbe..c54b6816 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -18,13 +18,14 @@ from .plugins import util def deserialize_config_args(input: list) -> dict: - """Convert a two-element list of configuration key-value pair into a flat dict + """ - Args: - input (str): list of configuration keys in dot-notation and their respective values. + Convert a two-element list of configuration key-value pair into a flat dict - Returns: - dict: A single level dict of the configuration keys in dot-notation and their respective desired values + :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 runtime_modifications = {} From 318e45e2adf9e21ed8c8e8a3947c3d092436f461 Mon Sep 17 00:00:00 2001 From: Suhas Date: Sun, 31 Jan 2021 20:31:23 -0500 Subject: [PATCH 79/82] variable renames --- jrnl/args.py | 24 ++++++++++++++---------- jrnl/override.py | 14 +++++++------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/jrnl/args.py b/jrnl/args.py index c54b6816..4e7c1199 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -27,19 +27,23 @@ def deserialize_config_args(input: list) -> dict: :return: A single level dict of the configuration keys in dot-notation and their respective desired values :rtype: dict """ + assert len(input) == 2 runtime_modifications = {} - l = input[0] - r = input[1] - r = r.strip() - if r.isdigit(): - r = int(r) - elif r.lower() == "true": - r = True - elif r.lower() == "false": - r = False - runtime_modifications[l] = r + cfg_key = input[0] + cfg_value = input[1] + cfg_value = cfg_value.strip() + + # Convert numbers and booleans + if cfg_value.isdigit(): + cfg_value = int(cfg_value) + elif cfg_value.lower() == "true": + cfg_value = True + elif cfg_value.lower() == "false": + cfg_value = False + + runtime_modifications[cfg_key] = cfg_value return runtime_modifications diff --git a/jrnl/override.py b/jrnl/override.py index 01904710..5eb00a39 100644 --- a/jrnl/override.py +++ b/jrnl/override.py @@ -11,13 +11,13 @@ def apply_overrides(overrides: list, base_config: dict) -> dict: """ config = base_config.copy() for pairs in overrides: - k, v = list(pairs.items())[0] - nodes = k.split(".") - config = _recursively_apply(config, nodes, v) + key_as_dots, override_value = list(pairs.items())[0] + keys = key_as_dots.split(".") + config = _recursively_apply(config, keys, override_value) return config -def _recursively_apply(config: dict, nodes: list, override_value) -> dict: +def _recursively_apply(tree: dict, nodes: list, override_value) -> dict: """Recurse through configuration and apply overrides at the leaf of the config tree Credit to iJames on SO: https://stackoverflow.com/a/47276490 for algorithm @@ -29,12 +29,12 @@ def _recursively_apply(config: dict, nodes: list, override_value) -> dict: """ key = nodes[0] if len(nodes) == 1: - config[key] = override_value + tree[key] = override_value else: next_key = nodes[1:] - _recursively_apply(_get_config_node(config, key), next_key, override_value) + _recursively_apply(_get_config_node(tree, key), next_key, override_value) - return config + return tree def _get_config_node(config: dict, key: str): From a51db6c6149fecbe9304b9784c3777ea4ff06a63 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Feb 2021 13:21:56 -0500 Subject: [PATCH 80/82] Bump pytz from 2020.5 to 2021.1 (#6) Bumps [pytz](https://github.com/stub42/pytz) from 2020.5 to 2021.1. - [Release notes](https://github.com/stub42/pytz/releases) - [Commits](https://github.com/stub42/pytz/compare/release_2020.5...release_2021.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index df676e25..9932c1fe 100644 --- a/poetry.lock +++ b/poetry.lock @@ -511,7 +511,7 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2020.5" +version = "2021.1" description = "World timezone definitions, modern and historical" category = "main" optional = false @@ -874,20 +874,39 @@ markupsafe = [ {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b"}, {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-win32.whl", hash = "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39"}, + {file = "MarkupSafe-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8"}, {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, ] mkdocs = [ @@ -961,8 +980,8 @@ python-dateutil = [ {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, ] pytz = [ - {file = "pytz-2020.5-py2.py3-none-any.whl", hash = "sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4"}, - {file = "pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"}, + {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"}, + {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"}, ] pywin32-ctypes = [ {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, From d55fa4134afac0b21893998a45898143fa538c3b Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 1 Feb 2021 13:22:55 -0500 Subject: [PATCH 81/82] Lockfile merge (#7) * Add brew and gitter badges to README * Update changelog [ci skip] * Make journal selection behavior more consistent when there's a colon with no date (#1164) * Bump pytest from 6.2.1 to 6.2.2 (#1167) Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.1 to 6.2.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/6.2.1...6.2.2) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump keyring from 21.8.0 to 22.0.1 (#1168) Bumps [keyring](https://github.com/jaraco/keyring) from 21.8.0 to 22.0.1. - [Release notes](https://github.com/jaraco/keyring/releases) - [Changelog](https://github.com/jaraco/keyring/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/keyring/compare/v21.8.0...v22.0.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update changelog [ci skip] Co-authored-by: Micah Jerome Ellison Co-authored-by: Jrnl Bot Co-authored-by: Jonathan Wren Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- CHANGELOG.md | 17 +++++++++++++++++ README.md | 2 ++ features/multiple_journals.feature | 14 ++++++++++++++ jrnl/config.py | 16 ++++++++++++---- poetry.lock | 10 ++-------- 5 files changed, 47 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72eb0379..88b1286d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## [Unreleased](https://github.com/jrnl-org/jrnl/) + +[Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7...HEAD) + +**Implemented enhancements:** + +- Allow timestamps in command line for new entries with editor [\#1083](https://github.com/jrnl-org/jrnl/issues/1083) + +**Fixed bugs:** + +- Make journal selection behavior more consistent when there's a colon with no date [\#1164](https://github.com/jrnl-org/jrnl/pull/1164) ([wren](https://github.com/wren)) + +**Packaging:** + +- Bump keyring from 21.8.0 to 22.0.1 [\#1168](https://github.com/jrnl-org/jrnl/pull/1168) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump pytest from 6.2.1 to 6.2.2 [\#1167](https://github.com/jrnl-org/jrnl/pull/1167) ([dependabot[bot]](https://github.com/apps/dependabot)) + ## [v2.7](https://pypi.org/project/jrnl/v2.7/) (2021-01-23) [Full Changelog](https://github.com/jrnl-org/jrnl/compare/v2.7-beta...v2.7) diff --git a/README.md b/README.md index bc295f6c..55202436 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ jrnl [![Testing](https://github.com/jrnl-org/jrnl/workflows/Testing/badge.svg)](https://github.com/jrnl-org/jrnl/actions?query=workflow%3ATesting) [![Downloads](https://pepy.tech/badge/jrnl)](https://pepy.tech/project/jrnl) [![Version](http://img.shields.io/pypi/v/jrnl.svg?style=flat)](https://pypi.python.org/pypi/jrnl/) + [![Homebrew](https://img.shields.io/homebrew/v/jrnl?style=flat-square)](https://formulae.brew.sh/formula/jrnl) + [![Gitter](https://img.shields.io/gitter/room/jrnl-org/jrnl)](https://gitter.im/jrnl-org/jrnl) ==== _To get help, [submit an issue](https://github.com/jrnl-org/jrnl/issues/new/choose) on diff --git a/features/multiple_journals.feature b/features/multiple_journals.feature index 6a9efe78..222be100 100644 --- a/features/multiple_journals.feature +++ b/features/multiple_journals.feature @@ -29,6 +29,20 @@ Feature: Multiple journals And journal "work" should have 1 entry And journal "work" should contain "2012-07-23" + Scenario: Write to specified journal without a timestamp but with colon + Given we use the config "multiple.yaml" + When we run "jrnl work : a long day in the office" + Then journal "default" should have 2 entries + And journal "work" should have 1 entry + And journal "work" should contain "a long day in the office" + + Scenario: Write to specified journal without a timestamp but with colon + Given we use the config "multiple.yaml" + When we run "jrnl work: a long day in the office" + Then journal "default" should have 2 entries + And journal "work" should have 1 entry + And journal "work" should contain "a long day in the office" + Scenario: Create new journals as required Given we use the config "multiple.yaml" Then journal "ideas" should not exist diff --git a/jrnl/config.py b/jrnl/config.py index 9e57de3d..a5a1d1cc 100644 --- a/jrnl/config.py +++ b/jrnl/config.py @@ -138,10 +138,18 @@ def update_config(config, new_config, scope, force_local=False): def get_journal_name(args, config): args.journal_name = DEFAULT_JOURNAL_KEY - if args.text and args.text[0] in config["journals"]: - args.journal_name = args.text[0] - args.text = args.text[1:] - elif DEFAULT_JOURNAL_KEY not in config["journals"]: + + # The first arg might be a journal name + if args.text: + potential_journal_name = args.text[0] + if potential_journal_name[-1] == ":": + potential_journal_name = potential_journal_name[0:-1] + + if potential_journal_name in config["journals"]: + args.journal_name = potential_journal_name + args.text = args.text[1:] + + if args.journal_name not in config["journals"]: print("No default journal configured.", file=sys.stderr) print(list_journals(config), file=sys.stderr) sys.exit(1) diff --git a/poetry.lock b/poetry.lock index 9932c1fe..c30a0abd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -966,14 +966,8 @@ pyparsing = [ pytest = [ {file = "pytest-6.2.2-py3-none-any.whl", hash = "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839"}, {file = "pytest-6.2.2.tar.gz", hash = "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9"}, -] -pytest-cov = [ - {file = "pytest-cov-2.11.1.tar.gz", hash = "sha256:359952d9d39b9f822d9d29324483e7ba04a3a17dd7d05aa6beb7ea01e359e5f7"}, - {file = "pytest_cov-2.11.1-py2.py3-none-any.whl", hash = "sha256:bdb9fdb0b85a7cc825269a4c56b48ccaa5c7e365054b6038772c32ddcdc969da"}, -] -pytest-mock = [ - {file = "pytest-mock-3.5.1.tar.gz", hash = "sha256:a1e2aba6af9560d313c642dae7e00a2a12b022b80301d9d7fc8ec6858e1dd9fc"}, - {file = "pytest_mock-3.5.1-py3-none-any.whl", hash = "sha256:379b391cfad22422ea2e252bdfc008edd08509029bcde3c25b2c0bd741e0424e"}, + + ] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, From 2be0d3729e093fec623809795f68288765fb6347 Mon Sep 17 00:00:00 2001 From: Suhas Date: Mon, 1 Feb 2021 13:30:59 -0500 Subject: [PATCH 82/82] Simplify config override syntax (#8) * update tests and expected behavior * clean up arg parsing tests * update deserialization * update deserialization * config argparse action * update override application logic * update tests; delete unused imports * override param must be list * update docstring * update test input to SUT * update remaining override unittests * make format * forgot to update CLI syntax --- jrnl/args.py | 2 ++ jrnl/override.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/jrnl/args.py b/jrnl/args.py index 4e7c1199..b3a04192 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -18,6 +18,7 @@ from .plugins import util def deserialize_config_args(input: list) -> dict: + """ Convert a two-element list of configuration key-value pair into a flat dict @@ -44,6 +45,7 @@ def deserialize_config_args(input: list) -> dict: cfg_value = False runtime_modifications[cfg_key] = cfg_value + return runtime_modifications diff --git a/jrnl/override.py b/jrnl/override.py index 5eb00a39..82d6da93 100644 --- a/jrnl/override.py +++ b/jrnl/override.py @@ -11,9 +11,11 @@ def apply_overrides(overrides: list, base_config: dict) -> dict: """ config = base_config.copy() for pairs in overrides: + key_as_dots, override_value = list(pairs.items())[0] keys = key_as_dots.split(".") config = _recursively_apply(config, keys, override_value) + return config