diff options
Diffstat (limited to 'scripts/contrib/convert-spdx-licenses.py')
| -rwxr-xr-x | scripts/contrib/convert-spdx-licenses.py | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/scripts/contrib/convert-spdx-licenses.py b/scripts/contrib/convert-spdx-licenses.py new file mode 100755 index 0000000000..68b9e2f18e --- /dev/null +++ b/scripts/contrib/convert-spdx-licenses.py | |||
| @@ -0,0 +1,144 @@ | |||
| 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 | |||
| 10 | import re | ||
| 11 | import os | ||
| 12 | import sys | ||
| 13 | import tempfile | ||
| 14 | import shutil | ||
| 15 | import mimetypes | ||
| 16 | |||
| 17 | if len(sys.argv) < 2: | ||
| 18 | print("Please specify a directory to run the conversion script against.") | ||
| 19 | sys.exit(1) | ||
| 20 | |||
| 21 | license_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 | |||
| 99 | def 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 | if modified: | ||
| 118 | shutil.copymode(fn, abs_path) | ||
| 119 | os.remove(fn) | ||
| 120 | shutil.move(abs_path, fn) | ||
| 121 | except UnicodeDecodeError: | ||
| 122 | pass | ||
| 123 | |||
| 124 | ourname = os.path.basename(sys.argv[0]) | ||
| 125 | ourversion = "0.01" | ||
| 126 | |||
| 127 | if os.path.isfile(sys.argv[1]): | ||
| 128 | processfile(sys.argv[1]) | ||
| 129 | sys.exit(0) | ||
| 130 | |||
| 131 | for targetdir in sys.argv[1:]: | ||
| 132 | print("processing directory '%s'" % targetdir) | ||
| 133 | for root, dirs, files in os.walk(targetdir): | ||
| 134 | for name in files: | ||
| 135 | if name == ourname: | ||
| 136 | continue | ||
| 137 | fn = os.path.join(root, name) | ||
| 138 | if os.path.islink(fn): | ||
| 139 | continue | ||
| 140 | if "/.git/" in fn or fn.endswith(".html") or fn.endswith(".patch") or fn.endswith(".m4") or fn.endswith(".diff") or fn.endswith(".orig"): | ||
| 141 | continue | ||
| 142 | processfile(fn) | ||
| 143 | |||
| 144 | print("All files processed with version %s" % ourversion) | ||
