Skip to content

Commit

Permalink
Merge pull request #53 from coddingtonbear/handle_config_overrides
Browse files Browse the repository at this point in the history
Merge configuration overrides into taskrc configuration.
  • Loading branch information
coddingtonbear committed Apr 14, 2014
2 parents e0d6415 + 7278ce3 commit 3c8adfe
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 14 deletions.
5 changes: 3 additions & 2 deletions taskw/taskrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class TaskRc(dict):
'string': StringField,
}

def __init__(self, path=None):
def __init__(self, path=None, overrides=None):
self.overrides = overrides if overrides else {}
if path:
self.path = os.path.normpath(
os.path.expanduser(
Expand Down Expand Up @@ -98,7 +99,7 @@ def _read(self, path):
self.path,
)

return config
return self._merge_trees(config, self.overrides)

def __delitem__(self, *args):
raise TypeError('TaskRc objects are immutable')
Expand Down
47 changes: 47 additions & 0 deletions taskw/test/test_taskrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,50 @@ def test_get_udas(self):
actual_udas = self.taskrc.get_udas()

self.assertEqual(actual_udas, expected_udas)

def test_config_overrides(self):
overrides = {
'uda': {
'd': {
'type': 'string',
'label': 'Delta',
}
},
'alpha': {
'two': '3',
}
}

taskrc = TaskRc(self.path_to_taskrc, overrides=overrides)

expected_config = {
'data': {
'location': '~/.task'
},
'alpha': {
'one': 'yes',
'two': '3',
},
'beta': {
'one': 'FALSE',
},
'gamma': {
'one': 'TRUE',
},
'uda': {
'a': {
'type': 'numeric',
'label': 'Alpha',
},
'b': {
'type': 'string',
'label': 'Beta',
},
'd': {
'type': 'string',
'label': 'Delta',
}
}
}

self.assertEqual(taskrc, expected_config)
28 changes: 27 additions & 1 deletion taskw/test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
import six

from taskw.utils import (
decode_task, encode_task, encode_task_experimental, DATE_FORMAT
convert_dict_to_override_args,
decode_task,
encode_task,
encode_task_experimental,
DATE_FORMAT
)

TASK = {'description': "task 2 http://www.google.com/",
Expand Down Expand Up @@ -162,3 +166,25 @@ def test_encodes_zoned_datetimes(self):
actual_encoded_task,
expected_encoded_task,
)

def test_convert_dict_to_override_args(self):
overrides = {
'one': {
'two': 1,
'three': {
'alpha': 'a'
},
'four': 'lorem ipsum',
},
'two': {
}
}

expected_overrides = [
'rc.one.two=1',
'rc.one.three.alpha=a',
'rc.one.four="lorem ipsum"',
]
actual_overrides = convert_dict_to_override_args(overrides)

eq_(set(actual_overrides), set(expected_overrides))
31 changes: 31 additions & 0 deletions taskw/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,34 @@ def annotation_list_to_comparison_map(annotations):
comparable = make_annotation_comparable(annotation)
mapping[comparable] = annotation
return mapping


def convert_dict_to_override_args(config, prefix=''):
""" Converts a dictionary of override arguments into CLI arguments.
* Converts leaf nodes into dot paths of key names leading to the leaf
node.
* Does not include paths to leaf nodes not being non-dictionary type.
See `taskw.test.test_utils.TestUtils.test_convert_dict_to_override_args`
for details.
"""
args = []
for k, v in six.iteritems(config):
if isinstance(v, dict):
args.extend(
convert_dict_to_override_args(
v,
prefix='.'.join([
prefix,
k,
]) if prefix else k
)
)
else:
v = six.text_type(v)
left = 'rc' + (('.' + prefix) if prefix else '') + '.' + k
right = v if ' ' not in v else '"%s"' % v
args.append('='.join([left, right]))
return args
16 changes: 5 additions & 11 deletions taskw/warrior.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,9 @@ class TaskWarriorShellout(TaskWarriorBase):
and /~https://github.com/ralphbean/taskw/issues/30 for more.
"""
DEFAULT_CONFIG_OVERRIDES = {
'json.array': 'TRUE',
'json': {
'array': 'TRUE'
},
'verbose': 'nothing',
'confirmation': 'no',
}
Expand All @@ -440,7 +442,7 @@ def __init__(
self.config_overrides = config_overrides if config_overrides else {}
self._marshal = marshal
try:
self.config = TaskRc(config_filename)
self.config = TaskRc(config_filename, overrides=config_overrides)
except:
logger.exception(
"Error encountered while loading configuration file "
Expand All @@ -449,17 +451,9 @@ def __init__(
)

def get_configuration_override_args(self):
args = []
config_overrides = self.DEFAULT_CONFIG_OVERRIDES.copy()
config_overrides.update(self.config_overrides)
for key, value in six.iteritems(config_overrides):
args.append(
'rc.%s=%s' % (
key,
value if ' ' not in value else '"%s"' % value
)
)
return args
return taskw.utils.convert_dict_to_override_args(config_overrides)

def _execute(self, *args):
""" Execute a given taskwarrior command with arguments
Expand Down

0 comments on commit 3c8adfe

Please sign in to comment.