/ scripts / update-license-headers.py
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()