Andrew Geissler | 7e0e3c0 | 2022-02-25 20:34:39 +0000 | [diff] [blame^] | 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 | 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 | |
| 125 | ourname = os.path.basename(sys.argv[0]) |
| 126 | ourversion = "0.01" |
| 127 | |
| 128 | if os.path.isfile(sys.argv[1]): |
| 129 | processfile(sys.argv[1]) |
| 130 | sys.exit(0) |
| 131 | |
| 132 | for 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 | |
| 145 | print("All files processed with version %s" % ourversion) |