Fix iOS build for XCode 4.6.
[chromium-blink-merge.git] / tools / checklicenses / checklicenses.py
blob6145785dcd167bd55a5375bcc0273e0150e99fd5
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Makes sure that all files contain proper licensing information."""
9 import optparse
10 import os.path
11 import subprocess
12 import sys
15 def PrintUsage():
16 print """Usage: python checklicenses.py [--root <root>] [tocheck]
17 --root Specifies the repository root. This defaults to "../.." relative
18 to the script file. This will be correct given the normal location
19 of the script in "<root>/tools/checklicenses".
21 --ignore-suppressions Ignores path-specific license whitelist. Useful when
22 trying to remove a suppression/whitelist entry.
24 tocheck Specifies the directory, relative to root, to check. This defaults
25 to "." so it checks everything.
27 Examples:
28 python checklicenses.py
29 python checklicenses.py --root ~/chromium/src third_party"""
32 WHITELISTED_LICENSES = [
33 'Apache (v2.0)',
34 'Apache (v2.0) BSD (2 clause)',
35 'Apache (v2.0) GPL (v2)',
36 'Apple MIT', # https://fedoraproject.org/wiki/Licensing/Apple_MIT_License
37 'APSL (v2)',
38 'APSL (v2) BSD (4 clause)',
39 'BSD',
40 'BSD (2 clause)',
41 'BSD (2 clause) MIT/X11 (BSD like)',
42 'BSD (3 clause)',
43 'BSD (3 clause) ISC',
44 'BSD (3 clause) LGPL (v2 or later)',
45 'BSD (3 clause) LGPL (v2.1 or later)',
46 'BSD (3 clause) MIT/X11 (BSD like)',
47 'BSD (4 clause)',
48 'BSD-like',
50 # TODO(phajdan.jr): Make licensecheck not print BSD-like twice.
51 'BSD-like MIT/X11 (BSD like)',
53 'BSL (v1.0)',
54 'GPL (v2 or later) with Bison parser exception',
55 'GPL (v2 or later) with libtool exception',
56 'GPL (v3 or later) with Bison parser exception',
57 'GPL with Bison parser exception',
58 'ISC',
59 'LGPL',
60 'LGPL (v2)',
61 'LGPL (v2 or later)',
62 'LGPL (v2.1)',
63 'LGPL (v3 or later)',
65 # TODO(phajdan.jr): Make licensecheck convert that comma to a dot.
66 'LGPL (v2,1 or later)',
68 'LGPL (v2.1 or later)',
69 'MPL (v1.0) LGPL (v2 or later)',
70 'MPL (v1.1)',
71 'MPL (v1.1) BSD-like',
72 'MPL (v1.1) BSD-like GPL (unversioned/unknown version)',
73 'MPL (v1.1,) BSD (3 clause) GPL (unversioned/unknown version) '
74 'LGPL (v2.1 or later)',
75 'MPL (v1.1) GPL (unversioned/unknown version)',
76 'MPL (v2.0)',
78 # TODO(phajdan.jr): Make licensecheck not print the comma after 1.1.
79 'MPL (v1.1,) GPL (unversioned/unknown version) LGPL (v2 or later)',
80 'MPL (v1.1,) GPL (unversioned/unknown version) LGPL (v2.1 or later)',
82 'MIT/X11 (BSD like)',
83 'Ms-PL',
84 'Public domain',
85 'Public domain BSD',
86 'Public domain BSD (3 clause)',
87 'Public domain BSD-like',
88 'Public domain LGPL (v2.1 or later)',
89 'libpng',
90 'zlib/libpng',
91 'SGI Free Software License B',
92 'University of Illinois/NCSA Open Source License (BSD like)',
96 PATH_SPECIFIC_WHITELISTED_LICENSES = {
97 'base/hash.cc': [ # http://crbug.com/98100
98 'UNKNOWN',
100 'base/third_party/icu': [ # http://crbug.com/98087
101 'UNKNOWN',
104 # http://code.google.com/p/google-breakpad/issues/detail?id=450
105 'breakpad/src': [
106 'UNKNOWN',
109 'chrome/common/extensions/docs/examples': [ # http://crbug.com/98092
110 'UNKNOWN',
112 'chrome/test/data/gpu/vt': [
113 'UNKNOWN',
115 'chrome/test/data/layout_tests/LayoutTests': [
116 'UNKNOWN',
118 'courgette/third_party/bsdiff_create.cc': [ # http://crbug.com/98095
119 'UNKNOWN',
121 'data/mozilla_js_tests': [
122 'UNKNOWN',
124 'data/page_cycler': [
125 'UNKNOWN',
126 'GPL (v2 or later)',
128 'data/tab_switching': [
129 'UNKNOWN',
131 'googleurl': [ # http://code.google.com/p/google-url/issues/detail?id=15
132 'UNKNOWN',
135 'native_client': [ # http://crbug.com/98099
136 'UNKNOWN',
138 'native_client/toolchain': [
139 'BSD GPL (v2 or later)',
140 'BSD (2 clause) GPL (v2 or later)',
141 'BSD (3 clause) GPL (v2 or later)',
142 'BSL (v1.0) GPL',
143 'BSL (v1.0) GPL (v3.1)',
144 'GPL',
145 'GPL (unversioned/unknown version)',
146 'GPL (v2)',
147 'GPL (v2 or later)',
148 'GPL (v3.1)',
149 'GPL (v3 or later)',
151 'net/tools/spdyshark': [
152 'GPL (v2 or later)',
153 'UNKNOWN',
156 # http://crbug.com/98107
157 'ppapi/c/documentation/check.sh': [
158 'UNKNOWN',
160 'ppapi/cpp/documentation/check.sh': [
161 'UNKNOWN',
163 'ppapi/lib/gl/include': [
164 'UNKNOWN',
166 'ppapi/native_client/tests/earth/earth_image.inc': [
167 'UNKNOWN',
170 'third_party/WebKit': [
171 'UNKNOWN',
173 'third_party/WebKit/Websites/webkit.org/blog/wp-content/plugins/'
174 'akismet/akismet.php': [
175 'GPL (v2 or later)'
177 'third_party/WebKit/Source/JavaScriptCore/tests/mozilla': [
178 'GPL',
179 'GPL (v2 or later)',
180 'GPL (unversioned/unknown version)',
182 'third_party/active_doc': [ # http://crbug.com/98113
183 'UNKNOWN',
186 # http://code.google.com/p/angleproject/issues/detail?id=217
187 'third_party/angle': [
188 'UNKNOWN',
191 'third_party/bsdiff/mbsdiff.cc': [
192 'UNKNOWN',
194 'third_party/bzip2': [
195 'UNKNOWN',
197 'third_party/cld/encodings/compact_lang_det': [ # http://crbug.com/98120
198 'UNKNOWN',
200 # Not used. http://crbug.com/156020
201 # Using third_party/cros_dbus_cplusplus/cros_dbus_cplusplus.gyp instead.
202 'third_party/cros_dbus_cplusplus/source/autogen.sh': [
203 'UNKNOWN',
205 # Included in the source tree but not built. http://crbug.com/156020
206 'third_party/cros_dbus_cplusplus/source/examples': [
207 'UNKNOWN',
209 'third_party/devscripts': [
210 'GPL (v2 or later)',
212 'third_party/expat/files/lib': [ # http://crbug.com/98121
213 'UNKNOWN',
215 'third_party/ffmpeg': [
216 'GPL',
217 'GPL (v2)',
218 'GPL (v2 or later)',
219 'UNKNOWN', # http://crbug.com/98123
221 'third_party/findbugs/doc': [ # http://crbug.com/157206
222 'UNKNOWN',
224 'third_party/gles2_book': [ # http://crbug.com/98130
225 'UNKNOWN',
227 'third_party/gles2_conform/GTF_ES': [ # http://crbug.com/98131
228 'UNKNOWN',
230 'third_party/harfbuzz': [ # http://crbug.com/98133
231 'UNKNOWN',
233 'third_party/hunspell': [ # http://crbug.com/98134
234 'UNKNOWN',
236 'third_party/hyphen/hyphen.tex': [ # http://crbug.com/157375
237 'UNKNOWN',
239 'third_party/iccjpeg': [ # http://crbug.com/98137
240 'UNKNOWN',
242 'third_party/icu': [ # http://crbug.com/98301
243 'UNKNOWN',
245 'third_party/jemalloc': [ # http://crbug.com/98302
246 'UNKNOWN',
248 'third_party/lcov': [ # http://crbug.com/98304
249 'UNKNOWN',
251 'third_party/lcov/contrib/galaxy/genflat.pl': [
252 'GPL (v2 or later)',
254 'third_party/lcov-1.9/contrib/galaxy/genflat.pl': [
255 'GPL (v2 or later)',
257 'third_party/libevent': [ # http://crbug.com/98309
258 'UNKNOWN',
260 'third_party/libjingle/source/talk': [ # http://crbug.com/98310
261 'UNKNOWN',
263 'third_party/libjingle/source_internal/talk': [ # http://crbug.com/98310
264 'UNKNOWN',
266 'third_party/libjpeg': [ # http://crbug.com/98313
267 'UNKNOWN',
269 'third_party/libjpeg_turbo': [ # http://crbug.com/98314
270 'UNKNOWN',
272 'third_party/libpng': [ # http://crbug.com/98318
273 'UNKNOWN',
276 # The following files lack license headers, but are trivial.
277 'third_party/libusb/src/libusb/os/poll_posix.h': [
278 'UNKNOWN',
280 'third_party/libusb/src/libusb/version.h': [
281 'UNKNOWN',
283 'third_party/libusb/src/autogen.sh': [
284 'UNKNOWN',
286 'third_party/libusb/src/config.h': [
287 'UNKNOWN',
289 'third_party/libusb/src/msvc/config.h': [
290 'UNKNOWN',
293 'third_party/libvpx/source': [ # http://crbug.com/98319
294 'UNKNOWN',
296 'third_party/libvpx/source/libvpx/examples/includes': [
297 'GPL (v2 or later)',
299 'third_party/libwebp': [ # http://crbug.com/98448
300 'UNKNOWN',
302 'third_party/libxml': [
303 'UNKNOWN',
305 'third_party/libxslt': [
306 'UNKNOWN',
308 'third_party/lzma_sdk': [
309 'UNKNOWN',
311 'third_party/mesa/MesaLib': [
312 'GPL (v2)',
313 'GPL (v3 or later)',
314 'MIT/X11 (BSD like) GPL (v3 or later) with Bison parser exception',
315 'UNKNOWN', # http://crbug.com/98450
317 'third_party/modp_b64': [
318 'UNKNOWN',
320 'third_party/npapi/npspy/extern/java': [
321 'GPL (unversioned/unknown version)',
323 'third_party/openssl': [ # http://crbug.com/98451
324 'UNKNOWN',
326 'third_party/ots/tools/ttf-checksum.py': [ # http://code.google.com/p/ots/issues/detail?id=2
327 'UNKNOWN',
329 'third_party/molokocacao': [ # http://crbug.com/98453
330 'UNKNOWN',
332 'third_party/npapi/npspy': [
333 'UNKNOWN',
335 'third_party/ocmock/OCMock': [ # http://crbug.com/98454
336 'UNKNOWN',
338 'third_party/opus/src': [ # http://crbug.com/156738
339 'UNKNOWN',
341 'third_party/ply/__init__.py': [
342 'UNKNOWN',
344 'third_party/protobuf': [ # http://crbug.com/98455
345 'UNKNOWN',
347 'third_party/pylib': [
348 'UNKNOWN',
350 'third_party/scons-2.0.1/engine/SCons': [ # http://crbug.com/98462
351 'UNKNOWN',
353 'third_party/simplejson': [
354 'UNKNOWN',
356 'third_party/skia': [ # http://crbug.com/98463
357 'UNKNOWN',
359 'third_party/snappy/src': [ # http://crbug.com/98464
360 'UNKNOWN',
362 'third_party/smhasher/src': [ # http://crbug.com/98465
363 'UNKNOWN',
365 'third_party/sqlite': [
366 'UNKNOWN',
368 'third_party/swig/Lib/linkruntime.c': [ # http://crbug.com/98585
369 'UNKNOWN',
371 'third_party/talloc': [
372 'GPL (v3 or later)',
373 'UNKNOWN', # http://crbug.com/98588
375 'third_party/tcmalloc': [
376 'UNKNOWN', # http://crbug.com/98589
378 'third_party/tlslite': [
379 'UNKNOWN',
381 'third_party/webdriver': [ # http://crbug.com/98590
382 'UNKNOWN',
384 'third_party/webrtc': [ # http://crbug.com/98592
385 'UNKNOWN',
387 'third_party/xdg-utils': [ # http://crbug.com/98593
388 'UNKNOWN',
390 'third_party/yasm/source': [ # http://crbug.com/98594
391 'UNKNOWN',
393 'third_party/zlib/contrib/minizip': [
394 'UNKNOWN',
396 'third_party/zlib/trees.h': [
397 'UNKNOWN',
399 'tools/dromaeo_benchmark_runner/dromaeo_benchmark_runner.py': [
400 'UNKNOWN',
402 'tools/emacs': [ # http://crbug.com/98595
403 'UNKNOWN',
405 'tools/grit/grit/node/custom/__init__.py': [
406 'UNKNOWN',
408 'tools/gyp/test': [
409 'UNKNOWN',
411 'tools/histograms': [
412 'UNKNOWN',
414 'tools/memory_watcher': [
415 'UNKNOWN',
417 'tools/playback_benchmark': [
418 'UNKNOWN',
420 'tools/python/google/__init__.py': [
421 'UNKNOWN',
423 'tools/site_compare': [
424 'UNKNOWN',
426 'tools/stats_viewer/Properties/AssemblyInfo.cs': [
427 'UNKNOWN',
429 'tools/symsrc/pefile.py': [
430 'UNKNOWN',
432 'v8/test/cctest': [ # http://crbug.com/98597
433 'UNKNOWN',
435 'webkit/data/ico_decoder': [
436 'UNKNOWN',
441 def check_licenses(options, args):
442 # Figure out which directory we have to check.
443 if len(args) == 0:
444 # No directory to check specified, use the repository root.
445 start_dir = options.base_directory
446 elif len(args) == 1:
447 # Directory specified. Start here. It's supposed to be relative to the
448 # base directory.
449 start_dir = os.path.abspath(os.path.join(options.base_directory, args[0]))
450 else:
451 # More than one argument, we don't handle this.
452 PrintUsage()
453 return 1
455 print "Using base directory:", options.base_directory
456 print "Checking:", start_dir
457 print
459 licensecheck_path = os.path.abspath(os.path.join(options.base_directory,
460 'third_party',
461 'devscripts',
462 'licensecheck.pl'))
464 licensecheck = subprocess.Popen([licensecheck_path,
465 '-l', '100',
466 '-r', start_dir],
467 stdout=subprocess.PIPE,
468 stderr=subprocess.PIPE)
469 stdout, stderr = licensecheck.communicate()
470 if options.verbose:
471 print '----------- licensecheck stdout -----------'
472 print stdout
473 print '--------- end licensecheck stdout ---------'
474 if licensecheck.returncode != 0 or stderr:
475 print '----------- licensecheck stderr -----------'
476 print stderr
477 print '--------- end licensecheck stderr ---------'
478 print "\nFAILED\n"
479 return 1
481 success = True
482 for line in stdout.splitlines():
483 filename, license = line.split(':', 1)
484 filename = os.path.relpath(filename.strip(), options.base_directory)
486 # All files in the build output directory are generated one way or another.
487 # There's no need to check them.
488 if filename.startswith('out/') or filename.startswith('sconsbuild/'):
489 continue
491 # For now we're just interested in the license.
492 license = license.replace('*No copyright*', '').strip()
494 # Skip generated files.
495 if 'GENERATED FILE' in license:
496 continue
498 if license in WHITELISTED_LICENSES:
499 continue
501 if not options.ignore_suppressions:
502 found_path_specific = False
503 for prefix in PATH_SPECIFIC_WHITELISTED_LICENSES:
504 if (filename.startswith(prefix) and
505 license in PATH_SPECIFIC_WHITELISTED_LICENSES[prefix]):
506 found_path_specific = True
507 break
508 if found_path_specific:
509 continue
511 print "'%s' has non-whitelisted license '%s'" % (filename, license)
512 success = False
514 if success:
515 print "\nSUCCESS\n"
516 return 0
517 else:
518 print "\nFAILED\n"
519 print "Please read",
520 print "http://www.chromium.org/developers/adding-3rd-party-libraries"
521 print "for more info how to handle the failure."
522 print
523 print "Please respect OWNERS of checklicenses.py. Changes violating"
524 print "this requirement may be reverted."
525 return 1
528 def main():
529 default_root = os.path.abspath(
530 os.path.join(os.path.dirname(__file__), '..', '..'))
531 option_parser = optparse.OptionParser()
532 option_parser.add_option('--root', default=default_root,
533 dest='base_directory',
534 help='Specifies the repository root. This defaults '
535 'to "../.." relative to the script file, which '
536 'will normally be the repository root.')
537 option_parser.add_option('-v', '--verbose', action='store_true',
538 default=False, help='Print debug logging')
539 option_parser.add_option('--ignore-suppressions',
540 action='store_true',
541 default=False,
542 help='Ignore path-specific license whitelist.')
543 options, args = option_parser.parse_args()
544 return check_licenses(options, args)
547 if '__main__' == __name__:
548 sys.exit(main())