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."""
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.
28 python checklicenses.py
29 python checklicenses.py --root ~/chromium/src third_party"""
32 WHITELISTED_LICENSES
= [
34 'Apache (v2.0) BSD (2 clause)',
35 'Apache (v2.0) GPL (v2)',
36 'Apple MIT', # https://fedoraproject.org/wiki/Licensing/Apple_MIT_License
38 'APSL (v2) BSD (4 clause)',
41 'BSD (2 clause) MIT/X11 (BSD like)',
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)',
50 # TODO(phajdan.jr): Make licensecheck not print BSD-like twice.
51 'BSD-like MIT/X11 (BSD like)',
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',
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)',
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)',
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)',
86 'Public domain BSD (3 clause)',
87 'Public domain BSD-like',
88 'Public domain LGPL (v2.1 or later)',
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
100 'base/third_party/icu': [ # http://crbug.com/98087
104 # http://code.google.com/p/google-breakpad/issues/detail?id=450
109 'chrome/common/extensions/docs/examples': [ # http://crbug.com/98092
112 'chrome/test/data/gpu/vt': [
115 'chrome/test/data/layout_tests/LayoutTests': [
118 'courgette/third_party/bsdiff_create.cc': [ # http://crbug.com/98095
121 'data/mozilla_js_tests': [
124 'data/page_cycler': [
128 'data/tab_switching': [
131 'googleurl': [ # http://code.google.com/p/google-url/issues/detail?id=15
135 'native_client': [ # http://crbug.com/98099
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)',
143 'BSL (v1.0) GPL (v3.1)',
145 'GPL (unversioned/unknown version)',
151 'net/tools/spdyshark': [
155 'third_party/WebKit': [
158 'third_party/WebKit/Websites/webkit.org/blog/wp-content/plugins/'
159 'akismet/akismet.php': [
162 'third_party/WebKit/Source/JavaScriptCore/tests/mozilla': [
165 'GPL (unversioned/unknown version)',
167 'third_party/active_doc': [ # http://crbug.com/98113
171 # http://code.google.com/p/angleproject/issues/detail?id=217
172 'third_party/angle': [
176 'third_party/bsdiff/mbsdiff.cc': [
179 'third_party/bzip2': [
183 # http://crbug.com/222828
184 # http://bugs.python.org/issue17514
185 'third_party/chromite/third_party/argparse.py': [
189 # Not used. http://crbug.com/156020
190 # Using third_party/cros_dbus_cplusplus/cros_dbus_cplusplus.gyp instead.
191 'third_party/cros_dbus_cplusplus/source/autogen.sh': [
194 # Included in the source tree but not built. http://crbug.com/156020
195 'third_party/cros_dbus_cplusplus/source/examples': [
198 'third_party/devscripts': [
201 'third_party/expat/files/lib': [ # http://crbug.com/98121
204 'third_party/ffmpeg': [
208 'UNKNOWN', # http://crbug.com/98123
210 'third_party/findbugs/doc': [ # http://crbug.com/157206
213 'third_party/freetype2': [ # http://crbug.com/177319
216 'third_party/gles2_book': [ # http://crbug.com/98130
219 'third_party/gles2_conform/GTF_ES': [ # http://crbug.com/98131
222 'third_party/harfbuzz': [ # http://crbug.com/98133
225 'third_party/hunspell': [ # http://crbug.com/98134
228 'third_party/hyphen/hyphen.tex': [ # http://crbug.com/157375
231 'third_party/iccjpeg': [ # http://crbug.com/98137
234 'third_party/icu': [ # http://crbug.com/98301
237 'third_party/jemalloc': [ # http://crbug.com/98302
240 'third_party/lcov': [ # http://crbug.com/98304
243 'third_party/lcov/contrib/galaxy/genflat.pl': [
246 'third_party/lcov-1.9/contrib/galaxy/genflat.pl': [
249 'third_party/libevent': [ # http://crbug.com/98309
252 'third_party/libjingle/source/talk': [ # http://crbug.com/98310
255 'third_party/libjingle/source_internal/talk': [ # http://crbug.com/98310
258 'third_party/libjpeg': [ # http://crbug.com/98313
261 'third_party/libjpeg_turbo': [ # http://crbug.com/98314
264 'third_party/libpng': [ # http://crbug.com/98318
268 # The following files lack license headers, but are trivial.
269 'third_party/libusb/src/libusb/os/poll_posix.h': [
272 'third_party/libusb/src/libusb/version.h': [
275 'third_party/libusb/src/autogen.sh': [
278 'third_party/libusb/src/config.h': [
281 'third_party/libusb/src/msvc/config.h': [
285 'third_party/libvpx/source': [ # http://crbug.com/98319
288 'third_party/libvpx/source/libvpx/examples/includes': [
291 'third_party/libwebp': [ # http://crbug.com/98448
294 'third_party/libxml': [
297 'third_party/libxslt': [
300 'third_party/lzma_sdk': [
303 'third_party/mesa/MesaLib': [
306 'MIT/X11 (BSD like) GPL (v3 or later) with Bison parser exception',
307 'UNKNOWN', # http://crbug.com/98450
309 'third_party/modp_b64': [
312 'third_party/npapi/npspy/extern/java': [
313 'GPL (unversioned/unknown version)',
315 'third_party/openmax_dl/dl' : [
318 'third_party/openssl': [ # http://crbug.com/98451
321 'third_party/ots/tools/ttf-checksum.py': [ # http://code.google.com/p/ots/issues/detail?id=2
324 'third_party/molokocacao': [ # http://crbug.com/98453
327 'third_party/npapi/npspy': [
330 'third_party/ocmock/OCMock': [ # http://crbug.com/98454
333 'third_party/ply/__init__.py': [
336 'third_party/protobuf': [ # http://crbug.com/98455
340 # http://crbug.com/222831
341 # https://bitbucket.org/eliben/pyelftools/issue/12
342 'third_party/pyelftools': [
346 'third_party/pylib': [
349 'third_party/scons-2.0.1/engine/SCons': [ # http://crbug.com/98462
352 'third_party/simplejson': [
355 'third_party/skia': [ # http://crbug.com/98463
358 'third_party/snappy/src': [ # http://crbug.com/98464
361 'third_party/smhasher/src': [ # http://crbug.com/98465
364 'third_party/sqlite': [
367 'third_party/swig/Lib/linkruntime.c': [ # http://crbug.com/98585
370 'third_party/talloc': [
372 'UNKNOWN', # http://crbug.com/98588
374 'third_party/tcmalloc': [
375 'UNKNOWN', # http://crbug.com/98589
377 'third_party/tlslite': [
380 'third_party/webdriver': [ # http://crbug.com/98590
383 'third_party/webrtc': [ # http://crbug.com/98592
386 'third_party/xdg-utils': [ # http://crbug.com/98593
389 'third_party/yasm/source': [ # http://crbug.com/98594
392 'third_party/zlib/contrib/minizip': [
395 'third_party/zlib/trees.h': [
398 'tools/dromaeo_benchmark_runner/dromaeo_benchmark_runner.py': [
401 'tools/emacs': [ # http://crbug.com/98595
404 'tools/grit/grit/node/custom/__init__.py': [
410 'tools/histograms': [
413 'tools/memory_watcher': [
416 'tools/playback_benchmark': [
419 'tools/python/google/__init__.py': [
422 'tools/site_compare': [
425 'tools/stats_viewer/Properties/AssemblyInfo.cs': [
428 'tools/symsrc/pefile.py': [
431 'v8/test/cctest': [ # http://crbug.com/98597
434 'webkit/data/ico_decoder': [
440 def check_licenses(options
, args
):
441 # Figure out which directory we have to check.
443 # No directory to check specified, use the repository root.
444 start_dir
= options
.base_directory
446 # Directory specified. Start here. It's supposed to be relative to the
448 start_dir
= os
.path
.abspath(os
.path
.join(options
.base_directory
, args
[0]))
450 # More than one argument, we don't handle this.
454 print "Using base directory:", options
.base_directory
455 print "Checking:", start_dir
458 licensecheck_path
= os
.path
.abspath(os
.path
.join(options
.base_directory
,
463 licensecheck
= subprocess
.Popen([licensecheck_path
,
466 stdout
=subprocess
.PIPE
,
467 stderr
=subprocess
.PIPE
)
468 stdout
, stderr
= licensecheck
.communicate()
470 print '----------- licensecheck stdout -----------'
472 print '--------- end licensecheck stdout ---------'
473 if licensecheck
.returncode
!= 0 or stderr
:
474 print '----------- licensecheck stderr -----------'
476 print '--------- end licensecheck stderr ---------'
481 for line
in stdout
.splitlines():
482 filename
, license
= line
.split(':', 1)
483 filename
= os
.path
.relpath(filename
.strip(), options
.base_directory
)
485 # All files in the build output directory are generated one way or another.
486 # There's no need to check them.
487 if filename
.startswith('out/') or filename
.startswith('sconsbuild/'):
490 # For now we're just interested in the license.
491 license
= license
.replace('*No copyright*', '').strip()
493 # Skip generated files.
494 if 'GENERATED FILE' in license
:
497 if license
in WHITELISTED_LICENSES
:
500 if not options
.ignore_suppressions
:
501 found_path_specific
= False
502 for prefix
in PATH_SPECIFIC_WHITELISTED_LICENSES
:
503 if (filename
.startswith(prefix
) and
504 license
in PATH_SPECIFIC_WHITELISTED_LICENSES
[prefix
]):
505 found_path_specific
= True
507 if found_path_specific
:
510 print "'%s' has non-whitelisted license '%s'" % (filename
, license
)
519 print "http://www.chromium.org/developers/adding-3rd-party-libraries"
520 print "for more info how to handle the failure."
522 print "Please respect OWNERS of checklicenses.py. Changes violating"
523 print "this requirement may be reverted."
528 default_root
= os
.path
.abspath(
529 os
.path
.join(os
.path
.dirname(__file__
), '..', '..'))
530 option_parser
= optparse
.OptionParser()
531 option_parser
.add_option('--root', default
=default_root
,
532 dest
='base_directory',
533 help='Specifies the repository root. This defaults '
534 'to "../.." relative to the script file, which '
535 'will normally be the repository root.')
536 option_parser
.add_option('-v', '--verbose', action
='store_true',
537 default
=False, help='Print debug logging')
538 option_parser
.add_option('--ignore-suppressions',
541 help='Ignore path-specific license whitelist.')
542 options
, args
= option_parser
.parse_args()
543 return check_licenses(options
, args
)
546 if '__main__' == __name__
: