diff --git a/core/obsidian_sync.py b/core/obsidian_sync.py index 1f4d2b6..d536147 100644 --- a/core/obsidian_sync.py +++ b/core/obsidian_sync.py @@ -141,36 +141,39 @@ def sync_obsidian(conn: sqlite3.Connection, project_id: str) -> dict: vault_path = Path(vault_path_str) errors: list[str] = [] + # --- Создаём vault_path если не существует --- + try: + vault_path.mkdir(parents=True, exist_ok=True) + except Exception as e: + errors.append(f"Cannot create vault path {vault_path_str}: {e}") + return {"exported_decisions": 0, "tasks_updated": 0, "errors": errors, "vault_path": vault_path_str} + # --- Export decisions --- exported_count = 0 - if not vault_path.is_dir(): - errors.append(f"Vault path does not exist or is not a directory: {vault_path_str}") - else: - try: - decisions = models.get_decisions(conn, project_id) - created_files = export_decisions_to_md(project_id, decisions, vault_path) - exported_count = len(created_files) - except Exception as e: - errors.append(f"Export error: {e}") + try: + decisions = models.get_decisions(conn, project_id) + created_files = export_decisions_to_md(project_id, decisions, vault_path) + exported_count = len(created_files) + except Exception as e: + errors.append(f"Export error: {e}") # --- Import checkboxes --- tasks_updated = 0 - if vault_path.is_dir(): - try: - checkboxes = parse_task_checkboxes(vault_path, project_id) - for item in checkboxes: - if not item["done"]: - continue - task = models.get_task(conn, item["task_id"]) - if task is None: - continue - if task.get("project_id") != project_id: - continue - if task.get("status") != "done": - models.update_task(conn, item["task_id"], status="done") - tasks_updated += 1 - except Exception as e: - errors.append(f"Import error: {e}") + try: + checkboxes = parse_task_checkboxes(vault_path, project_id) + for item in checkboxes: + if not item["done"]: + continue + task = models.get_task(conn, item["task_id"]) + if task is None: + continue + if task.get("project_id") != project_id: + continue + if task.get("status") != "done": + models.update_task(conn, item["task_id"], status="done") + tasks_updated += 1 + except Exception as e: + errors.append(f"Import error: {e}") return { "exported_decisions": exported_count, diff --git a/tests/test_obsidian_sync.py b/tests/test_obsidian_sync.py index b0e3027..642a24f 100644 --- a/tests/test_obsidian_sync.py +++ b/tests/test_obsidian_sync.py @@ -227,19 +227,19 @@ def test_export_frontmatter_has_yaml_delimiters(tmp_vault): # --------------------------------------------------------------------------- -# 9. sync_obsidian — несуществующий vault_path → ошибка в errors, не исключение +# 9. sync_obsidian — несуществующий vault_path → директория создаётся автоматически # --------------------------------------------------------------------------- -def test_sync_nonexistent_vault_records_error(db, tmp_path): - """Если vault_path не существует, sync возвращает ошибку в errors без raise.""" +def test_sync_nonexistent_vault_creates_directory(db, tmp_path): + """Если vault_path не существует, sync автоматически создаёт директорию.""" nonexistent = tmp_path / "ghost_vault" models.update_project(db, "proj1", obsidian_vault_path=str(nonexistent)) result = sync_obsidian(db, "proj1") - assert len(result["errors"]) > 0 - assert "does not exist" in result["errors"][0].lower() or "not exist" in result["errors"][0].lower() - assert result["exported_decisions"] == 0 + assert result["errors"] == [] + assert nonexistent.is_dir() # директория автоматически создана + assert result["exported_decisions"] == 0 # нет decisions в DB assert result["tasks_updated"] == 0