|
3 | 3 | """ |
4 | 4 |
|
5 | 5 | import configparser |
| 6 | +import os |
6 | 7 | from pathlib import Path |
7 | 8 | from typing import Optional |
8 | 9 | import webcolors |
9 | 10 |
|
| 11 | +from .providers import ProviderConfig, PROVIDER_ENV_VARS, PROVIDER_DEFAULT_URLS |
| 12 | + |
10 | 13 | class ConfigManager: |
11 | 14 | """Manages gitfetch configuration.""" |
12 | 15 |
|
@@ -276,6 +279,69 @@ def set_token(self, token: str) -> None: |
276 | 279 | self.config['DEFAULT'] = {} |
277 | 280 | self.config['DEFAULT']['token'] = token |
278 | 281 |
|
| 282 | + def get_provider_config(self) -> Optional[ProviderConfig]: |
| 283 | + """ |
| 284 | + Get complete provider configuration with token resolution. |
| 285 | +
|
| 286 | + Token resolution chain: |
| 287 | + 1. Read from provider section |
| 288 | + 2. Fall back to environment variable |
| 289 | +
|
| 290 | + Returns: |
| 291 | + ProviderConfig with resolved token, or None if no provider set |
| 292 | + """ |
| 293 | + provider_name = self.get_provider() |
| 294 | + if not provider_name: |
| 295 | + return None |
| 296 | + |
| 297 | + section = provider_name # e.g., "github" |
| 298 | + |
| 299 | + # Try provider section first, fall back to DEFAULT for backward compat |
| 300 | + if self.config.has_section(section): |
| 301 | + username = self.config.get(section, 'username', fallback='') |
| 302 | + url = self.config.get(section, 'url', fallback='') |
| 303 | + token = self.config.get(section, 'token', fallback='') |
| 304 | + else: |
| 305 | + # Backward compatibility: read from DEFAULT |
| 306 | + username = self.get_default_username() or '' |
| 307 | + url = self.get_provider_url() or '' |
| 308 | + token = self.get_token() or '' |
| 309 | + |
| 310 | + # Token resolution: config -> env var |
| 311 | + if not token: |
| 312 | + env_var = PROVIDER_ENV_VARS.get(provider_name, '') |
| 313 | + if env_var: |
| 314 | + token = os.getenv(env_var, '') or '' |
| 315 | + |
| 316 | + # Use default URL if not specified |
| 317 | + if not url: |
| 318 | + url = PROVIDER_DEFAULT_URLS.get(provider_name, '') |
| 319 | + |
| 320 | + return ProviderConfig( |
| 321 | + name=provider_name, |
| 322 | + username=username, |
| 323 | + url=url, |
| 324 | + token=token |
| 325 | + ) |
| 326 | + |
| 327 | + def set_provider_config(self, config: ProviderConfig) -> None: |
| 328 | + """ |
| 329 | + Save provider configuration to its dedicated section. |
| 330 | +
|
| 331 | + Args: |
| 332 | + config: ProviderConfig to save |
| 333 | + """ |
| 334 | + section = config.name |
| 335 | + if not self.config.has_section(section): |
| 336 | + self.config.add_section(section) |
| 337 | + |
| 338 | + self.config.set(section, 'username', config.username) |
| 339 | + self.config.set(section, 'url', config.url) |
| 340 | + self.config.set(section, 'token', config.token) |
| 341 | + |
| 342 | + # Also set provider in DEFAULT |
| 343 | + self.set_provider(config.name) |
| 344 | + |
279 | 345 | def save(self) -> None: |
280 | 346 | """Save configuration to file.""" |
281 | 347 | import os |
@@ -318,6 +384,17 @@ def save(self) -> None: |
318 | 384 |
|
319 | 385 | f.write("\n") |
320 | 386 |
|
| 387 | + # Write provider sections |
| 388 | + known_providers = ['github', 'gitlab', 'gitea', 'sourcehut'] |
| 389 | + for provider_section in known_providers: |
| 390 | + if self.config.has_section(provider_section): |
| 391 | + f.write(f"[{provider_section}]\n") |
| 392 | + for key in ['username', 'url', 'token']: |
| 393 | + value = self.config.get(provider_section, key, |
| 394 | + fallback='') |
| 395 | + f.write(f"{key} = {value}\n") |
| 396 | + f.write("\n") |
| 397 | + |
321 | 398 | if 'COLORS' in self.config._sections: |
322 | 399 | f.write("[COLORS]\n") |
323 | 400 | # Find the longest key for alignment |
|
0 commit comments