diff options
-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) | ||