diff --git a/commands/__pycache__/__init__.cpython-311.pyc b/commands/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..4a7dcb9 Binary files /dev/null and b/commands/__pycache__/__init__.cpython-311.pyc differ diff --git a/commands/__pycache__/add.cpython-311.pyc b/commands/__pycache__/add.cpython-311.pyc new file mode 100644 index 0000000..8296fc8 Binary files /dev/null and b/commands/__pycache__/add.cpython-311.pyc differ diff --git a/commands/__pycache__/done.cpython-311.pyc b/commands/__pycache__/done.cpython-311.pyc new file mode 100644 index 0000000..51f3aca Binary files /dev/null and b/commands/__pycache__/done.cpython-311.pyc differ diff --git a/commands/__pycache__/list.cpython-311.pyc b/commands/__pycache__/list.cpython-311.pyc new file mode 100644 index 0000000..9d0533e Binary files /dev/null and b/commands/__pycache__/list.cpython-311.pyc differ diff --git a/commands/add.py b/commands/add.py index 1b1a943..dba12e4 100644 --- a/commands/add.py +++ b/commands/add.py @@ -1,22 +1,8 @@ """Add task command.""" import json -from pathlib import Path - - -def get_tasks_file(): - """Get path to tasks file.""" - return Path.home() / ".local" / "share" / "task-cli" / "tasks.json" - - -def validate_description(description): - """Validate task description.""" - # NOTE: Validation logic scattered here - should be in utils (refactor bounty) - if not description: - raise ValueError("Description cannot be empty") - if len(description) > 200: - raise ValueError("Description too long (max 200 chars)") - return description.strip() +from utils.paths import get_tasks_file +from utils.validation import validate_description def add_task(description): diff --git a/commands/done.py b/commands/done.py index c9dfd42..995f058 100644 --- a/commands/done.py +++ b/commands/done.py @@ -1,20 +1,8 @@ """Mark task done command.""" import json -from pathlib import Path - - -def get_tasks_file(): - """Get path to tasks file.""" - return Path.home() / ".local" / "share" / "task-cli" / "tasks.json" - - -def validate_task_id(tasks, task_id): - """Validate task ID exists.""" - # NOTE: Validation logic scattered here - should be in utils (refactor bounty) - if task_id < 1 or task_id > len(tasks): - raise ValueError(f"Invalid task ID: {task_id}") - return task_id +from utils.paths import get_tasks_file +from utils.validation import validate_task_id def mark_done(task_id): diff --git a/commands/list.py b/commands/list.py index 714315d..d7921ba 100644 --- a/commands/list.py +++ b/commands/list.py @@ -1,27 +1,14 @@ """List tasks command.""" import json -from pathlib import Path - - -def get_tasks_file(): - """Get path to tasks file.""" - return Path.home() / ".local" / "share" / "task-cli" / "tasks.json" - - -def validate_task_file(): - """Validate tasks file exists.""" - # NOTE: Validation logic scattered here - should be in utils (refactor bounty) - tasks_file = get_tasks_file() - if not tasks_file.exists(): - return [] - return tasks_file +from utils.paths import get_tasks_file +from utils.validation import validate_task_file def list_tasks(): """List all tasks.""" # NOTE: No --json flag support yet (feature bounty) - tasks_file = validate_task_file() + tasks_file = validate_task_file(get_tasks_file()) if not tasks_file: print("No tasks yet!") return diff --git a/test_task.py b/test_task.py index ba98e43..8a87dba 100644 --- a/test_task.py +++ b/test_task.py @@ -3,8 +3,8 @@ import json import pytest from pathlib import Path -from commands.add import add_task, validate_description -from commands.done import validate_task_id +from commands.add import add_task +from utils.validation import validate_description, validate_task_id def test_validate_description(): diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000..db3e327 --- /dev/null +++ b/utils/__init__.py @@ -0,0 +1 @@ +# utils package diff --git a/utils/__pycache__/__init__.cpython-311.pyc b/utils/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..8b8b2ac Binary files /dev/null and b/utils/__pycache__/__init__.cpython-311.pyc differ diff --git a/utils/__pycache__/paths.cpython-311.pyc b/utils/__pycache__/paths.cpython-311.pyc new file mode 100644 index 0000000..5bd3c62 Binary files /dev/null and b/utils/__pycache__/paths.cpython-311.pyc differ diff --git a/utils/__pycache__/validation.cpython-311.pyc b/utils/__pycache__/validation.cpython-311.pyc new file mode 100644 index 0000000..77acc1a Binary files /dev/null and b/utils/__pycache__/validation.cpython-311.pyc differ diff --git a/utils/paths.py b/utils/paths.py new file mode 100644 index 0000000..19a7497 --- /dev/null +++ b/utils/paths.py @@ -0,0 +1,8 @@ +"""Shared path helpers for task-cli.""" + +from pathlib import Path + + +def get_tasks_file() -> Path: + """Return the path to the tasks JSON file.""" + return Path.home() / ".local" / "share" / "task-cli" / "tasks.json" diff --git a/utils/validation.py b/utils/validation.py new file mode 100644 index 0000000..a89be55 --- /dev/null +++ b/utils/validation.py @@ -0,0 +1,37 @@ +"""Shared validation helpers for task-cli.""" + + +def validate_description(description: str) -> str: + """Validate and normalise a task description. + + Raises: + ValueError: if the description is empty or exceeds 200 characters. + """ + if not description: + raise ValueError("Description cannot be empty") + if len(description) > 200: + raise ValueError("Description too long (max 200 chars)") + return description.strip() + + +def validate_task_file(tasks_file): + """Check whether the tasks file exists. + + Returns: + The ``tasks_file`` path if it exists, otherwise an empty list so + callers can treat a falsy return as "no tasks yet". + """ + if not tasks_file.exists(): + return [] + return tasks_file + + +def validate_task_id(tasks, task_id: int) -> int: + """Validate that *task_id* refers to an existing task. + + Raises: + ValueError: if *task_id* is out of range. + """ + if task_id < 1 or task_id > len(tasks): + raise ValueError(f"Invalid task ID: {task_id}") + return task_id