From 36bd1339aa187efdbfd137f5572d7079cba48a90 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 15 Apr 2026 07:56:50 +0800 Subject: [PATCH] Fix: Handle missing config file gracefully Previously, load_config() would crash with FileNotFoundError when ~/.config/task-cli/config.yaml didn't exist. Now it: - Creates the config directory if missing - Writes a sensible default config file - Returns default config values Added test_load_config_missing_file to verify the fix. Fixes #2 --- .gitignore | 3 +++ task.py | 18 ++++++++++++++++-- test_task.py | 27 +++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..75c6182 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +__pycache__/ +*.pyc +.pytest_cache/ diff --git a/task.py b/task.py index 53cc8ed..e566f1e 100644 --- a/task.py +++ b/task.py @@ -10,10 +10,24 @@ from commands.done import mark_done +DEFAULT_CONFIG = """# Task CLI configuration +storage: + format: json + max_tasks: 1000 + +display: + color: true + unicode: true +""" + + def load_config(): - """Load configuration from file.""" + """Load configuration from file, falling back to defaults if missing.""" config_path = Path.home() / ".config" / "task-cli" / "config.yaml" - # NOTE: This will crash if config doesn't exist - known bug for bounty testing + if not config_path.exists(): + config_path.parent.mkdir(parents=True, exist_ok=True) + config_path.write_text(DEFAULT_CONFIG) + return DEFAULT_CONFIG with open(config_path) as f: return f.read() diff --git a/test_task.py b/test_task.py index ba98e43..22e075e 100644 --- a/test_task.py +++ b/test_task.py @@ -1,10 +1,13 @@ """Basic tests for task CLI.""" import json +import os +import shutil import pytest from pathlib import Path from commands.add import add_task, validate_description from commands.done import validate_task_id +from task import load_config def test_validate_description(): @@ -28,3 +31,27 @@ def test_validate_task_id(): with pytest.raises(ValueError): validate_task_id(tasks, 99) + + +def test_load_config_missing_file(tmp_path, monkeypatch): + """Test that load_config handles missing config file gracefully.""" + # Redirect HOME to a temp directory + monkeypatch.setattr(Path, "home", lambda: tmp_path) + + # Ensure config doesn't exist + config_dir = tmp_path / ".config" / "task-cli" + if config_dir.exists(): + shutil.rmtree(config_dir) + + # Should not crash, should create default config + config_content = load_config() + assert "storage:" in config_content + assert "display:" in config_content + + # Config file should now exist + config_path = config_dir / "config.yaml" + assert config_path.exists() + + # Loading again should return the same content + config_content2 = load_config() + assert config_content2 == config_content