update-license-headers.py
1 #!/usr/bin/env python3 2 """ 3 Update license headers across all alpha-delta-network repos. 4 Replaces old Apache 2.0 Alpha-Delta Network Inc headers with new CC0 ACDC Network headers. 5 """ 6 7 import os 8 import re 9 import sys 10 from pathlib import Path 11 12 # Old header pattern (regex to match the old header block) 13 OLD_HEADER_PATTERN = re.compile( 14 r'// Copyright \(c\) 2019-2025 Alpha-Delta Network Inc\.\n' 15 r'// This file is part of the (\w+) library\.\n' 16 r'\n?' 17 r'// Licensed under the Apache License.*?' 18 r'// limitations under the License\.\n', 19 re.DOTALL 20 ) 21 22 # New header template 23 NEW_HEADER_TEMPLATE = '''// Copyright (c) 2025-2026 ACDC Network 24 // This file is part of the {library_name} library. 25 // 26 // Alpha Chain | Delta Chain Protocol 27 // International Monetary Graphite. 28 // 29 // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com). 30 // They built world-class ZK infrastructure. We installed the EASY button. 31 // Their cryptography: elegant. Our modifications: bureaucracy-compatible. 32 // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours. 33 // 34 // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0 35 // All modifications and new work: CC0 1.0 Universal Public Domain Dedication. 36 // No rights reserved. No permission required. No warranty. No refunds. 37 // 38 // https://creativecommons.org/publicdomain/zero/1.0/ 39 // SPDX-License-Identifier: CC0-1.0 40 41 ''' 42 43 def get_library_name(repo_path: Path) -> str: 44 """Get library name from repo path.""" 45 name = repo_path.name 46 # Map repo names to library names if different 47 return name 48 49 def update_file(file_path: Path, library_name: str, dry_run: bool = False) -> bool: 50 """Update a single file's header. Returns True if changed.""" 51 try: 52 content = file_path.read_text(encoding='utf-8') 53 except Exception as e: 54 print(f" Error reading {file_path}: {e}") 55 return False 56 57 # Check if old header exists 58 match = OLD_HEADER_PATTERN.search(content) 59 if not match: 60 return False 61 62 # Get the library name from the old header if present 63 old_lib_name = match.group(1) if match.groups() else library_name 64 65 # Create new header 66 new_header = NEW_HEADER_TEMPLATE.format(library_name=old_lib_name) 67 68 # Replace old header with new 69 new_content = OLD_HEADER_PATTERN.sub(new_header, content, count=1) 70 71 if dry_run: 72 print(f" Would update: {file_path}") 73 return True 74 75 try: 76 file_path.write_text(new_content, encoding='utf-8') 77 print(f" Updated: {file_path}") 78 return True 79 except Exception as e: 80 print(f" Error writing {file_path}: {e}") 81 return False 82 83 def process_repo(repo_path: Path, dry_run: bool = False) -> int: 84 """Process all .rs files in a repo. Returns count of updated files.""" 85 if not repo_path.exists(): 86 print(f"Repo not found: {repo_path}") 87 return 0 88 89 library_name = get_library_name(repo_path) 90 print(f"\nProcessing {repo_path.name} (library: {library_name})...") 91 92 updated = 0 93 for rs_file in repo_path.rglob("*.rs"): 94 # Skip target directories 95 if "target" in str(rs_file): 96 continue 97 if update_file(rs_file, library_name, dry_run): 98 updated += 1 99 100 print(f" {updated} files {'would be ' if dry_run else ''}updated in {repo_path.name}") 101 return updated 102 103 def main(): 104 dry_run = "--dry-run" in sys.argv 105 if dry_run: 106 print("DRY RUN - no files will be modified\n") 107 108 base_path = Path("/mnt/c/Users/MarcoAniballi/Radicle") 109 110 repos = [ 111 "alphavm", 112 "alphaos", 113 "deltavm", 114 "deltaos", 115 "adnet", 116 "adl", 117 "sdk", 118 "ac-dc", 119 "acdc-core", 120 ] 121 122 total = 0 123 for repo in repos: 124 repo_path = base_path / repo 125 total += process_repo(repo_path, dry_run) 126 127 print(f"\n{'Would update' if dry_run else 'Updated'} {total} files total") 128 129 if not dry_run: 130 print("\nDon't forget to commit changes in each repo!") 131 132 if __name__ == "__main__": 133 main()