blob: e87a7c8e95aeb59f0ad378dd65d78318ddfddf8f [file] [log] [blame]
Zack Williams557d3012019-04-19 15:53:00 -07001#!/usr/bin/env python
2
3# Copyright 2017-present Open Networking Foundation
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17from __future__ import absolute_import, print_function
18import sys
19import os
20from io import open
21
22
23COPYRIGHTS = {
24 "slash": """/*
25 * Copyright 2017-present Open Networking Foundation
26
27 * Licensed under the Apache License, Version 2.0 (the "License");
28 * you may not use this file except in compliance with the License.
29 * You may obtain a copy of the License at
30
31 * http://www.apache.org/licenses/LICENSE-2.0
32
33 * Unless required by applicable law or agreed to in writing, software
34 * distributed under the License is distributed on an "AS IS" BASIS,
35 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36 * See the License for the specific language governing permissions and
37 * limitations under the License.
38 */""",
39 "hash": """# Copyright 2017-present Open Networking Foundation
40#
41# Licensed under the Apache License, Version 2.0 (the "License");
42# you may not use this file except in compliance with the License.
43# You may obtain a copy of the License at
44#
45# http://www.apache.org/licenses/LICENSE-2.0
46#
47# Unless required by applicable law or agreed to in writing, software
48# distributed under the License is distributed on an "AS IS" BASIS,
49# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50# See the License for the specific language governing permissions and
51# limitations under the License.""",
52 "html": """<!--
53Copyright 2017-present Open Networking Foundation
54
55Licensed under the Apache License, Version 2.0 (the "License");
56you may not use this file except in compliance with the License.
57You may obtain a copy of the License at
58
59http://www.apache.org/licenses/LICENSE-2.0
60
61Unless required by applicable law or agreed to in writing, software
62distributed under the License is distributed on an "AS IS" BASIS,
63WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64See the License for the specific language governing permissions and
65limitations under the License.
66-->""",
67 "jinja": """{#
68Copyright 2017-present Open Networking Foundation
69
70Licensed under the Apache License, Version 2.0 (the "License");
71you may not use this file except in compliance with the License.
72You may obtain a copy of the License at
73
74http://www.apache.org/licenses/LICENSE-2.0
75
76Unless required by applicable law or agreed to in writing, software
77distributed under the License is distributed on an "AS IS" BASIS,
78WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79See the License for the specific language governing permissions and
80limitations under the License.
81#}""",
82 "ini": """;Copyright 2017-present Open Networking Foundation
83;
84;Licensed under the Apache License, Version 2.0 (the "License");
85;you may not use this file except in compliance with the License.
86;You may obtain a copy of the License at
87;
88;http://www.apache.org/licenses/LICENSE-2.0
89;
90;Unless required by applicable law or agreed to in writing, software
91;distributed under the License is distributed on an "AS IS" BASIS,
92;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
93;See the License for the specific language governing permissions and
94;limitations under the License.""",
95}
96
97EXT_MAPPING = {
98 ".js": COPYRIGHTS["slash"],
99 ".ts": COPYRIGHTS["slash"],
100 ".scss": COPYRIGHTS["slash"],
101 ".css": COPYRIGHTS["slash"],
102 ".gradle": COPYRIGHTS["slash"],
103 ".go": COPYRIGHTS["slash"],
104 ".c": COPYRIGHTS["slash"],
105 ".h": COPYRIGHTS["slash"],
106
107 "docker": COPYRIGHTS["hash"],
108 ".py": COPYRIGHTS["hash"],
109 ".model": COPYRIGHTS["hash"], # attic files
110 ".sh": COPYRIGHTS["hash"],
111 ".yaml": COPYRIGHTS["hash"],
112 ".yml": COPYRIGHTS["hash"],
113 ".m4": COPYRIGHTS["hash"],
114 ".sql": COPYRIGHTS["hash"],
115
116 ".html": COPYRIGHTS["html"],
117 ".xml": COPYRIGHTS["html"],
118 ".j2": COPYRIGHTS["jinja"],
119 ".ini": COPYRIGHTS["ini"],
120}
121
122
123def get_copyright(file):
124 name, ext = os.path.splitext(file)
125
126 if "Dockerfile" in name:
127 return EXT_MAPPING["docker"]
128 try:
129 return EXT_MAPPING[ext]
130 except KeyError:
131 print("Missing copyright for file of type: %s" % ext)
132 return None
133
134
135def add_copyright(file):
136 with open(file, 'r') as original:
137 data = original.read()
138 if "Licensed under the Apache License, Version 2.0" not in data:
139 print("Adding copyright to: %s" % file)
140
141 # don't push special first lines below copyright
142 specialline = ""
143 if data and "#!" in data.splitlines()[0]:
144 print("Has Shebang: %s" % data.splitlines()[0])
145 (specialline, data) = data.split("\n", 1)
146 specialline += "\n"
147
148 elif data and "---" in data.splitlines()[0]:
149 print("Has YAML start of document: %s" % data.splitlines()[0])
150 (specialline, data) = data.split("\n", 1)
151 specialline += "\n"
152
153 copy = get_copyright(file)
154 if copy:
155 with open(file, 'w') as modified:
156 modified.write(specialline + copy + "\n" + data)
157 return
158
159
160def get_files_ignore_by_git(root):
161 # NOTE this is not perfect, some file will still be copyrighted, but we
162 # save some time
163 if root == ".gitignore":
164 gitignore = root
165 else:
166 gitignore = os.path.join(root, ".gitignore")
167
168 exclusion_list = []
169 if os.path.exists(gitignore):
170 for line in open(gitignore).readlines():
171 if "#" not in line:
172 line = line.strip()
173 if line.endswith("/"):
174 line = line.replace("/", "")
175 exclusion_list.append(line)
176 return exclusion_list
177
178
179def should_skip(entry):
180
181 # do not skip directories
182 if os.path.isdir(entry):
183 return False
184
185 if "LICENSE.txt" in entry \
186 or ".git" in entry \
187 or ".idea" in entry:
188 return True
189
190 name, ext = os.path.splitext(entry)
191 if not ext or ext == "" \
192 or ext == ".pyc" \
193 or ext == ".txt" \
194 or ext == ".in" \
195 or ext == ".crt" \
196 or ext == ".unused" \
197 or ext == ".list" \
198 or ext == ".README" \
199 or ext == ".json" \
200 or ext == ".log" \
201 or ext == ".asc" \
202 or ext == ".dot" \
203 or ext == ".do" \
204 or ext == ".template" \
205 or ext == ".svg" \
206 or ext == ".ttf" \
207 or ext == ".woff" \
208 or ext == ".woof2" \
209 or ext == ".eot" \
210 or ext == ".md" \
211 or ext == ".png" \
212 or ext == ".pdf" \
213 or ext == ".PNG" \
214 or ext == ".jpg" \
215 or ext == ".gif" \
216 or ext == ".ico" \
217 or ext == ".conf"\
218 or ext == ".key" \
219 or ext == ".proto" \
220 or ext == ".xproto" \
221 or ext == ".xtarget" \
222 or ext == ".otf" \
223 or ext == ".desc":
224 return True
225 return False
226
227
228def recursive_iterate_dirs(source, apply_copyright=True):
229 # print "Iterating on: %s" % source
230 # skipping files in the gitignore
231 gitignored = get_files_ignore_by_git(source)
232 entries = []
233 for entry in os.listdir(source):
234
235 if entry in gitignored:
236 # print "Skipping because gitignored: %s" % entry
237 continue
238
239 entry = os.path.join(source, entry)
240 if should_skip(entry):
241 # print "Skipping: %s" % entry
242 continue
243
244 if os.path.isdir(entry):
245 entries.append(recursive_iterate_dirs(entry, apply_copyright))
246 elif os.path.isfile(entry):
247 entries.append(entry)
248 if apply_copyright is True:
249 add_copyright(entry)
250 return entries
251
252
253def flatten(aList):
254 t = []
255 for i in aList:
256 if not isinstance(i, list):
257 t.append(i)
258 else:
259 t.extend(flatten(i))
260 return t
261
262
263def list_file_types(source):
264 file_types = []
265 files = flatten(recursive_iterate_dirs(source, apply_copyright=False))
266 for entry in files:
267 name, ext = os.path.splitext(entry)
268 if ext not in file_types:
269 file_types.append(ext)
270 print(file_types)
271
272
273def main():
274 if len(sys.argv) < 2:
275 raise Exception("You must provide a path to the source folder"
276 "as arguments to the script")
277 source_root = os.path.abspath(os.path.join(os.getcwd(), sys.argv[1]))
278 if not os.path.exists(source_root):
279 raise Exception("You must provide an existing the source folder")
280 if len(sys.argv) == 3:
281 list_file_types(source_root)
282 else:
283 recursive_iterate_dirs(source_root)
284
285
286if __name__ == "__main__":
287 main()