diff --git a/redmine_reporter/cli.py b/redmine_reporter/cli.py index 6300fcc..1ed712b 100644 --- a/redmine_reporter/cli.py +++ b/redmine_reporter/cli.py @@ -8,6 +8,7 @@ from pathlib import Path from typing import List, Optional import yaml +from dotenv import find_dotenv, load_dotenv from . import __version__ from .client import RedmineAPIError, fetch_issues_with_spent_time @@ -70,7 +71,16 @@ def parse_date_range(date_arg: str) -> tuple[str, str]: def _run_init_config(config_path: str, force: bool) -> int: - """Создаёт YAML-конфиг из текущих настроек окружения.""" + """Создаёт YAML-конфиг из текущих настроек окружения. + + Подгружает .env из текущей директории (override=False: реальные + переменные окружения не перебиваются), чтобы --init-config видел + значения, заданные только в .env (#64). Поиск идёт от cwd + (usecwd=True): find_dotenv() без него стартует от директории + cli.py и .env пользователя не находит. + """ + load_dotenv(find_dotenv(usecwd=True), override=False) + path = Path(config_path) if path.exists() and not force: diff --git a/tests/test_cli.py b/tests/test_cli.py index e2fdb2d..e362ec2 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -425,6 +425,49 @@ class TestInitConfig: assert data["redmine"]["url"] == "" assert data["redmine"]["api_key"] == "" + def test_init_config_reads_dotenv_file(self, tmp_path, monkeypatch): + """#64: --init-config подхватывает значения из реального .env в cwd. + + Регрессионный тест: после 1df1194 load_dotenv перестал выполняться + до _run_init_config, и пользователь с настройками только в .env + получал пустой YAML. + """ + import yaml + + (tmp_path / ".env").write_text( + "REDMINE_URL=https://redmine.example.com\n" + "REDMINE_API_KEY=secret-from-dotenv\n" + "REDMINE_AUTHOR=ivan.ivanov\n" + "DEFAULT_FROM_DATE=2026-01-01\n" + "DEFAULT_TO_DATE=2026-01-31\n" + "SMTP_PASSWORD=smtp-secret\n" + ) + monkeypatch.chdir(tmp_path) + # Целевые переменные не мокаются: значения должны прийти только из .env. + for var in ( + "REDMINE_URL", + "REDMINE_API_KEY", + "REDMINE_AUTHOR", + "DEFAULT_FROM_DATE", + "DEFAULT_TO_DATE", + "SMTP_PASSWORD", + ): + monkeypatch.delenv(var, raising=False) + + config_path = tmp_path / "config.yml" + code = main(["--init-config", "--config-path", str(config_path)]) + assert code == 0 + + with open(config_path) as fh: + data = yaml.safe_load(fh) + + assert data["redmine"]["url"] == "https://redmine.example.com" + assert data["redmine"]["api_key"] == "${REDMINE_API_KEY}" + assert data["redmine"]["author"] == "ivan.ivanov" + assert data["period"]["default_from"] == "2026-01-01" + assert data["period"]["default_to"] == "2026-01-31" + assert data["email"]["smtp"]["password"] == "${SMTP_PASSWORD}" + @mock.patch.dict(os.environ, VALID_ENV, clear=True) def test_init_config_includes_report_section(self, tmp_path): """--init-config генерирует секцию report с no_time: false."""