diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/README.md b/README.md index 91da9a7..6905456 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,4 @@ python -m pytest test_task.py ## Configuration Copy `config.yaml.example` to `~/.config/task-cli/config.yaml` and customize. +If the config file is missing, a sensible default is created automatically on first run. diff --git a/task.py b/task.py index 53cc8ed..b357841 100644 --- a/task.py +++ b/task.py @@ -11,9 +11,30 @@ 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 + """Load configuration from file. + + Returns the config contents as a string, or a sensible default config + if the file does not exist yet. A default config file is also created + on disk so future runs pick it up automatically. + """ + config_dir = Path.home() / ".config" / "task-cli" + config_path = config_dir / "config.yaml" + + if not config_path.exists(): + # Create a sensible default config + default_config = ( + "# Task CLI configuration\n" + "storage:\n" + " format: json\n" + " max_tasks: 1000\n" + "display:\n" + " color: true\n" + " unicode: true\n" + ) + config_dir.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..6f3e115 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,40 @@ def test_validate_task_id(): with pytest.raises(ValueError): validate_task_id(tasks, 99) + + +def test_load_config_creates_default_when_missing(tmp_path, monkeypatch): + """Test that load_config() creates a default config when the file is missing.""" + fake_home = tmp_path / "home" + fake_home.mkdir() + monkeypatch.setattr(Path, "home", staticmethod(lambda: fake_home)) + + config_dir = fake_home / ".config" / "task-cli" + config_path = config_dir / "config.yaml" + + # Ensure config does not exist + assert not config_path.exists() + + # load_config should NOT crash and should return default content + result = load_config() + assert result is not None + assert "storage:" in result + assert "display:" in result + + # It should have created the file on disk + assert config_path.exists() + assert config_path.read_text() == result + + +def test_load_config_reads_existing_file(tmp_path, monkeypatch): + """Test that load_config() reads an existing config file.""" + fake_home = tmp_path / "home" + config_dir = fake_home / ".config" / "task-cli" + config_dir.mkdir(parents=True) + config_path = config_dir / "config.yaml" + config_path.write_text("custom: value\n") + + monkeypatch.setattr(Path, "home", staticmethod(lambda: fake_home)) + + result = load_config() + assert "custom: value" in result