#!/usr/bin/env python3 """ Fetch BIND9 grammar files from Gitea mirror repository for version comparison. This script uses the Gitea MCP tools to fetch grammar files from the official BIND9 mirror at git.valid.dk/Mirrors/bind9 for specified version tags. """ import argparse import json import os import sys from pathlib import Path from typing import Dict, List # Grammar files to fetch from doc/misc/ GRAMMAR_FILES = [ "options", "forward.zoneopt", "hint.zoneopt", "in-view.zoneopt", "mirror.zoneopt", "primary.zoneopt", "redirect.zoneopt", "secondary.zoneopt", "static-stub.zoneopt", "stub.zoneopt", "delegation-only.zoneopt", "rndc.grammar", ] # Support files SUPPORT_FILES = [ "parsegrammar.py", "checkgrammar.py", ] def fetch_file_content(owner: str, repo: str, ref: str, file_path: str) -> str: """ Fetch file content from Gitea repository. This would use mcp_gitea-mcp_get_file_content in the actual MCP environment. For standalone usage, returns placeholder. """ # In MCP environment, this would call: # mcp_gitea-mcp_get_file_content(owner=owner, repo=repo, ref=ref, filePath=file_path) print(f"Would fetch: {owner}/{repo}@{ref}:{file_path}") return "" def save_grammar_file(content: str, version: str, filename: str, output_dir: Path): """Save fetched grammar file to local directory.""" version_dir = output_dir / version / "grammar" version_dir.mkdir(parents=True, exist_ok=True) file_path = version_dir / filename with open(file_path, 'w', encoding='utf-8') as f: f.write(content) print(f"Saved: {file_path}") def fetch_version_grammars(owner: str, repo: str, tag: str, output_dir: Path): """Fetch all grammar files for a specific version tag.""" print(f"\n=== Fetching grammar files for {tag} ===") # Create metadata metadata = { "version": tag, "repository": f"{owner}/{repo}", "files": [], } # Fetch grammar files for grammar_file in GRAMMAR_FILES: try: file_path = f"doc/misc/{grammar_file}" content = fetch_file_content(owner, repo, tag, file_path) if content: save_grammar_file(content, tag, grammar_file, output_dir) metadata["files"].append({ "name": grammar_file, "path": file_path, "type": "grammar" }) except Exception as e: print(f"Warning: Could not fetch {grammar_file}: {e}") # Fetch support files for support_file in SUPPORT_FILES: try: file_path = f"doc/misc/{support_file}" content = fetch_file_content(owner, repo, tag, file_path) if content: save_grammar_file(content, tag, support_file, output_dir) metadata["files"].append({ "name": support_file, "path": file_path, "type": "support" }) except Exception as e: print(f"Warning: Could not fetch {support_file}: {e}") # Save metadata metadata_file = output_dir / tag / "metadata.json" with open(metadata_file, 'w', encoding='utf-8') as f: json.dump(metadata, f, indent=2) print(f"Metadata saved: {metadata_file}") return metadata def main(): """Main entry point.""" parser = argparse.ArgumentParser( description="Fetch BIND9 grammar files from Gitea mirror" ) parser.add_argument( "--owner", default="Mirrors", help="Repository owner (default: Mirrors)" ) parser.add_argument( "--repo", default="bind9", help="Repository name (default: bind9)" ) parser.add_argument( "--tags", nargs="+", default=["v9.18.44", "v9.20.18"], help="Version tags to fetch (default: v9.18.44 v9.20.18)" ) parser.add_argument( "--output-dir", type=Path, default=Path("bind9-grammar/upstream"), help="Output directory for grammar files" ) args = parser.parse_args() print("BIND9 Grammar Fetcher") print("=" * 60) print(f"Repository: {args.owner}/{args.repo}") print(f"Tags: {', '.join(args.tags)}") print(f"Output: {args.output_dir}") # Fetch grammars for each version results = {} for tag in args.tags: try: metadata = fetch_version_grammars( args.owner, args.repo, tag, args.output_dir ) results[tag] = metadata except Exception as e: print(f"Error fetching {tag}: {e}") sys.exit(1) # Save overall summary summary_file = args.output_dir / "fetch_summary.json" with open(summary_file, 'w', encoding='utf-8') as f: json.dump(results, f, indent=2) print(f"\n=== Fetch complete ===") print(f"Summary: {summary_file}") print(f"Fetched {len(results)} versions") if __name__ == "__main__": main()