|
| 1 | +from functools import cache |
| 2 | +from importlib.metadata import entry_points |
1 | 3 | import logging |
2 | 4 | import os |
3 | 5 | from pathlib import Path |
4 | 6 | import re |
5 | 7 | import typing |
6 | | -from typing import Annotated, Any, Literal |
| 8 | +from typing import TYPE_CHECKING, Annotated, Any, Literal |
7 | 9 |
|
8 | 10 | import pydantic |
9 | 11 | from pydantic import ( |
|
23 | 25 |
|
24 | 26 | from .data import BugwarriorData, get_data_path |
25 | 27 |
|
| 28 | +if TYPE_CHECKING: |
| 29 | + from bugwarrior.services import Service |
| 30 | + |
26 | 31 | log = logging.getLogger(__name__) |
27 | 32 |
|
28 | 33 | Priority = Literal['', 'L', 'M', 'H'] |
@@ -215,8 +220,6 @@ class ServiceConfig(_ServiceConfig): |
215 | 220 |
|
216 | 221 | @property |
217 | 222 | def keyring_service(self) -> str: |
218 | | - # FIXME change this import and move it outside method after rebase |
219 | | - from bugwarrior.collect import get_service |
220 | 223 |
|
221 | 224 | service = get_service(self.service) |
222 | 225 | if service.API_VERSION < 2: |
@@ -291,3 +294,23 @@ def deprecate_project_name(cls, value: str) -> str: |
291 | 294 | if value != '': |
292 | 295 | log.warning('project_name is deprecated in favor of project_template') |
293 | 296 | return value |
| 297 | + |
| 298 | + |
| 299 | +@cache |
| 300 | +def get_service(service_name: str) -> type["Service"]: |
| 301 | + try: |
| 302 | + (service,) = entry_points(group='bugwarrior.service', name=service_name) |
| 303 | + except ValueError as e: |
| 304 | + if service_name in [ |
| 305 | + 'activecollab', |
| 306 | + 'activecollab2', |
| 307 | + 'megaplan', |
| 308 | + 'teamlab', |
| 309 | + 'versionone', |
| 310 | + ]: |
| 311 | + log.warning(f"The {service_name} service has been removed.") |
| 312 | + raise ValueError( |
| 313 | + f"Configured service '{service_name}' not found. " |
| 314 | + "Is it installed? Or misspelled?" |
| 315 | + ) from e |
| 316 | + return service.load() |
0 commit comments