1#! /usr/bin/env python3 2# 3# Copyright OpenEmbedded Contributors 4# 5# SPDX-License-Identifier: GPL-2.0-only 6 7import argparse 8import json 9import sys 10import urllib.request 11from pathlib import Path 12 13TOP_DIR = Path(__file__).parent.parent 14 15 16def main(): 17 parser = argparse.ArgumentParser( 18 description="Update SPDX License files from upstream" 19 ) 20 parser.add_argument( 21 "-v", 22 "--version", 23 metavar="MAJOR.MINOR[.MICRO]", 24 help="Pull specific version of License list instead of latest", 25 ) 26 parser.add_argument( 27 "--overwrite", 28 action="store_true", 29 help="Update existing license file text with upstream text", 30 ) 31 parser.add_argument( 32 "--deprecated", 33 action="store_true", 34 help="Update deprecated licenses", 35 ) 36 parser.add_argument( 37 "--dest", 38 type=Path, 39 default=TOP_DIR / "meta" / "files" / "common-licenses", 40 help="Write licenses to directory DEST. Default is %(default)s", 41 ) 42 43 args = parser.parse_args() 44 45 if args.version: 46 version = f"v{args.version}" 47 else: 48 # Fetch the latest release 49 req = urllib.request.Request( 50 "https://api.github.com/repos/spdx/license-list-data/releases/latest" 51 ) 52 req.add_header("X-GitHub-Api-Version", "2022-11-28") 53 req.add_header("Accept", "application/vnd.github+json") 54 with urllib.request.urlopen(req) as response: 55 data = json.load(response) 56 version = data["tag_name"] 57 58 print(f"Pulling SPDX license list version {version}") 59 req = urllib.request.Request( 60 f"https://raw.githubusercontent.com/spdx/license-list-data/{version}/json/licenses.json" 61 ) 62 with urllib.request.urlopen(req) as response: 63 spdx_licenses = json.load(response) 64 65 with (TOP_DIR / "meta" / "files" / "spdx-licenses.json").open("w") as f: 66 json.dump(spdx_licenses, f, sort_keys=True, indent=2) 67 68 total_count = len(spdx_licenses["licenses"]) 69 updated = 0 70 for idx, lic in enumerate(spdx_licenses["licenses"]): 71 lic_id = lic["licenseId"] 72 73 print(f"[{idx + 1} of {total_count}] ", end="") 74 75 dest_license_file = args.dest / lic_id 76 if dest_license_file.is_file() and not args.overwrite: 77 print(f"Skipping {lic_id} since it already exists") 78 continue 79 80 print(f"Fetching {lic_id}... ", end="", flush=True) 81 82 req = urllib.request.Request(lic["detailsUrl"]) 83 with urllib.request.urlopen(req) as response: 84 lic_data = json.load(response) 85 86 if lic_data["isDeprecatedLicenseId"] and not args.deprecated: 87 print("Skipping (deprecated)") 88 continue 89 90 with dest_license_file.open("w") as f: 91 f.write(lic_data["licenseText"]) 92 updated += 1 93 print("done") 94 95 print(f"Updated {updated} licenses") 96 97 return 0 98 99 100if __name__ == "__main__": 101 sys.exit(main()) 102