|
4 | 4 |
|
5 | 5 | import argparse |
6 | 6 | import sys |
| 7 | +import os |
| 8 | +import subprocess |
7 | 9 | from typing import Optional |
8 | 10 |
|
9 | 11 | import readchar |
|
14 | 16 | from . import __version__ |
15 | 17 |
|
16 | 18 |
|
| 19 | +def _background_refresh_cache_subprocess(username: str) -> None: |
| 20 | + """ |
| 21 | + Background cache refresh function that runs as a standalone script. |
| 22 | + This is called by the subprocess, not directly. |
| 23 | + """ |
| 24 | + try: |
| 25 | + # Re-create components |
| 26 | + config_manager = ConfigManager() |
| 27 | + cache_expiry = config_manager.get_cache_expiry_minutes() |
| 28 | + cache_manager = CacheManager(cache_expiry_minutes=cache_expiry) |
| 29 | + provider = config_manager.get_provider() |
| 30 | + provider_url = config_manager.get_provider_url() |
| 31 | + token = config_manager.get_token() |
| 32 | + fetcher = _create_fetcher(provider, provider_url, token) |
| 33 | + |
| 34 | + fresh_user_data = fetcher.fetch_user_data(username) |
| 35 | + fresh_stats = fetcher.fetch_user_stats(username, fresh_user_data) |
| 36 | + cache_manager.cache_user_data(username, fresh_user_data, fresh_stats) |
| 37 | + except Exception: |
| 38 | + # Silent fail - this is background refresh |
| 39 | + pass |
| 40 | + |
| 41 | + |
17 | 42 | def parse_args() -> argparse.Namespace: |
18 | 43 | """Parse command-line arguments.""" |
19 | 44 | parser = argparse.ArgumentParser( |
@@ -53,6 +78,13 @@ def parse_args() -> argparse.Namespace: |
53 | 78 | help="Change the configured git provider" |
54 | 79 | ) |
55 | 80 |
|
| 81 | + # Hidden argument for background cache refresh |
| 82 | + general_group.add_argument( |
| 83 | + "--background-refresh", |
| 84 | + type=str, |
| 85 | + help=argparse.SUPPRESS # Hide from help |
| 86 | + ) |
| 87 | + |
56 | 88 | visual_group = parser.add_argument_group('\033[94mVisual Options\033[0m') |
57 | 89 | visual_group.add_argument( |
58 | 90 | "--spaced", |
@@ -146,6 +178,11 @@ def main() -> int: |
146 | 178 | try: |
147 | 179 | args = parse_args() |
148 | 180 |
|
| 181 | + # Handle background refresh mode (hidden feature) |
| 182 | + if args.background_refresh: |
| 183 | + _background_refresh_cache_subprocess(args.background_refresh) |
| 184 | + return 0 |
| 185 | + |
149 | 186 | if args.change_provider: |
150 | 187 | config_manager = ConfigManager() |
151 | 188 | print("🔄 Changing git provider...\n") |
@@ -252,27 +289,34 @@ def main() -> int: |
252 | 289 |
|
253 | 290 | # If fresh cache is available, just display |
254 | 291 | if user_data is not None and stats is not None: |
255 | | - formatter.display(username, user_data, stats, spaced=spaced) |
| 292 | + formatter.display(username, user_data, |
| 293 | + stats, spaced=spaced) |
256 | 294 | return 0 |
257 | 295 |
|
258 | 296 | # Try stale cache for immediate display |
259 | | - stale_user_data = cache_manager.get_stale_cached_user_data(username) |
| 297 | + stale_user_data = cache_manager.get_stale_cached_user_data( |
| 298 | + username) |
260 | 299 | stale_stats = cache_manager.get_stale_cached_stats(username) |
261 | 300 |
|
262 | 301 | if stale_user_data is not None and stale_stats is not None: |
263 | | - formatter.display(username, stale_user_data, stale_stats, spaced=spaced) |
264 | | - print("\n🔄 Refreshing data in background...", file=sys.stderr) |
265 | | - |
266 | | - import threading |
267 | | - def refresh_cache(): |
268 | | - try: |
269 | | - fresh_user_data = fetcher.fetch_user_data(username) |
270 | | - fresh_stats = fetcher.fetch_user_stats(username, fresh_user_data) |
271 | | - cache_manager.cache_user_data(username, fresh_user_data, fresh_stats) |
272 | | - except Exception: |
273 | | - pass |
274 | | - |
275 | | - threading.Thread(target=refresh_cache, daemon=True).start() |
| 302 | + formatter.display(username, stale_user_data, |
| 303 | + stale_stats, spaced=spaced) |
| 304 | + |
| 305 | + # Spawn a completely independent background process |
| 306 | + # Use the same Python interpreter and call gitfetch with hidden flag |
| 307 | + try: |
| 308 | + subprocess.Popen( |
| 309 | + [sys.executable, "-m", "gitfetch.cli", |
| 310 | + "--background-refresh", username], |
| 311 | + stdout=subprocess.DEVNULL, |
| 312 | + stderr=subprocess.DEVNULL, |
| 313 | + stdin=subprocess.DEVNULL, |
| 314 | + start_new_session=True # Detach from parent process |
| 315 | + ) |
| 316 | + except Exception: |
| 317 | + # If subprocess fails, silently continue |
| 318 | + pass |
| 319 | + |
276 | 320 | return 0 |
277 | 321 |
|
278 | 322 | # No cache at all so fall through to fresh fetch |
|
0 commit comments