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)',
43 'BSD (3 clause) GPL (v2)',
45 'BSD (3 clause) LGPL (v2 or later)',
46 'BSD (3 clause) LGPL (v2.1 or later)',
47 'BSD (3 clause) MIT/X11 (BSD like)',
51 # TODO(phajdan.jr): Make licensecheck not print BSD-like twice.
52 'BSD-like MIT/X11 (BSD like)',
55 'GPL (v2 or later) with Bison parser exception',
56 'GPL (v2 or later) with libtool exception',
57 'GPL (v3 or later) with Bison parser exception',
58 'GPL with Bison parser exception',
66 # TODO(phajdan.jr): Make licensecheck convert that comma to a dot.
67 'LGPL (v2,1 or later)',
69 'LGPL (v2.1 or later)',
70 'MPL (v1.0) LGPL (v2 or later)',
72 'MPL (v1.1) BSD-like',
73 'MPL (v1.1) BSD-like GPL (unversioned/unknown version)',
74 'MPL (v1.1,) BSD (3 clause) GPL (unversioned/unknown version) '
75 'LGPL (v2.1 or later)',
76 'MPL (v1.1) GPL (unversioned/unknown version)',
79 # TODO(phajdan.jr): Make licensecheck not print the comma after 1.1.
80 'MPL (v1.1,) GPL (unversioned/unknown version) LGPL (v2 or later)',
81 'MPL (v1.1,) GPL (unversioned/unknown version) LGPL (v2.1 or later)',
87 'Public domain BSD (3 clause)',
88 'Public domain BSD-like',
89 'Public domain LGPL (v2.1 or later)',
92 'SGI Free Software License B',
93 'University of Illinois/NCSA Open Source License (BSD like)',
97 PATH_SPECIFIC_WHITELISTED_LICENSES
= {
98 'base/hash.cc': [ # http://crbug.com/98100
101 'base/third_party/icu': [ # http://crbug.com/98087
105 # http://code.google.com/p/google-breakpad/issues/detail?id=450
110 'chrome/common/extensions/docs/examples': [ # http://crbug.com/98092
113 'chrome/test/data/gpu/vt': [
116 'chrome/test/data/layout_tests/LayoutTests': [
119 'courgette/third_party/bsdiff_create.cc': [ # http://crbug.com/98095
122 'data/mozilla_js_tests': [
125 'data/page_cycler': [
129 'data/tab_switching': [
132 'googleurl': [ # http://code.google.com/p/google-url/issues/detail?id=15
136 'native_client': [ # http://crbug.com/98099
139 'native_client/toolchain': [
140 'BSD GPL (v2 or later)',
141 'BSD (2 clause) GPL (v2 or later)',
142 'BSD (3 clause) GPL (v2 or later)',
144 'BSL (v1.0) GPL (v3.1)',
146 'GPL (unversioned/unknown version)',
152 'net/tools/spdyshark': [
156 'third_party/WebKit': [
159 'third_party/WebKit/Websites/webkit.org/blog/wp-content/plugins/'
160 'akismet/akismet.php': [
163 'third_party/WebKit/Source/JavaScriptCore/tests/mozilla': [
166 'GPL (unversioned/unknown version)',
168 'third_party/active_doc': [ # http://crbug.com/98113
172 # http://code.google.com/p/angleproject/issues/detail?id=217
173 'third_party/angle': [
177 'third_party/bsdiff/mbsdiff.cc': [
180 'third_party/bzip2': [
184 # http://crbug.com/222828
185 # http://bugs.python.org/issue17514
186 'third_party/chromite/third_party/argparse.py': [
190 # Not used. http://crbug.com/156020
191 # Using third_party/cros_dbus_cplusplus/cros_dbus_cplusplus.gyp instead.
192 'third_party/cros_dbus_cplusplus/source/autogen.sh': [
195 # Included in the source tree but not built. http://crbug.com/156020
196 'third_party/cros_dbus_cplusplus/source/examples': [
199 'third_party/devscripts': [
202 'third_party/expat/files/lib': [ # http://crbug.com/98121
205 'third_party/ffmpeg': [
209 'UNKNOWN', # http://crbug.com/98123
211 'third_party/findbugs/doc': [ # http://crbug.com/157206
214 'third_party/freetype2': [ # http://crbug.com/177319
217 'third_party/gles2_book': [ # http://crbug.com/98130
220 'third_party/gles2_conform/GTF_ES': [ # http://crbug.com/98131
223 'third_party/harfbuzz': [ # http://crbug.com/98133
226 'third_party/hunspell': [ # http://crbug.com/98134
229 'third_party/hyphen/hyphen.tex': [ # http://crbug.com/157375
232 'third_party/iccjpeg': [ # http://crbug.com/98137
235 'third_party/icu': [ # http://crbug.com/98301
238 'third_party/jemalloc': [ # http://crbug.com/98302
241 'third_party/lcov': [ # http://crbug.com/98304
244 'third_party/lcov/contrib/galaxy/genflat.pl': [
247 'third_party/lcov-1.9/contrib/galaxy/genflat.pl': [
250 'third_party/libevent': [ # http://crbug.com/98309
253 'third_party/libjingle/source/talk': [ # http://crbug.com/98310
256 'third_party/libjingle/source_internal/talk': [ # http://crbug.com/98310
259 'third_party/libjpeg': [ # http://crbug.com/98313
262 'third_party/libjpeg_turbo': [ # http://crbug.com/98314
265 'third_party/libpng': [ # http://crbug.com/98318
269 # The following files lack license headers, but are trivial.
270 'third_party/libusb/src/libusb/os/poll_posix.h': [
273 'third_party/libusb/src/libusb/version.h': [
276 'third_party/libusb/src/autogen.sh': [
279 'third_party/libusb/src/config.h': [
282 'third_party/libusb/src/msvc/config.h': [
286 'third_party/libvpx/source': [ # http://crbug.com/98319
289 'third_party/libvpx/source/libvpx/examples/includes': [
292 'third_party/libwebp': [ # http://crbug.com/98448
295 'third_party/libxml': [
298 'third_party/libxslt': [
301 'third_party/lzma_sdk': [
304 'third_party/mesa/MesaLib': [
307 'MIT/X11 (BSD like) GPL (v3 or later) with Bison parser exception',
308 'UNKNOWN', # http://crbug.com/98450
310 'third_party/mesa/src': [
313 'MIT/X11 (BSD like) GPL (v3 or later) with Bison parser exception',
314 'UNKNOWN', # http://crbug.com/98450
316 'third_party/modp_b64': [
319 'third_party/npapi/npspy/extern/java': [
320 'GPL (unversioned/unknown version)',
322 'third_party/openmax_dl/dl' : [
325 'third_party/openssl': [ # http://crbug.com/98451
328 'third_party/ots/tools/ttf-checksum.py': [ # http://code.google.com/p/ots/issues/detail?id=2
331 'third_party/molokocacao': [ # http://crbug.com/98453
334 'third_party/npapi/npspy': [
337 'third_party/ocmock/OCMock': [ # http://crbug.com/98454
340 'third_party/ply/__init__.py': [
343 'third_party/protobuf': [ # http://crbug.com/98455
347 # http://crbug.com/222831
348 # https://bitbucket.org/eliben/pyelftools/issue/12
349 'third_party/pyelftools': [
353 'third_party/pylib': [
356 'third_party/scons-2.0.1/engine/SCons': [ # http://crbug.com/98462
359 'third_party/simplejson': [
362 'third_party/skia': [ # http://crbug.com/98463
365 'third_party/snappy/src': [ # http://crbug.com/98464
368 'third_party/smhasher/src': [ # http://crbug.com/98465
371 'third_party/speech-dispatcher/libspeechd.h': [
374 'third_party/sqlite': [
377 'third_party/swig/Lib/linkruntime.c': [ # http://crbug.com/98585
380 'third_party/talloc': [
382 'UNKNOWN', # http://crbug.com/98588
384 'third_party/tcmalloc': [
385 'UNKNOWN', # http://crbug.com/98589
387 'third_party/tlslite': [
390 'third_party/webdriver': [ # http://crbug.com/98590
393 'third_party/webrtc': [ # http://crbug.com/98592
396 'third_party/xdg-utils': [ # http://crbug.com/98593
399 'third_party/yasm/source': [ # http://crbug.com/98594
402 'third_party/zlib/contrib/minizip': [
405 'third_party/zlib/trees.h': [
408 'tools/dromaeo_benchmark_runner/dromaeo_benchmark_runner.py': [
411 'tools/emacs': [ # http://crbug.com/98595
414 'tools/grit/grit/node/custom/__init__.py': [
420 'tools/histograms': [
423 'tools/memory_watcher': [
426 'tools/playback_benchmark': [
429 'tools/python/google/__init__.py': [
432 'tools/site_compare': [
435 'tools/stats_viewer/Properties/AssemblyInfo.cs': [
438 'tools/symsrc/pefile.py': [
441 'v8/test/cctest': [ # http://crbug.com/98597
444 'webkit/data/ico_decoder': [
450 def check_licenses(options
, args
):
451 # Figure out which directory we have to check.
453 # No directory to check specified, use the repository root.
454 start_dir
= options
.base_directory
456 # Directory specified. Start here. It's supposed to be relative to the
458 start_dir
= os
.path
.abspath(os
.path
.join(options
.base_directory
, args
[0]))
460 # More than one argument, we don't handle this.
464 print "Using base directory:", options
.base_directory
465 print "Checking:", start_dir
468 licensecheck_path
= os
.path
.abspath(os
.path
.join(options
.base_directory
,
473 licensecheck
= subprocess
.Popen([licensecheck_path
,
476 stdout
=subprocess
.PIPE
,
477 stderr
=subprocess
.PIPE
)
478 stdout
, stderr
= licensecheck
.communicate()
480 print '----------- licensecheck stdout -----------'
482 print '--------- end licensecheck stdout ---------'
483 if licensecheck
.returncode
!= 0 or stderr
:
484 print '----------- licensecheck stderr -----------'
486 print '--------- end licensecheck stderr ---------'
491 for line
in stdout
.splitlines():
492 filename
, license
= line
.split(':', 1)
493 filename
= os
.path
.relpath(filename
.strip(), options
.base_directory
)
495 # All files in the build output directory are generated one way or another.
496 # There's no need to check them.
497 if filename
.startswith('out/') or filename
.startswith('sconsbuild/'):
500 # For now we're just interested in the license.
501 license
= license
.replace('*No copyright*', '').strip()
503 # Skip generated files.
504 if 'GENERATED FILE' in license
:
507 if license
in WHITELISTED_LICENSES
:
510 if not options
.ignore_suppressions
:
511 found_path_specific
= False
512 for prefix
in PATH_SPECIFIC_WHITELISTED_LICENSES
:
513 if (filename
.startswith(prefix
) and
514 license
in PATH_SPECIFIC_WHITELISTED_LICENSES
[prefix
]):
515 found_path_specific
= True
517 if found_path_specific
:
520 print "'%s' has non-whitelisted license '%s'" % (filename
, license
)
529 print "http://www.chromium.org/developers/adding-3rd-party-libraries"
530 print "for more info how to handle the failure."
532 print "Please respect OWNERS of checklicenses.py. Changes violating"
533 print "this requirement may be reverted."
538 default_root
= os
.path
.abspath(
539 os
.path
.join(os
.path
.dirname(__file__
), '..', '..'))
540 option_parser
= optparse
.OptionParser()
541 option_parser
.add_option('--root', default
=default_root
,
542 dest
='base_directory',
543 help='Specifies the repository root. This defaults '
544 'to "../.." relative to the script file, which '
545 'will normally be the repository root.')
546 option_parser
.add_option('-v', '--verbose', action
='store_true',
547 default
=False, help='Print debug logging')
548 option_parser
.add_option('--ignore-suppressions',
551 help='Ignore path-specific license whitelist.')
552 options
, args
= option_parser
.parse_args()
553 return check_licenses(options
, args
)
556 if '__main__' == __name__
: