Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 1 addition & 16 deletions commands/add.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,7 @@
"""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 import get_tasks_file, validate_description


def add_task(description):
Expand Down
15 changes: 1 addition & 14 deletions commands/done.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
"""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 import get_tasks_file, validate_task_id


def mark_done(task_id):
Expand Down
16 changes: 1 addition & 15 deletions commands/list.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
"""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 import get_tasks_file, validate_task_file


def list_tasks():
Expand Down
33 changes: 31 additions & 2 deletions task.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,39 @@
from commands.done import mark_done


DEFAULT_CONFIG = """# Default configuration for task CLI
# Auto-generated on first run

# Task storage settings
storage:
format: json
max_tasks: 1000

# Display settings
display:
color: true
unicode: true
"""


def ensure_config_exists():
"""Ensure config file exists, create default if missing."""
config_dir = Path.home() / ".config" / "task-cli"
config_path = config_dir / "config.yaml"

if not config_path.exists():
# Create config directory if it doesn't exist
config_dir.mkdir(parents=True, exist_ok=True)
# Create default config file
config_path.write_text(DEFAULT_CONFIG)
print(f"Created default config at {config_path}")

return config_path


def load_config():
"""Load configuration from file."""
config_path = Path.home() / ".config" / "task-cli" / "config.yaml"
# NOTE: This will crash if config doesn't exist - known bug for bounty testing
config_path = ensure_config_exists()
with open(config_path) as f:
return f.read()

Expand Down
15 changes: 15 additions & 0 deletions utils/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""Utility modules for task-cli."""

from .validation import (
validate_description,
validate_task_file,
validate_task_id,
)
from .paths import get_tasks_file

__all__ = [
"validate_description",
"validate_task_file",
"validate_task_id",
"get_tasks_file",
]
12 changes: 12 additions & 0 deletions utils/paths.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""Path utilities for task-cli."""

from pathlib import Path


def get_tasks_file():
"""Get path to tasks file.

Returns:
Path to the tasks.json file in user's local data directory.
"""
return Path.home() / ".local" / "share" / "task-cli" / "tasks.json"
52 changes: 52 additions & 0 deletions utils/validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Validation utilities for task-cli."""

from .paths import get_tasks_file


def validate_description(description):
"""Validate task description.

Args:
description: The task description to validate.

Returns:
Stripped description if valid.

Raises:
ValueError: If description is empty or too long.
"""
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():
"""Validate tasks file exists.

Returns:
Path to tasks file if exists, empty list otherwise.
"""
tasks_file = get_tasks_file()
if not tasks_file.exists():
return []
return tasks_file


def validate_task_id(tasks, task_id):
"""Validate task ID exists.

Args:
tasks: List of tasks.
task_id: Task ID to validate.

Returns:
Task ID if valid.

Raises:
ValueError: If task ID is invalid.
"""
if task_id < 1 or task_id > len(tasks):
raise ValueError(f"Invalid task ID: {task_id}")
return task_id