1#!/usr/bin/env python3 2# 3# Conversion script to change LICENSE entries to SPDX identifiers 4# 5# Copyright (C) 2021-2022 Richard Purdie 6# 7# SPDX-License-Identifier: GPL-2.0-only 8# 9 10import re 11import os 12import sys 13import tempfile 14import shutil 15import mimetypes 16 17if len(sys.argv) < 2: 18 print("Please specify a directory to run the conversion script against.") 19 sys.exit(1) 20 21license_map = { 22"AGPL-3" : "AGPL-3.0-only", 23"AGPL-3+" : "AGPL-3.0-or-later", 24"AGPLv3" : "AGPL-3.0-only", 25"AGPLv3+" : "AGPL-3.0-or-later", 26"AGPLv3.0" : "AGPL-3.0-only", 27"AGPLv3.0+" : "AGPL-3.0-or-later", 28"AGPL-3.0" : "AGPL-3.0-only", 29"AGPL-3.0+" : "AGPL-3.0-or-later", 30"BSD-0-Clause" : "0BSD", 31"GPL-1" : "GPL-1.0-only", 32"GPL-1+" : "GPL-1.0-or-later", 33"GPLv1" : "GPL-1.0-only", 34"GPLv1+" : "GPL-1.0-or-later", 35"GPLv1.0" : "GPL-1.0-only", 36"GPLv1.0+" : "GPL-1.0-or-later", 37"GPL-1.0" : "GPL-1.0-only", 38"GPL-1.0+" : "GPL-1.0-or-later", 39"GPL-2" : "GPL-2.0-only", 40"GPL-2+" : "GPL-2.0-or-later", 41"GPLv2" : "GPL-2.0-only", 42"GPLv2+" : "GPL-2.0-or-later", 43"GPLv2.0" : "GPL-2.0-only", 44"GPLv2.0+" : "GPL-2.0-or-later", 45"GPL-2.0" : "GPL-2.0-only", 46"GPL-2.0+" : "GPL-2.0-or-later", 47"GPL-3" : "GPL-3.0-only", 48"GPL-3+" : "GPL-3.0-or-later", 49"GPLv3" : "GPL-3.0-only", 50"GPLv3+" : "GPL-3.0-or-later", 51"GPLv3.0" : "GPL-3.0-only", 52"GPLv3.0+" : "GPL-3.0-or-later", 53"GPL-3.0" : "GPL-3.0-only", 54"GPL-3.0+" : "GPL-3.0-or-later", 55"LGPLv2" : "LGPL-2.0-only", 56"LGPLv2+" : "LGPL-2.0-or-later", 57"LGPLv2.0" : "LGPL-2.0-only", 58"LGPLv2.0+" : "LGPL-2.0-or-later", 59"LGPL-2.0" : "LGPL-2.0-only", 60"LGPL-2.0+" : "LGPL-2.0-or-later", 61"LGPL2.1" : "LGPL-2.1-only", 62"LGPL2.1+" : "LGPL-2.1-or-later", 63"LGPLv2.1" : "LGPL-2.1-only", 64"LGPLv2.1+" : "LGPL-2.1-or-later", 65"LGPL-2.1" : "LGPL-2.1-only", 66"LGPL-2.1+" : "LGPL-2.1-or-later", 67"LGPLv3" : "LGPL-3.0-only", 68"LGPLv3+" : "LGPL-3.0-or-later", 69"LGPL-3.0" : "LGPL-3.0-only", 70"LGPL-3.0+" : "LGPL-3.0-or-later", 71"MPL-1" : "MPL-1.0", 72"MPLv1" : "MPL-1.0", 73"MPLv1.1" : "MPL-1.1", 74"MPLv2" : "MPL-2.0", 75"MIT-X" : "MIT", 76"MIT-style" : "MIT", 77"openssl" : "OpenSSL", 78"PSF" : "PSF-2.0", 79"PSFv2" : "PSF-2.0", 80"Python-2" : "Python-2.0", 81"Apachev2" : "Apache-2.0", 82"Apache-2" : "Apache-2.0", 83"Artisticv1" : "Artistic-1.0", 84"Artistic-1" : "Artistic-1.0", 85"AFL-2" : "AFL-2.0", 86"AFL-1" : "AFL-1.2", 87"AFLv2" : "AFL-2.0", 88"AFLv1" : "AFL-1.2", 89"CDDLv1" : "CDDL-1.0", 90"CDDL-1" : "CDDL-1.0", 91"EPLv1.0" : "EPL-1.0", 92"FreeType" : "FTL", 93"Nauman" : "Naumen", 94"tcl" : "TCL", 95"vim" : "Vim", 96"SGIv1" : "SGI-1", 97} 98 99def processfile(fn): 100 print("processing file '%s'" % fn) 101 try: 102 fh, abs_path = tempfile.mkstemp() 103 modified = False 104 with os.fdopen(fh, 'w') as new_file: 105 with open(fn, "r") as old_file: 106 for line in old_file: 107 if not line.startswith("LICENSE"): 108 new_file.write(line) 109 continue 110 orig = line 111 for license in sorted(license_map, key=len, reverse=True): 112 for ending in ['"', "'", " ", ")"]: 113 line = line.replace(license + ending, license_map[license] + ending) 114 if orig != line: 115 modified = True 116 new_file.write(line) 117 new_file.close() 118 if modified: 119 shutil.copymode(fn, abs_path) 120 os.remove(fn) 121 shutil.move(abs_path, fn) 122 except UnicodeDecodeError: 123 pass 124 125ourname = os.path.basename(sys.argv[0]) 126ourversion = "0.01" 127 128if os.path.isfile(sys.argv[1]): 129 processfile(sys.argv[1]) 130 sys.exit(0) 131 132for targetdir in sys.argv[1:]: 133 print("processing directory '%s'" % targetdir) 134 for root, dirs, files in os.walk(targetdir): 135 for name in files: 136 if name == ourname: 137 continue 138 fn = os.path.join(root, name) 139 if os.path.islink(fn): 140 continue 141 if "/.git/" in fn or fn.endswith(".html") or fn.endswith(".patch") or fn.endswith(".m4") or fn.endswith(".diff") or fn.endswith(".orig"): 142 continue 143 processfile(fn) 144 145print("All files processed with version %s" % ourversion) 146