/
mnskripnichenko
/
uvm-source-code-1.2-knowledge-mcp
Обзор
Документация
Войти
/
mnskripnichenko
/
uvm-source-code-1.2-knowledge-mcp
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
scripts/fetch_uvm_source.py
135 строк
5 KB
luoyonghao1997
first commit
02 мар 2026, 10:18
02 мар 2026, 10:18
8bcd356
Код
Авторство
О чём код?
#!/usr/bin/env python3 """ Download UVM 1.2 source code from the official Accellera GitHub repository. Run this script once before starting the MCP server. Usage: python scripts/fetch_uvm_source.py """ import shutil import ssl import subprocess import sys import tarfile import tempfile import urllib.request from pathlib import Path sys.path.insert(0, str(Path(__file__).parent.parent)) from config import UVM_SOURCE_DIR, UVM_REPO_URL, UVM_TAG, UVM_SRC_SUBPATH ARCHIVE_URL = ( f"https://github.com/accellera/uvm/archive/refs/tags/{UVM_TAG}.tar.gz" ) def _download(url: str, dest: Path) -> None: """ Download url → dest, trying three strategies in order: 1. curl (most reliable on macOS — respects system keychain) 2. urllib with SSL verification disabled (fallback for corp proxies / old Python) 3. urllib default (raises original error if all else fails) """ # ── Strategy 1: curl ────────────────────────────────────────────── curl = shutil.which("curl") if curl: result = subprocess.run( [curl, "-fsSL", "--retry", "3", "-o", str(dest), url], check=False, ) if result.returncode == 0: return print(f"[fetch] curl failed (exit {result.returncode}), trying urllib...") # ── Strategy 2: urllib, SSL verification disabled ───────────────── ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE def _progress(block_num: int, block_size: int, total_size: int) -> None: if total_size > 0: pct = min(block_num * block_size * 100 // total_size, 100) print(f"\r[fetch] {pct:3d}%", end="", flush=True) try: opener = urllib.request.build_opener( urllib.request.HTTPSHandler(context=ctx) ) with opener.open(url) as resp, open(dest, "wb") as f: total = int(resp.headers.get("Content-Length", 0)) downloaded = 0 block = 65536 while True: chunk = resp.read(block) if not chunk: break f.write(chunk) downloaded += len(chunk) _progress(downloaded // block, block, total) print() return except Exception as e: print(f"\n[fetch] urllib (no-verify) failed: {e}") # ── Strategy 3: urllib default (let it raise) ───────────────────── urllib.request.urlretrieve(url, dest, reporthook=_progress) print() def fetch(force: bool = False) -> None: if UVM_SOURCE_DIR.exists() and any(UVM_SOURCE_DIR.iterdir()): if not force: print( f"[fetch] UVM source already present at: {UVM_SOURCE_DIR}\n" " Pass --force to re-download." ) return print("[fetch] --force flag set. Re-downloading...") shutil.rmtree(UVM_SOURCE_DIR) UVM_SOURCE_DIR.mkdir(parents=True, exist_ok=True) print(f"[fetch] Downloading UVM {UVM_TAG} from:\n {ARCHIVE_URL}") with tempfile.TemporaryDirectory() as tmp: archive_path = Path(tmp) / "uvm.tar.gz" _download(ARCHIVE_URL, archive_path) print("[fetch] Extracting archive...") with tarfile.open(archive_path, "r:gz") as tar: tar.extractall(tmp) # The extracted folder will be named like "uvm-UVM_1_2_RELEASE" extracted_dirs = [ p for p in Path(tmp).iterdir() if p.is_dir() and p.name.startswith("uvm-") ] if not extracted_dirs: print("[fetch] ERROR: Could not find extracted directory.", file=sys.stderr) sys.exit(1) src_path = extracted_dirs[0] / UVM_SRC_SUBPATH if not src_path.exists(): print(f"[fetch] ERROR: Expected src path not found: {src_path}", file=sys.stderr) sys.exit(1) print(f"[fetch] Copying source files to {UVM_SOURCE_DIR}...") shutil.copytree(src_path, UVM_SOURCE_DIR, dirs_exist_ok=True) sv_count = sum( 1 for p in UVM_SOURCE_DIR.rglob("*") if p.suffix.lower() in {".sv", ".svh"} and p.is_file() ) print(f"[fetch] Done. {sv_count} .sv/.svh files available at {UVM_SOURCE_DIR}") if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description="Download UVM 1.2 source code") parser.add_argument("--force", action="store_true", help="Re-download even if already present") args = parser.parse_args() fetch(force=args.force)