Skip to content

Commit

Permalink
Merge pull request #3 from minddistrict/prefer-exact-match
Browse files Browse the repository at this point in the history
Prefer exact matches in case of multiple ones.
  • Loading branch information
icemac authored Dec 5, 2023
2 parents f4c3cfe + c47cd54 commit 193530d
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 10 deletions.
7 changes: 7 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Change log
==========

0.2 (unreleased)
----------------

- Prefer exact matches in case of multiple ones.
33 changes: 23 additions & 10 deletions gtimelog2tick.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,21 +202,27 @@ def parse_entry_message(
config: dict,
message: str
) -> tuple[str, str, int]:
"""Parse entry message into task, text and task_id."""
"""Parse entry message into "project: task", text and task_id."""
project_name, task_name, *text_parts = message.split(':')
task_name = task_name.strip()

tick_projects = [
x
(x, x.name == project_name)
for x in config['tick_projects']
if x.name.startswith(project_name)]

if not tick_projects:
raise DataError(f'Cannot find a Tick project matching {message}.')
if len(tick_projects) > 1:
raise DataError(f'Found multiple Tick projects matching {message}: '
f'{", ".join(x.name for x in tick_projects)}.')
tick_project = tick_projects[0]
exact_match = [x for x, match in tick_projects if match]
if not exact_match:
raise DataError(
f'Found multiple Tick projects matching {message!r}, but no'
' exact match.'
f' ({", ".join(x[0].name for x in tick_projects)})')
tick_project = exact_match[0]
else:
tick_project = tick_projects[0][0]
if tick_project.tasks is None:
raw_tasks = call(
config, 'get', f'/projects/{tick_project.id}/tasks.json')
Expand All @@ -230,13 +236,20 @@ def parse_entry_message(
if not possible_tasks:
raise DataError(f'Cannot find a Tick task matching {message}.')
if len(possible_tasks) > 1:
raise DataError(f'Found multiple Tick tasks matching {message}: '
f'{", ".join(x.name for x in tick_project.tasks)}.')
exact_match = [
task for task in possible_tasks if task.name == task_name]
if not exact_match:
raise DataError(
f'Found multiple Tick tasks matching {message!r}, but no'
' exact match.'
f' ({", ".join(x[0].name for x in tick_projects)})')
task = exact_match[0]
else:
task = possible_tasks[0]

task_id = possible_tasks[0].id
task_name = f'{tick_project.name}: {possible_tasks[0].name}'
task_name = f'{tick_project.name}: {task.name}'

return task_name, ':'.join(text_parts).strip(), task_id
return task_name, ':'.join(text_parts).strip(), task.id


def parse_timelog(
Expand Down
35 changes: 35 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,3 +505,38 @@ def test_dry_run(env):
'project1-other: support: 1.08 h in 1 entries.',
'project2: development: 9.17 h in 1 entries.',
]


def test_gtimelog2tick__parse_entry_message__1(env):
"""In case of multiple project matches it prefers the exact one."""
config = {
'tick_projects': [
gtimelog2tick.Project('proj2', 42, [
gtimelog2tick.Task('dev', 1),
]),
gtimelog2tick.Project('proj2 - maintenance', 43, [])
]
}
task, text, task_id = gtimelog2tick.parse_entry_message(
config, 'proj2: dev: work')
assert task == 'proj2: dev'
assert text == 'work'
assert task_id == 1


def test_gtimelog2tick__parse_entry_message__2(env):
"""In case of multiple task matches it prefers the exact one."""
config = {
'tick_projects': [
gtimelog2tick.Project('proj2', 42, [
gtimelog2tick.Task('dev', 1),
gtimelog2tick.Task('dev - 2', 1),
gtimelog2tick.Task('dev - 23', 1),
]),
]
}
task, text, task_id = gtimelog2tick.parse_entry_message(
config, 'proj2: dev: work')
assert task == 'proj2: dev'
assert text == 'work'
assert task_id == 1

0 comments on commit 193530d

Please sign in to comment.