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': [
156 # http://crbug.com/98107
157 'ppapi/c/documentation/check.sh': [
160 'ppapi/cpp/documentation/check.sh': [
163 'ppapi/lib/gl/include': [
166 'ppapi/native_client/tests/earth/earth_image.inc': [
170 'third_party/WebKit': [
173 'third_party/WebKit/Websites/webkit.org/blog/wp-content/plugins/'
174 'akismet/akismet.php': [
177 'third_party/WebKit/Source/JavaScriptCore/tests/mozilla': [
180 'GPL (unversioned/unknown version)',
182 'third_party/active_doc': [ # http://crbug.com/98113
186 # http://code.google.com/p/angleproject/issues/detail?id=217
187 'third_party/angle': [
191 'third_party/bsdiff/mbsdiff.cc': [
194 'third_party/bzip2': [
197 'third_party/cld/encodings/compact_lang_det': [ # http://crbug.com/98120
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': [
205 # Included in the source tree but not built. http://crbug.com/156020
206 'third_party/cros_dbus_cplusplus/source/examples': [
209 'third_party/devscripts': [
212 'third_party/expat/files/lib': [ # http://crbug.com/98121
215 'third_party/ffmpeg': [
219 'UNKNOWN', # http://crbug.com/98123
221 'third_party/findbugs/doc': [ # http://crbug.com/157206
224 'third_party/gles2_book': [ # http://crbug.com/98130
227 'third_party/gles2_conform/GTF_ES': [ # http://crbug.com/98131
230 'third_party/harfbuzz': [ # http://crbug.com/98133
233 'third_party/hunspell': [ # http://crbug.com/98134
236 'third_party/hyphen/hyphen.tex': [ # http://crbug.com/157375
239 'third_party/iccjpeg': [ # http://crbug.com/98137
242 'third_party/icu': [ # http://crbug.com/98301
245 'third_party/jemalloc': [ # http://crbug.com/98302
248 'third_party/lcov': [ # http://crbug.com/98304
251 'third_party/lcov/contrib/galaxy/genflat.pl': [
254 'third_party/lcov-1.9/contrib/galaxy/genflat.pl': [
257 'third_party/libevent': [ # http://crbug.com/98309
260 'third_party/libjingle/source/talk': [ # http://crbug.com/98310
263 'third_party/libjingle/source_internal/talk': [ # http://crbug.com/98310
266 'third_party/libjpeg': [ # http://crbug.com/98313
269 'third_party/libjpeg_turbo': [ # http://crbug.com/98314
272 'third_party/libpng': [ # http://crbug.com/98318
276 # The following files lack license headers, but are trivial.
277 'third_party/libusb/src/libusb/os/poll_posix.h': [
280 'third_party/libusb/src/libusb/version.h': [
283 'third_party/libusb/src/autogen.sh': [
286 'third_party/libusb/src/config.h': [
289 'third_party/libusb/src/msvc/config.h': [
293 'third_party/libvpx/source': [ # http://crbug.com/98319
296 'third_party/libvpx/source/libvpx/examples/includes': [
299 'third_party/libwebp': [ # http://crbug.com/98448
302 'third_party/libxml': [
305 'third_party/libxslt': [
308 'third_party/lzma_sdk': [
311 'third_party/mesa/MesaLib': [
314 'MIT/X11 (BSD like) GPL (v3 or later) with Bison parser exception',
315 'UNKNOWN', # http://crbug.com/98450
317 'third_party/modp_b64': [
320 'third_party/npapi/npspy/extern/java': [
321 'GPL (unversioned/unknown version)',
323 'third_party/openssl': [ # http://crbug.com/98451
326 'third_party/ots/tools/ttf-checksum.py': [ # http://code.google.com/p/ots/issues/detail?id=2
329 'third_party/molokocacao': [ # http://crbug.com/98453
332 'third_party/npapi/npspy': [
335 'third_party/ocmock/OCMock': [ # http://crbug.com/98454
338 'third_party/opus/src': [ # http://crbug.com/156738
341 'third_party/ply/__init__.py': [
344 'third_party/protobuf': [ # http://crbug.com/98455
347 'third_party/pylib': [
350 'third_party/scons-2.0.1/engine/SCons': [ # http://crbug.com/98462
353 'third_party/simplejson': [
356 'third_party/skia': [ # http://crbug.com/98463
359 'third_party/snappy/src': [ # http://crbug.com/98464
362 'third_party/smhasher/src': [ # http://crbug.com/98465
365 'third_party/sqlite': [
368 'third_party/swig/Lib/linkruntime.c': [ # http://crbug.com/98585
371 'third_party/talloc': [
373 'UNKNOWN', # http://crbug.com/98588
375 'third_party/tcmalloc': [
376 'UNKNOWN', # http://crbug.com/98589
378 'third_party/tlslite': [
381 'third_party/webdriver': [ # http://crbug.com/98590
384 'third_party/webrtc': [ # http://crbug.com/98592
387 'third_party/xdg-utils': [ # http://crbug.com/98593
390 'third_party/yasm/source': [ # http://crbug.com/98594
393 'third_party/zlib/contrib/minizip': [
396 'third_party/zlib/trees.h': [
399 'tools/dromaeo_benchmark_runner/dromaeo_benchmark_runner.py': [
402 'tools/emacs': [ # http://crbug.com/98595
405 'tools/grit/grit/node/custom/__init__.py': [
411 'tools/histograms': [
414 'tools/memory_watcher': [
417 'tools/playback_benchmark': [
420 'tools/python/google/__init__.py': [
423 'tools/site_compare': [
426 'tools/stats_viewer/Properties/AssemblyInfo.cs': [
429 'tools/symsrc/pefile.py': [
432 'v8/test/cctest': [ # http://crbug.com/98597
435 'webkit/data/ico_decoder': [
441 def check_licenses(options
, args
):
442 # Figure out which directory we have to check.
444 # No directory to check specified, use the repository root.
445 start_dir
= options
.base_directory
447 # Directory specified. Start here. It's supposed to be relative to the
449 start_dir
= os
.path
.abspath(os
.path
.join(options
.base_directory
, args
[0]))
451 # More than one argument, we don't handle this.
455 print "Using base directory:", options
.base_directory
456 print "Checking:", start_dir
459 licensecheck_path
= os
.path
.abspath(os
.path
.join(options
.base_directory
,
464 licensecheck
= subprocess
.Popen([licensecheck_path
,
467 stdout
=subprocess
.PIPE
,
468 stderr
=subprocess
.PIPE
)
469 stdout
, stderr
= licensecheck
.communicate()
471 print '----------- licensecheck stdout -----------'
473 print '--------- end licensecheck stdout ---------'
474 if licensecheck
.returncode
!= 0 or stderr
:
475 print '----------- licensecheck stderr -----------'
477 print '--------- end licensecheck stderr ---------'
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/'):
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
:
498 if license
in WHITELISTED_LICENSES
:
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
508 if found_path_specific
:
511 print "'%s' has non-whitelisted license '%s'" % (filename
, license
)
520 print "http://www.chromium.org/developers/adding-3rd-party-libraries"
521 print "for more info how to handle the failure."
523 print "Please respect OWNERS of checklicenses.py. Changes violating"
524 print "this requirement may be reverted."
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',
542 help='Ignore path-specific license whitelist.')
543 options
, args
= option_parser
.parse_args()
544 return check_licenses(options
, args
)
547 if '__main__' == __name__
: