mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-05-20 13:08:31 +02:00
Merge branch 'develop' into lockfile-merge
This commit is contained in:
commit
f250406e7d
7 changed files with 123 additions and 127 deletions
|
@ -2,13 +2,13 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys
|
||||||
|
|
||||||
Scenario: Override configured editor with built-in input === editor:''
|
Scenario: Override configured editor with built-in input === editor:''
|
||||||
Given we use the config "tiny.yaml"
|
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
|
Then the stdin prompt must be launched
|
||||||
|
|
||||||
@skip_win
|
@skip_win
|
||||||
Scenario: Override configured linewrap with a value of 23
|
Scenario: Override configured linewrap with a value of 23
|
||||||
Given we use the config "tiny.yaml"
|
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
|
Then the output should be
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -30,13 +30,13 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys
|
||||||
@skip_win
|
@skip_win
|
||||||
Scenario: Override color selections with runtime overrides
|
Scenario: Override color selections with runtime overrides
|
||||||
Given we use the config "tiny.yaml"
|
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
|
Then the runtime config should have colors.body set to blue
|
||||||
|
|
||||||
@skip_win
|
@skip_win
|
||||||
Scenario: Apply multiple config overrides
|
Scenario: Apply multiple config overrides
|
||||||
Given we use the config "tiny.yaml"
|
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
|
Then the runtime config should have colors.body set to green
|
||||||
And the runtime config should have editor set to nano
|
And the runtime config should have editor set to nano
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys
|
||||||
@skip_win
|
@skip_win
|
||||||
Scenario Outline: Override configured editor
|
Scenario Outline: Override configured editor
|
||||||
Given we use the config "tiny.yaml"
|
Given we use the config "tiny.yaml"
|
||||||
When we run jrnl with --config-override editor:"<editor>"
|
When we run jrnl with --config-override editor "<editor>"
|
||||||
Then the editor <editor> should have been called
|
Then the editor <editor> should have been called
|
||||||
Examples: Editor Commands
|
Examples: Editor Commands
|
||||||
| editor |
|
| editor |
|
||||||
|
|
88
jrnl/args.py
88
jrnl/args.py
|
@ -17,50 +17,46 @@ from .plugins import IMPORT_FORMATS
|
||||||
from .plugins import util
|
from .plugins import util
|
||||||
|
|
||||||
|
|
||||||
def deserialize_config_args(input: str) -> dict:
|
def deserialize_config_args(input: list) -> 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'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
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 = ":"
|
Convert a two-element list of configuration key-value pair into a flat dict
|
||||||
_kvpairs = _split_at_delimiter(
|
|
||||||
input, slug_delimiter, " "
|
:param input: list of configuration keys in dot-notation and their respective values.
|
||||||
) # Strip away all whitespace in input, not just leading
|
: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 = {}
|
runtime_modifications = {}
|
||||||
for _p in _kvpairs:
|
|
||||||
l, r = _split_at_delimiter(_p, key_value_separator)
|
cfg_key = input[0]
|
||||||
r = r.strip()
|
cfg_value = input[1]
|
||||||
if r.isdigit():
|
cfg_value = cfg_value.strip()
|
||||||
r = int(r)
|
|
||||||
elif r.lower() == "true":
|
# Convert numbers and booleans
|
||||||
r = True
|
if cfg_value.isdigit():
|
||||||
elif r.lower() == "false":
|
cfg_value = int(cfg_value)
|
||||||
r = False
|
elif cfg_value.lower() == "true":
|
||||||
runtime_modifications[l] = r
|
cfg_value = True
|
||||||
|
elif cfg_value.lower() == "false":
|
||||||
|
cfg_value = False
|
||||||
|
|
||||||
|
runtime_modifications[cfg_key] = cfg_value
|
||||||
|
|
||||||
return runtime_modifications
|
return runtime_modifications
|
||||||
|
|
||||||
|
|
||||||
def _split_at_delimiter(
|
class ConfigurationAction(argparse.Action):
|
||||||
input: str, slug_delimiter: str, whitespace_to_strip=None
|
def __init__(self, **kwargs) -> None:
|
||||||
) -> list:
|
super().__init__(**kwargs)
|
||||||
return input.strip(whitespace_to_strip).split(slug_delimiter)
|
|
||||||
|
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):
|
class WrappingFormatter(argparse.RawTextHelpFormatter):
|
||||||
|
@ -361,25 +357,25 @@ def parse_args(args=[]):
|
||||||
)
|
)
|
||||||
|
|
||||||
config_overrides = parser.add_argument_group(
|
config_overrides = parser.add_argument_group(
|
||||||
"Config file overrides",
|
"Config file override",
|
||||||
textwrap.dedent("These are one-off overrides of the config file options"),
|
textwrap.dedent("Apply a one-off override of the config file option"),
|
||||||
)
|
)
|
||||||
config_overrides.add_argument(
|
config_overrides.add_argument(
|
||||||
"--config-override",
|
"--config-override",
|
||||||
dest="config_override",
|
dest="config_override",
|
||||||
action="store",
|
action=ConfigurationAction,
|
||||||
type=deserialize_config_args,
|
type=str,
|
||||||
nargs="?",
|
nargs=2,
|
||||||
default=None,
|
default=[],
|
||||||
metavar="CONFIG_KV_PAIR",
|
metavar="CONFIG_KV_PAIR",
|
||||||
help="""
|
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
|
Examples: \n
|
||||||
\t - Use a different editor for this jrnl entry, call: \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 - 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
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
# import logging
|
# import logging
|
||||||
def apply_overrides(overrides: dict, base_config: dict) -> dict:
|
def apply_overrides(overrides: list, base_config: dict) -> dict:
|
||||||
"""Unpack parsed overrides in dot-notation and return the "patched" configuration
|
"""Unpack CLI provided overrides into the configuration tree.
|
||||||
|
|
||||||
Args:
|
:param overrides: List of configuration key-value pairs collected from the CLI
|
||||||
overrides (dict): Single-level dict of config fields in dot-notation and their desired values
|
:type overrides: list
|
||||||
base_config (dict): The "saved" configuration, as read from YAML
|
:param base_config: Configuration Loaded from the saved YAML
|
||||||
|
:type base_config: dict
|
||||||
Returns:
|
:return: Configuration to be used during runtime with the overrides applied
|
||||||
dict: Updated configuration with applied overrides, in the format of the loaded configuration
|
:rtype: dict
|
||||||
"""
|
"""
|
||||||
config = base_config.copy()
|
config = base_config.copy()
|
||||||
for k in overrides:
|
for pairs in overrides:
|
||||||
nodes = k.split(".")
|
|
||||||
config = _recursively_apply(config, nodes, overrides[k])
|
key_as_dots, override_value = list(pairs.items())[0]
|
||||||
|
keys = key_as_dots.split(".")
|
||||||
|
config = _recursively_apply(config, keys, override_value)
|
||||||
|
|
||||||
return config
|
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
|
"""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
|
Credit to iJames on SO: https://stackoverflow.com/a/47276490 for algorithm
|
||||||
|
@ -28,12 +31,12 @@ def _recursively_apply(config: dict, nodes: list, override_value) -> dict:
|
||||||
"""
|
"""
|
||||||
key = nodes[0]
|
key = nodes[0]
|
||||||
if len(nodes) == 1:
|
if len(nodes) == 1:
|
||||||
config[key] = override_value
|
tree[key] = override_value
|
||||||
else:
|
else:
|
||||||
next_key = nodes[1:]
|
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):
|
def _get_config_node(config: dict, key: str):
|
||||||
|
|
25
poetry.lock
generated
25
poetry.lock
generated
|
@ -511,7 +511,7 @@ six = ">=1.5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytz"
|
name = "pytz"
|
||||||
version = "2020.5"
|
version = "2021.1"
|
||||||
description = "World timezone definitions, modern and historical"
|
description = "World timezone definitions, modern and historical"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
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-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"},
|
||||||
{file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"},
|
{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_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_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-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-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"},
|
||||||
{file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"},
|
{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_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_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-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-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"},
|
||||||
{file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"},
|
{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-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_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-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-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"},
|
||||||
{file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"},
|
{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"},
|
{file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
|
||||||
]
|
]
|
||||||
mkdocs = [
|
mkdocs = [
|
||||||
|
@ -955,8 +974,8 @@ python-dateutil = [
|
||||||
{file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
|
{file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
|
||||||
]
|
]
|
||||||
pytz = [
|
pytz = [
|
||||||
{file = "pytz-2020.5-py2.py3-none-any.whl", hash = "sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4"},
|
{file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"},
|
||||||
{file = "pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"},
|
{file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"},
|
||||||
]
|
]
|
||||||
pywin32-ctypes = [
|
pywin32-ctypes = [
|
||||||
{file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"},
|
{file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"},
|
||||||
|
|
|
@ -43,10 +43,10 @@ def test_override_configured_editor(
|
||||||
mock_load_or_install.return_value = minimal_config
|
mock_load_or_install.return_value = minimal_config
|
||||||
mock_isatty.return_value = True
|
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)
|
parser = parse_args(cli_args)
|
||||||
assert parser.config_override.__len__() == 1
|
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):
|
def mock_editor_launch(editor):
|
||||||
print("%s launched! Success!" % editor)
|
print("%s launched! Success!" % editor)
|
||||||
|
@ -54,7 +54,7 @@ def test_override_configured_editor(
|
||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
jrnl,
|
jrnl,
|
||||||
"_write_in_editor",
|
"_write_in_editor",
|
||||||
side_effect=mock_editor_launch(parser.config_override["editor"]),
|
side_effect=mock_editor_launch("TODO: replace"),
|
||||||
return_value="note_contents",
|
return_value="note_contents",
|
||||||
) as mock_write_in_editor:
|
) as mock_write_in_editor:
|
||||||
run(parser)
|
run(parser)
|
||||||
|
@ -84,9 +84,9 @@ def test_override_configured_colors(
|
||||||
):
|
):
|
||||||
mock_load_or_install.return_value = minimal_config
|
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)
|
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(
|
with mock.patch.object(
|
||||||
jrnl,
|
jrnl,
|
||||||
"_write_in_editor",
|
"_write_in_editor",
|
||||||
|
|
|
@ -16,24 +16,24 @@ def minimal_config():
|
||||||
|
|
||||||
def test_apply_override(minimal_config):
|
def test_apply_override(minimal_config):
|
||||||
config = minimal_config.copy()
|
config = minimal_config.copy()
|
||||||
overrides = {"editor": "nano"}
|
overrides = [{"editor": "nano"}]
|
||||||
config = apply_overrides(overrides, config)
|
config = apply_overrides(overrides, config)
|
||||||
assert config["editor"] == "nano"
|
assert config["editor"] == "nano"
|
||||||
|
|
||||||
|
|
||||||
def test_override_dot_notation(minimal_config):
|
def test_override_dot_notation(minimal_config):
|
||||||
cfg = minimal_config.copy()
|
cfg = minimal_config.copy()
|
||||||
overrides = {"colors.body": "blue"}
|
overrides = [{"colors.body": "blue"}]
|
||||||
cfg = apply_overrides(overrides=overrides, base_config=cfg)
|
cfg = apply_overrides(overrides=overrides, base_config=cfg)
|
||||||
assert cfg["colors"] == {"body": "blue", "date": "green"}
|
assert cfg["colors"] == {"body": "blue", "date": "green"}
|
||||||
|
|
||||||
|
|
||||||
def test_multiple_overrides(minimal_config):
|
def test_multiple_overrides(minimal_config):
|
||||||
overrides = {
|
overrides = [
|
||||||
"colors.title": "magenta",
|
{"colors.title": "magenta"},
|
||||||
"editor": "nano",
|
{"editor": "nano"},
|
||||||
"journals.burner": "/tmp/journals/burner.jrnl",
|
{"journals.burner": "/tmp/journals/burner.jrnl"},
|
||||||
} # as returned by parse_args, saved in parser.config_override
|
] # as returned by parse_args, saved in parser.config_override
|
||||||
|
|
||||||
cfg = apply_overrides(overrides, minimal_config.copy())
|
cfg = apply_overrides(overrides, minimal_config.copy())
|
||||||
assert cfg["editor"] == "nano"
|
assert cfg["editor"] == "nano"
|
||||||
|
|
|
@ -36,7 +36,7 @@ def expected_args(**kwargs):
|
||||||
"strict": False,
|
"strict": False,
|
||||||
"tags": False,
|
"tags": False,
|
||||||
"text": [],
|
"text": [],
|
||||||
"config_override": None,
|
"config_override": [],
|
||||||
}
|
}
|
||||||
return {**default_args, **kwargs}
|
return {**default_args, **kwargs}
|
||||||
|
|
||||||
|
@ -209,26 +209,26 @@ def test_version_alone():
|
||||||
|
|
||||||
def test_editor_override():
|
def test_editor_override():
|
||||||
|
|
||||||
parsed_args = cli_as_dict('--config-override editor:"nano"')
|
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():
|
def test_color_override():
|
||||||
assert cli_as_dict("--config-override colors.body:blue") == expected_args(
|
assert cli_as_dict("--config-override colors.body blue") == expected_args(
|
||||||
config_override={"colors.body": "blue"}
|
config_override=[{"colors.body": "blue"}]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_multiple_overrides():
|
def test_multiple_overrides():
|
||||||
parsed_args = cli_as_dict(
|
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(
|
assert parsed_args == expected_args(
|
||||||
config_override={
|
config_override=[
|
||||||
"colors.title": "green",
|
{"colors.title": "green"},
|
||||||
"journal.scratchpad": "/tmp/scratchpad",
|
{"editor": "nano"},
|
||||||
"editor": "nano",
|
{"journal.scratchpad": "/tmp/scratchpad"},
|
||||||
}
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -266,49 +266,27 @@ class TestDeserialization:
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"input_str",
|
"input_str",
|
||||||
[
|
[
|
||||||
'editor:"nano", colors.title:blue, default:"/tmp/egg.txt"',
|
["editor", '"nano"'],
|
||||||
'editor:"vi -c startinsert", colors.title:blue, default:"/tmp/egg.txt"',
|
["colors.title", "blue"],
|
||||||
'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"',
|
["default", "/tmp/egg.txt"],
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_deserialize_multiword_strings(self, input_str):
|
def test_deserialize_multiword_strings(self, input_str):
|
||||||
|
|
||||||
runtime_config = deserialize_config_args(input_str)
|
runtime_config = deserialize_config_args(input_str)
|
||||||
assert runtime_config.__class__ == dict
|
assert runtime_config.__class__ == dict
|
||||||
assert "editor" in runtime_config.keys()
|
assert input_str[0] in runtime_config.keys()
|
||||||
assert "colors.title" in runtime_config.keys()
|
assert runtime_config[input_str[0]] == input_str[1]
|
||||||
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):
|
def test_deserialize_multiple_datatypes(self):
|
||||||
input = (
|
cfg = deserialize_config_args(["linewrap", "23"])
|
||||||
'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["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"'
|
assert cfg["editor"] == '"vi -c startinsert"'
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
cfg = deserialize_config_args(["highlight", "true"])
|
||||||
"delimiter",
|
assert cfg["highlight"] == True
|
||||||
[
|
|
||||||
".",
|
|
||||||
":",
|
|
||||||
", ", # 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"]
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue