Coverage for repo_ctx / providers / factory.py: 70%
46 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-25 17:42 +0100
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-25 17:42 +0100
1"""Factory for creating provider instances."""
2from typing import Optional, Dict
3from .base import GitProvider
4from .exceptions import ProviderConfigError
7class ProviderFactory:
8 """Factory for creating provider instances."""
10 # Registry of provider classes
11 _providers: Dict[str, type] = {}
13 @classmethod
14 def register(cls, name: str, provider_class: type):
15 """
16 Register a provider class.
18 Args:
19 name: Provider name (gitlab, github, local, etc.)
20 provider_class: Provider class implementing GitProvider
21 """
22 cls._providers[name] = provider_class
24 @classmethod
25 def create(
26 cls,
27 provider_type: str,
28 **kwargs
29 ) -> GitProvider:
30 """
31 Create provider instance.
33 Args:
34 provider_type: Provider type (gitlab, github, local, etc.)
35 **kwargs: Provider-specific configuration
37 Returns:
38 Provider instance
40 Raises:
41 ProviderConfigError: Provider type not registered or invalid config
43 Examples:
44 factory.create("gitlab", url="...", token="...")
45 factory.create("github", url="...", token="...")
46 factory.create("local")
47 """
48 if provider_type not in cls._providers:
49 available = ", ".join(cls._providers.keys())
50 raise ProviderConfigError(
51 f"Unknown provider type: {provider_type}. "
52 f"Available providers: {available}"
53 )
55 provider_class = cls._providers[provider_type]
57 try:
58 return provider_class(**kwargs)
59 except TypeError as e:
60 raise ProviderConfigError(
61 f"Invalid configuration for provider {provider_type}: {e}"
62 )
64 @classmethod
65 def create_gitlab(cls, url: str, token: str) -> GitProvider:
66 """
67 Create GitLab provider instance.
69 Args:
70 url: GitLab instance URL
71 token: Personal access token
73 Returns:
74 GitLab provider instance
75 """
76 return cls.create("gitlab", url=url, token=token)
78 @classmethod
79 def create_github(
80 cls,
81 url: str = "https://api.github.com",
82 token: Optional[str] = None
83 ) -> GitProvider:
84 """
85 Create GitHub provider instance.
87 Args:
88 url: GitHub API URL (default: public GitHub)
89 token: Personal access token (optional for public repos)
91 Returns:
92 GitHub provider instance
93 """
94 return cls.create("github", url=url, token=token)
96 @classmethod
97 def create_local(cls) -> GitProvider:
98 """
99 Create local Git provider instance.
101 Returns:
102 Local provider instance
103 """
104 return cls.create("local")
106 @classmethod
107 def from_config(cls, config, provider_type: str) -> GitProvider:
108 """
109 Create provider from configuration object.
111 Args:
112 config: Config object with provider settings
113 provider_type: Provider type to create
115 Returns:
116 Provider instance
118 Raises:
119 ProviderConfigError: Invalid provider type or missing config
121 Note:
122 Config object should have providers attribute with
123 gitlab, github, local sub-objects containing url/token
124 """
125 if provider_type == "gitlab":
126 if not hasattr(config, 'gitlab_url') or not hasattr(config, 'gitlab_token'):
127 raise ProviderConfigError(
128 "GitLab provider requires gitlab_url and gitlab_token in config"
129 )
130 return cls.create_gitlab(
131 url=config.gitlab_url,
132 token=config.gitlab_token
133 )
135 elif provider_type == "github":
136 # GitHub token is optional for public repos
137 url = getattr(config, 'github_url', "https://api.github.com")
138 token = getattr(config, 'github_token', None)
139 return cls.create_github(url=url, token=token)
141 elif provider_type == "local":
142 return cls.create_local()
144 else:
145 raise ProviderConfigError(f"Unknown provider type: {provider_type}")
147 @classmethod
148 def list_providers(cls) -> list[str]:
149 """
150 List all registered provider types.
152 Returns:
153 List of provider names
154 """
155 return list(cls._providers.keys())
157 @classmethod
158 def is_registered(cls, provider_type: str) -> bool:
159 """
160 Check if provider type is registered.
162 Args:
163 provider_type: Provider type to check
165 Returns:
166 True if registered, False otherwise
167 """
168 return provider_type in cls._providers