Clean up validation and add interactive cmd 'r' to edit recur

This commit is contained in:
Matt Snider 2019-07-13 11:34:03 +02:00
parent 03be344f5e
commit 8180893f08
4 changed files with 47 additions and 27 deletions

View File

@ -4,7 +4,7 @@ Test argument/option validations
""" """
import click import click
import pytest import pytest
from todoist_taskwarrior import utils from todoist_taskwarrior import validation
def validate(fn, value): def validate(fn, value):
@ -19,18 +19,18 @@ def validate(fn, value):
def test_validate_map(): def test_validate_map():
# Simple # Simple
assert validate(utils.validate_map, ('HELLO=WORLD',)) == {'HELLO': 'WORLD'} assert validate(validation.validate_map, ('HELLO=WORLD',)) == {'HELLO': 'WORLD'}
# Missing DST # Missing DST
assert validate(utils.validate_map, ('HELLO=',)) == {'HELLO': None} assert validate(validation.validate_map, ('HELLO=',)) == {'HELLO': None}
# Multiple # Multiple
assert validate(utils.validate_map, ('FOO=BAR', 'BAR=BAZZ')) == {'FOO': 'BAR', 'BAR': 'BAZZ'} assert validate(validation.validate_map, ('FOO=BAR', 'BAR=BAZZ')) == {'FOO': 'BAR', 'BAR': 'BAZZ'}
# Invalid, no '=' # Invalid, no '='
with pytest.raises(click.BadParameter): with pytest.raises(click.BadParameter):
assert validate(utils.validate_map, ('FOO',)) == None assert validate(validation.validate_map, ('FOO',)) == None
# Hierarchical src # Hierarchical src
assert validate(utils.validate_map, ('foo.bar=bazz',)) == {'foo.bar': 'bazz'} assert validate(validation.validate_map, ('foo.bar=bazz',)) == {'foo.bar': 'bazz'}
assert validate(utils.validate_map, ('foo bar.bazz=bazz',)) == {'foo bar.bazz': 'bazz'} assert validate(validation.validate_map, ('foo bar.bazz=bazz',)) == {'foo bar.bazz': 'bazz'}

View File

@ -4,7 +4,7 @@ import sys
from taskw import TaskWarrior from taskw import TaskWarrior
from todoist.api import TodoistAPI from todoist.api import TodoistAPI
from . import utils, io from . import errors, io, utils, validation
# This is the location where the todoist # This is the location where the todoist
@ -68,11 +68,11 @@ def clean():
@click.option('--sync/--no-sync', default=True, @click.option('--sync/--no-sync', default=True,
help='Enable/disable Todoist synchronization of the local task cache.') help='Enable/disable Todoist synchronization of the local task cache.')
@click.option('-p', '--map-project', metavar='SRC=DST', multiple=True, @click.option('-p', '--map-project', metavar='SRC=DST', multiple=True,
callback=utils.validate_map, callback=validation.validate_map,
help='Project names specified will be translated from SRC to DST. ' help='Project names specified will be translated from SRC to DST. '
'If DST is omitted, the project will be unset when SRC matches.') 'If DST is omitted, the project will be unset when SRC matches.')
@click.option('-t', '--map-tag', metavar='SRC=DST', multiple=True, @click.option('-t', '--map-tag', metavar='SRC=DST', multiple=True,
callback=utils.validate_map, callback=validation.validate_map,
help='Tags specified will be translated from SRC to DST. ' help='Tags specified will be translated from SRC to DST. '
'If DST is omitted, the tag will be removed when SRC matches.') 'If DST is omitted, the tag will be removed when SRC matches.')
@click.pass_context @click.pass_context
@ -182,9 +182,10 @@ def add_task_interactive(**task_data):
y - add task y - add task
n - skip task n - skip task
r - rename task d - change description
p - change priority p - change priority
t - change tags t - change tags
r - change recur
q - quit immediately q - quit immediately
? - print help ? - print help
""" """
@ -193,7 +194,7 @@ def add_task_interactive(**task_data):
'n': lambda: task_data, 'n': lambda: task_data,
# Rename # Rename
'r': lambda: { 'd': lambda: {
**task_data, **task_data,
'name': io.prompt( 'name': io.prompt(
'Set name', 'Set name',
@ -224,6 +225,17 @@ def add_task_interactive(**task_data):
), ),
}, },
# Edit recur
'r': lambda: {
**task_data,
'recur': io.prompt(
'Set recurrence (todoist style)',
default=task_data['recur'],
value_proc=validation.validate_recur,
),
},
# Quit # Quit
'q': lambda: exit(1), 'q': lambda: exit(1),

View File

@ -3,21 +3,6 @@ import re
from datetime import datetime from datetime import datetime
from .errors import UnsupportedRecurrence from .errors import UnsupportedRecurrence
""" Validation """
def validate_map(ctx, param, value):
map_project = {}
for mapping in value:
try:
src, dst = mapping.split('=', 2)
except ValueError:
raise click.BadParameter('--map-project needs to be of the form SRC=DST')
if dst == '':
dst = None
map_project[src] = dst
return map_project
""" Mappings """ """ Mappings """

View File

@ -0,0 +1,23 @@
import click
from . import errors, utils
def validate_map(ctx, param, value):
map_project = {}
for mapping in value:
try:
src, dst = mapping.split('=', 2)
except ValueError:
raise click.BadParameter('--map-project needs to be of the form SRC=DST')
if dst == '':
dst = None
map_project[src] = dst
return map_project
def validate_recur(value):
try:
return utils.parse_recur(value)
except errors.UnsupportedRecurrence as e:
raise click.BadParameter(e)