checklicenses.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  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.
  5. """Makes sure that all files contain proper licensing information."""
  6. from __future__ import print_function
  7. import json
  8. import optparse
  9. import os.path
  10. import re
  11. import subprocess
  12. import sys
  13. def PrintUsage():
  14. print("""Usage: python checklicenses.py [--root <root>] [tocheck]
  15. --root Specifies the repository root. This defaults to "../.." relative
  16. to the script file. This will be correct given the normal location
  17. of the script in "<root>/tools/checklicenses".
  18. --ignore-suppressions Ignores path-specific license allowlist. Useful when
  19. trying to remove a suppression/allowlist entry.
  20. tocheck Specifies the directory, relative to root, to check. This defaults
  21. to "." so it checks everything.
  22. Examples:
  23. python checklicenses.py
  24. python checklicenses.py --root ~/chromium/src third_party""")
  25. ALLOWLISTED_LICENSES = [
  26. 'APSL (v2) BSD (4 clause)',
  27. 'APSL (v2)',
  28. 'Anti-Grain Geometry',
  29. 'Apache (v2.0) BSD (2 clause)',
  30. 'Apache (v2.0) BSD-like',
  31. 'Apache (v2.0) GPL (v2)',
  32. 'Apache (v2.0) ISC',
  33. 'Apache (v2.0)',
  34. 'Apple MIT', # https://fedoraproject.org/wiki/Licensing/Apple_MIT_License
  35. 'BSD (2 clause) ISC',
  36. 'BSD (2 clause) MIT/X11 (BSD like)',
  37. 'BSD (2 clause)',
  38. 'BSD (3 clause) GPL (v2)',
  39. 'BSD (3 clause) ISC',
  40. 'BSD (3 clause) LGPL (v2 or later)',
  41. 'BSD (3 clause) LGPL (v2.1 or later)',
  42. 'BSD (3 clause) MIT/X11 (BSD like)',
  43. 'BSD (3 clause)',
  44. 'BSD (4 clause)',
  45. 'BSD',
  46. 'BSD-like',
  47. # TODO(phajdan.jr): Make licensecheck not print BSD-like twice.
  48. 'BSD MIT/X11 (BSD like)',
  49. 'BSD-like MIT/X11 (BSD like)',
  50. 'BSL (v1.0)',
  51. 'BSL (v1) LGPL (v2.1 or later)',
  52. 'FreeType (BSD like) with patent clause',
  53. 'FreeType (BSD like)',
  54. 'GPL (v2 or later) with Bison parser exception',
  55. 'GPL (v2 or later) with libtool exception',
  56. 'GPL (v2) LGPL (v2.1 or later)',
  57. 'GPL (v3 or later) LGPL (v2.1 or later) with Bison parser exception',
  58. 'GPL (v3 or later) with Bison parser exception',
  59. 'GPL with Bison parser exception',
  60. 'ISC',
  61. 'Independent JPEG Group License',
  62. 'LGPL (unversioned/unknown version)',
  63. 'LGPL (v2 or later)',
  64. 'LGPL (v2)',
  65. 'LGPL (v2.1 or later)',
  66. 'LGPL (v2.1)',
  67. 'LGPL (v3 or later)',
  68. 'MIT/X11 (BSD like) LGPL (v2.1 or later)',
  69. 'MIT/X11 (BSD like)',
  70. 'MIT/X11 (BSD like) Public domain MIT/X11 (BSD like)',
  71. 'MPL (v1.0) LGPL (v2 or later)',
  72. 'MPL (v1.1) BSD (3 clause) GPL (v2) LGPL (v2.1 or later)',
  73. 'MPL (v1.1) BSD (3 clause) LGPL (v2.1 or later)',
  74. 'MPL (v1.1) BSD-like GPL (unversioned/unknown version)',
  75. 'MPL (v1.1) BSD-like GPL (v2) LGPL (v2.1 or later)',
  76. 'MPL (v1.1) BSD-like LGPL (v2.1 or later)',
  77. 'MPL (v1.1) BSD-like',
  78. 'MPL (v1.1) GPL (unversioned/unknown version)',
  79. 'MPL (v1.1) GPL (v2) LGPL (v2 or later)',
  80. 'MPL (v1.1) GPL (v2) LGPL (v2.1 or later)',
  81. 'MPL (v1.1) GPL (v2)',
  82. 'MPL (v1.1) LGPL (v2 or later)',
  83. 'MPL (v1.1) LGPL (v2.1 or later)',
  84. 'MPL (v1.1)',
  85. 'MPL (v2.0)',
  86. 'Ms-PL',
  87. 'Public domain BSD (3 clause)',
  88. 'Public domain BSD',
  89. 'Public domain BSD-like',
  90. 'Public domain LGPL (v2.1 or later)',
  91. 'Public domain University of Illinois/NCSA Open Source License (BSD like)',
  92. 'Public domain',
  93. 'SGI Free Software License B',
  94. 'SunSoft (BSD like)',
  95. 'libpng',
  96. 'zlib/libpng',
  97. 'University of Illinois/NCSA Open Source License (BSD like)',
  98. ('University of Illinois/NCSA Open Source License (BSD like) '
  99. 'MIT/X11 (BSD like)'),
  100. ]
  101. PATH_SPECIFIC_ALLOWLISTED_LICENSES = {
  102. 'base/third_party/icu': [ # http://crbug.com/98087
  103. 'UNKNOWN',
  104. ],
  105. 'buildtools/third_party/libc++/trunk/test': [
  106. # http://llvm.org/bugs/show_bug.cgi?id=25980
  107. 'UNKNOWN',
  108. ],
  109. # http://llvm.org/bugs/show_bug.cgi?id=25976
  110. 'buildtools/third_party/libc++/trunk/src/include/atomic_support.h':
  111. ['UNKNOWN'],
  112. 'buildtools/third_party/libc++/trunk/utils/gen_link_script': ['UNKNOWN'],
  113. 'buildtools/third_party/libc++/trunk/utils/not': ['UNKNOWN'],
  114. 'buildtools/third_party/libc++/trunk/utils/sym_check': ['UNKNOWN'],
  115. 'buildtools/third_party/libc++abi/trunk/test': ['UNKNOWN'],
  116. 'chrome/common/extensions/docs/examples': [ # http://crbug.com/98092
  117. 'UNKNOWN',
  118. ],
  119. # This contains files copied from elsewhere from the tree. Since the copied
  120. # directories might have suppressions below (like simplejson), allowlist the
  121. # whole directory. This is also not shipped code.
  122. 'chrome/common/extensions/docs/server2/third_party': [
  123. 'UNKNOWN',
  124. ],
  125. 'native_client': [ # http://crbug.com/98099
  126. 'UNKNOWN',
  127. ],
  128. 'native_client/toolchain': [
  129. 'BSD GPL (v2 or later)',
  130. 'BSD (2 clause) GPL (v2 or later)',
  131. 'BSD (3 clause) GPL (v2 or later)',
  132. 'BSD (4 clause) ISC',
  133. 'BSL (v1.0) GPL',
  134. 'BSL (v1.0) GPL (v3.1)',
  135. 'GPL',
  136. 'GPL (unversioned/unknown version)',
  137. 'GPL (v2)',
  138. 'GPL (v2 or later)',
  139. 'GPL (v3.1)',
  140. 'GPL (v3 or later)',
  141. 'MPL (v1.1) LGPL (unversioned/unknown version)',
  142. ],
  143. # The project is BSD-licensed but the individual files do not have
  144. # consistent license headers. Also, this is just used in a utility
  145. # and not shipped. https://github.com/waylan/Python-Markdown/issues/435
  146. 'third_party/Python-Markdown': [
  147. 'UNKNOWN',
  148. ],
  149. # https://bugs.chromium.org/p/swiftshader/issues/detail?id=1
  150. 'third_party/swiftshader': [
  151. 'UNKNOWN',
  152. ],
  153. # http://code.google.com/p/angleproject/issues/detail?id=217
  154. 'third_party/angle': [
  155. 'UNKNOWN',
  156. ],
  157. 'third_party/blink': [
  158. 'UNKNOWN',
  159. ],
  160. # https://crbug.com/google-breakpad/450
  161. 'third_party/breakpad/breakpad': [
  162. 'UNKNOWN',
  163. ],
  164. # http://crbug.com/603946
  165. # https://github.com/google/oauth2client/issues/331
  166. # Just imports googleapiclient. Chromite is not shipped.
  167. 'third_party/chromite/third_party/apiclient': [
  168. 'UNKNOWN',
  169. ],
  170. # http://crbug.com/603946
  171. # https://github.com/google/google-api-python-client/issues/216
  172. # Apache (v2.0) license. Chromite is not shipped.
  173. 'third_party/chromite/third_party/googleapiclient/channel.py': [
  174. 'UNKNOWN',
  175. ],
  176. # http://crbug.com/222828
  177. # http://bugs.python.org/issue17514
  178. 'third_party/chromite/third_party/argparse.py': [
  179. 'UNKNOWN',
  180. ],
  181. # http://crbug.com/603939
  182. # https://github.com/jcgregorio/httplib2/issues/307
  183. # MIT license. Chromite is not shipped.
  184. 'third_party/chromite/third_party/httplib2': [
  185. 'UNKNOWN',
  186. ],
  187. # http://crbug.com/326117
  188. # https://bitbucket.org/chrisatlee/poster/issue/21
  189. 'third_party/chromite/third_party/poster': [
  190. 'UNKNOWN',
  191. ],
  192. # http://crbug.com/603944
  193. # https://github.com/kennethreitz/requests/issues/1610
  194. # Apache (v2.0) license. Chromite is not shipped
  195. 'third_party/chromite/third_party/requests': [
  196. 'UNKNOWN',
  197. ],
  198. # http://crbug.com/333508
  199. 'buildtools/clang_format/script': [
  200. 'UNKNOWN',
  201. ],
  202. 'third_party/devscripts': [
  203. 'GPL (v2 or later)',
  204. ],
  205. 'third_party/catapult/firefighter/default/tracing/third_party/devscripts': [
  206. 'GPL (v2 or later)',
  207. ],
  208. 'third_party/catapult/tracing/third_party/devscripts': [
  209. 'GPL (v2 or later)',
  210. ],
  211. # https://github.com/shazow/apiclient/issues/8
  212. # MIT license.
  213. 'third_party/catapult/third_party/apiclient': [
  214. 'UNKNOWN',
  215. ],
  216. # https://bugs.launchpad.net/beautifulsoup/+bug/1481316
  217. # MIT license.
  218. 'third_party/catapult/third_party/beautifulsoup': ['UNKNOWN'],
  219. # https://bitbucket.org/ned/coveragepy/issue/313/add-license-file-containing-2-3-or-4
  220. # Apache (v2.0) license, not shipped
  221. 'third_party/catapult/third_party/coverage': ['UNKNOWN'],
  222. # https://code.google.com/p/graphy/issues/detail?id=6
  223. # Apache (v2.0)
  224. 'third_party/catapult/third_party/graphy': [
  225. 'UNKNOWN',
  226. ],
  227. # https://github.com/GoogleCloudPlatform/gsutil/issues/305
  228. ('third_party/catapult/third_party/gsutil/gslib/third_party/'
  229. 'storage_apitools'): [
  230. 'UNKNOWN',
  231. ],
  232. # https://github.com/google/apitools/issues/63
  233. 'third_party/catapult/third_party/gsutil/third_party/apitools': [
  234. 'UNKNOWN',
  235. ],
  236. # https://github.com/boto/boto/issues/3373
  237. 'third_party/catapult/third_party/gsutil/third_party/boto': [
  238. 'UNKNOWN',
  239. ],
  240. # https://bitbucket.org/cmcqueen1975/crcmod/issues/1/please-add-per-file-licenses
  241. # Includes third_party/catapult/third_party/gsutil/third_party/crcmod_osx.
  242. 'third_party/catapult/third_party/gsutil/third_party/crcmod': [
  243. 'UNKNOWN',
  244. ],
  245. # https://github.com/jcgregorio/httplib2/issues/307
  246. 'third_party/catapult/third_party/gsutil/third_party/httplib2': [
  247. 'UNKNOWN',
  248. ],
  249. # https://github.com/google/oauth2client/issues/331
  250. 'third_party/catapult/third_party/gsutil/third_party/oauth2client': [
  251. 'UNKNOWN',
  252. ],
  253. # https://github.com/google/protorpc/issues/14
  254. 'third_party/catapult/third_party/gsutil/third_party/protorpc': [
  255. 'UNKNOWN',
  256. ],
  257. # https://sourceforge.net/p/pyasn1/tickets/4/
  258. # Includes
  259. # third_party/catapult/third_party/gsutil/third_party/pyasn1-modules.
  260. 'third_party/catapult/third_party/gsutil/third_party/pyasn1': [
  261. 'UNKNOWN',
  262. ],
  263. # https://github.com/pnpnpn/retry-decorator/issues/4
  264. 'third_party/catapult/third_party/gsutil/third_party/retry-decorator': [
  265. 'UNKNOWN',
  266. ],
  267. # https://bitbucket.org/sybren/python-rsa/issues/28/please-add-per-file-licenses
  268. 'third_party/catapult/third_party/gsutil/third_party/rsa': [
  269. 'UNKNOWN',
  270. ],
  271. # https://bitbucket.org/gutworth/six/issues/137/please-add-per-file-licenses
  272. # Already fixed upstream. https://crbug.com/573341
  273. 'third_party/catapult/third_party/gsutil/third_party/six': [
  274. 'UNKNOWN',
  275. ],
  276. # https://github.com/html5lib/html5lib-python/issues/125
  277. # MIT license.
  278. 'third_party/catapult/third_party/html5lib-python': [
  279. 'UNKNOWN',
  280. ],
  281. # https://github.com/GoogleCloudPlatform/appengine-mapreduce/issues/71
  282. # Apache (v2.0)
  283. 'third_party/catapult/third_party/mapreduce': [
  284. 'UNKNOWN',
  285. ],
  286. # https://code.google.com/p/webapp-improved/issues/detail?id=103
  287. # Apache (v2.0).
  288. 'third_party/catapult/third_party/webapp2': [
  289. 'UNKNOWN',
  290. ],
  291. # https://github.com/Pylons/webob/issues/211
  292. # MIT license.
  293. 'third_party/catapult/third_party/WebOb': [
  294. 'UNKNOWN',
  295. ],
  296. # https://github.com/Pylons/webtest/issues/141
  297. # MIT license.
  298. 'third_party/catapult/third_party/webtest': [
  299. 'UNKNOWN',
  300. ],
  301. # https://bitbucket.org/ianb/paste/issues/12/add-license-headers-to-source-files
  302. # MIT license.
  303. 'third_party/catapult/third_party/Paste': [
  304. 'UNKNOWN',
  305. ],
  306. 'third_party/expat/files/lib': [ # http://crbug.com/98121
  307. 'UNKNOWN',
  308. ],
  309. 'third_party/ffmpeg': [
  310. 'GPL',
  311. 'GPL (v2)',
  312. 'GPL (v2 or later)',
  313. 'GPL (v3 or later)',
  314. 'UNKNOWN', # http://crbug.com/98123
  315. ],
  316. 'third_party/fontconfig': [
  317. # https://bugs.freedesktop.org/show_bug.cgi?id=73401
  318. 'UNKNOWN',
  319. ],
  320. 'third_party/freetype2': [ # http://crbug.com/177319
  321. 'UNKNOWN',
  322. ],
  323. 'third_party/freetype-android': [ # http://crbug.com/177319
  324. 'UNKNOWN',
  325. ],
  326. 'third_party/grpc': [ # https://github.com/grpc/grpc/issues/6951
  327. 'UNKNOWN',
  328. ],
  329. 'third_party/hunspell': [ # http://crbug.com/98134
  330. 'UNKNOWN',
  331. ],
  332. 'third_party/iccjpeg': [ # http://crbug.com/98137
  333. 'UNKNOWN',
  334. ],
  335. 'third_party/icu': [ # http://crbug.com/98301
  336. 'UNKNOWN',
  337. ],
  338. 'third_party/jmake': [ # Used only at build time.
  339. 'GPL (v2)',
  340. ],
  341. 'third_party/jsoncpp/source': [
  342. # https://github.com/open-source-parsers/jsoncpp/issues/234
  343. 'UNKNOWN',
  344. ],
  345. 'third_party/junit/src': [
  346. # Pulled in via DEPS for Android only.
  347. # Eclipse Public License / not shipped.
  348. # Bug filed but upstream prefers not to fix.
  349. # https://github.com/junit-team/junit/issues/1132
  350. 'UNKNOWN',
  351. ],
  352. 'third_party/lcov': [ # http://crbug.com/98304
  353. 'UNKNOWN',
  354. ],
  355. 'third_party/lcov/contrib/galaxy/genflat.pl': [
  356. 'GPL (v2 or later)',
  357. ],
  358. 'third_party/libevent': [ # http://crbug.com/98309
  359. 'UNKNOWN',
  360. ],
  361. 'third_party/libjpeg_turbo': [ # http://crbug.com/98314
  362. 'UNKNOWN',
  363. ],
  364. # Many liblouis files are mirrored but not used in the NaCl module.
  365. # They are not excluded from the mirror because of lack of infrastructure
  366. # support. Getting license headers added to the files where missing is
  367. # tracked in https://github.com/liblouis/liblouis/issues/22.
  368. 'third_party/liblouis/src': [
  369. 'GPL (v3 or later)',
  370. 'UNKNOWN',
  371. ],
  372. # The following files lack license headers, but are trivial.
  373. 'third_party/libusb/src/libusb/os/poll_posix.h': [
  374. 'UNKNOWN',
  375. ],
  376. 'third_party/libxml': [
  377. 'UNKNOWN',
  378. ],
  379. 'third_party/libxslt': [
  380. 'UNKNOWN',
  381. ],
  382. 'third_party/lzma_sdk': [
  383. 'UNKNOWN',
  384. ],
  385. 'third_party/modp_b64': [
  386. 'UNKNOWN',
  387. ],
  388. 'third_party/nvml': [
  389. 'UNKNOWN',
  390. ],
  391. # Missing license headers in openh264 sources: https://github.com/cisco/openh264/issues/2233
  392. 'third_party/openh264/src': [
  393. 'UNKNOWN',
  394. ],
  395. 'third_party/boringssl': [
  396. # There are some files in BoringSSL which came from OpenSSL and have no
  397. # license in them. We don't wish to add the license header ourselves
  398. # thus we don't expect to pass license checks.
  399. 'UNKNOWN',
  400. ],
  401. 'third_party/molokocacao': [ # http://crbug.com/98453
  402. 'UNKNOWN',
  403. ],
  404. 'third_party/ocmock/OCMock': [ # http://crbug.com/98454
  405. 'UNKNOWN',
  406. ],
  407. 'third_party/protobuf': [ # http://crbug.com/98455
  408. 'UNKNOWN',
  409. ],
  410. # https://bitbucket.org/ned/coveragepy/issue/313/add-license-file-containing-2-3-or-4
  411. # BSD 2-clause license.
  412. 'third_party/pycoverage': [
  413. 'UNKNOWN',
  414. ],
  415. 'third_party/pyelftools': [ # http://crbug.com/222831
  416. 'UNKNOWN',
  417. ],
  418. 'third_party/scons-2.0.1/engine/SCons': [ # http://crbug.com/98462
  419. 'UNKNOWN',
  420. ],
  421. 'third_party/simplejson': [
  422. 'UNKNOWN',
  423. ],
  424. 'third_party/skia': [ # http://crbug.com/98463
  425. 'UNKNOWN',
  426. ],
  427. 'third_party/snappy/src': [ # http://crbug.com/98464
  428. 'UNKNOWN',
  429. ],
  430. 'third_party/smhasher/src': [ # http://crbug.com/98465
  431. 'UNKNOWN',
  432. ],
  433. 'third_party/speech-dispatcher/libspeechd.h': [
  434. 'GPL (v2 or later)',
  435. ],
  436. 'third_party/sqlite': [
  437. 'UNKNOWN',
  438. ],
  439. 'third_party/minizip': [
  440. 'UNKNOWN',
  441. ],
  442. # BSD License. http://bugzilla.maptools.org/show_bug.cgi?id=2532
  443. 'third_party/pdfium/third_party/libtiff/tif_ojpeg.c': [
  444. 'UNKNOWN',
  445. ],
  446. 'third_party/pdfium/third_party/libtiff/tiffvers.h': [
  447. 'UNKNOWN',
  448. ],
  449. 'third_party/pdfium/third_party/libtiff/uvcode.h': [
  450. 'UNKNOWN',
  451. ],
  452. # MIT license but some files contain no licensing info. e.g. autogen.sh.
  453. # Files missing licensing info are not shipped.
  454. 'third_party/wayland': [ # http://crbug.com/553573
  455. 'UNKNOWN',
  456. ],
  457. 'third_party/webdriver': [ # http://crbug.com/98590
  458. 'UNKNOWN',
  459. ],
  460. # https://github.com/html5lib/html5lib-python/issues/125
  461. # https://github.com/KhronosGroup/WebGL/issues/435
  462. 'third_party/webgl/src': [
  463. 'UNKNOWN',
  464. ],
  465. 'third_party/webrtc': [ # http://crbug.com/98592
  466. 'UNKNOWN',
  467. ],
  468. 'third_party/xdg-utils': [ # http://crbug.com/98593
  469. 'UNKNOWN',
  470. ],
  471. 'third_party/yasm/source': [ # http://crbug.com/98594
  472. 'UNKNOWN',
  473. ],
  474. 'third_party/zlib/contrib/minizip': [
  475. 'UNKNOWN',
  476. ],
  477. 'third_party/zlib/trees.h': [
  478. 'UNKNOWN',
  479. ],
  480. 'tools/emacs': [ # http://crbug.com/98595
  481. 'UNKNOWN',
  482. ],
  483. 'tools/gyp/test': [
  484. 'UNKNOWN',
  485. ],
  486. # Perf test data from Google Maps team. Not shipped.
  487. 'tools/perf/page_sets/maps_perf_test': [
  488. 'UNKNOWN',
  489. ],
  490. 'tools/python/google/__init__.py': [
  491. 'UNKNOWN',
  492. ],
  493. 'tools/stats_viewer/Properties/AssemblyInfo.cs': [
  494. 'UNKNOWN',
  495. ],
  496. 'tools/symsrc/pefile.py': [
  497. 'UNKNOWN',
  498. ],
  499. # Not shipped, MIT license but the header files contain no licensing info.
  500. 'third_party/catapult/telemetry/third_party/altgraph': [
  501. 'UNKNOWN',
  502. ],
  503. # Not shipped, MIT license but the header files contain no licensing info.
  504. 'third_party/catapult/telemetry/third_party/modulegraph': [
  505. 'UNKNOWN',
  506. ],
  507. 'third_party/catapult/telemetry/third_party/pyserial': [
  508. # https://sourceforge.net/p/pyserial/feature-requests/35/
  509. 'UNKNOWN',
  510. ],
  511. # Not shipped, GPL license but some header files contain no licensing info.
  512. 'third_party/logilab/logilab/astroid': [
  513. 'GPL (v2 or later)',
  514. # https://github.com/PyCQA/astroid/issues/336
  515. 'UNKNOWN',
  516. ],
  517. # Not shipped, GPL license but some header files contain no licensing info.
  518. 'third_party/logilab/logilab/common': [
  519. 'GPL (v2 or later)',
  520. # Look for email by nednguyen@google.com in May 5th in
  521. # https://lists.logilab.org/pipermail/python-projects/
  522. 'UNKNOWN',
  523. ],
  524. # Not shipped, GPL license but some header files contain no licensing info.
  525. 'third_party/pylint': [
  526. 'GPL (v2 or later)',
  527. # https://github.com/PyCQA/pylint/issues/894
  528. 'UNKNOWN',
  529. ],
  530. }
  531. EXCLUDED_PATHS = [
  532. # Don't check generated files
  533. re.compile('^out/'),
  534. # Don't check downloaded goma client binaries
  535. re.compile('^build/goma/client/'),
  536. # Don't check sysroot directories
  537. re.compile('^build/linux/.+-sysroot/'),
  538. ]
  539. def check_licenses(options, args):
  540. # Figure out which directory we have to check.
  541. if len(args) == 0:
  542. # No directory to check specified, use the repository root.
  543. start_dir = options.base_directory
  544. elif len(args) == 1:
  545. # Directory specified. Start here. It's supposed to be relative to the
  546. # base directory.
  547. start_dir = os.path.abspath(os.path.join(options.base_directory, args[0]))
  548. else:
  549. # More than one argument, we don't handle this.
  550. PrintUsage()
  551. return 1
  552. print("Using base directory:", options.base_directory)
  553. print("Checking:", start_dir)
  554. print()
  555. licensecheck_path = os.path.abspath(os.path.join(options.base_directory,
  556. 'third_party',
  557. 'devscripts',
  558. 'licensecheck.pl'))
  559. licensecheck = subprocess.Popen([licensecheck_path,
  560. '-l', '100',
  561. '-r', start_dir],
  562. stdout=subprocess.PIPE,
  563. stderr=subprocess.PIPE)
  564. stdout, stderr = licensecheck.communicate()
  565. if options.verbose:
  566. print('----------- licensecheck stdout -----------')
  567. print(stdout)
  568. print('--------- end licensecheck stdout ---------')
  569. if licensecheck.returncode != 0 or stderr:
  570. print('----------- licensecheck stderr -----------')
  571. print(stderr)
  572. print('--------- end licensecheck stderr ---------')
  573. print("\nFAILED\n")
  574. return 1
  575. used_suppressions = set()
  576. errors = []
  577. for line in stdout.splitlines():
  578. line = line.decode('utf-8')
  579. filename, license = line.split(':', 1)
  580. filename = os.path.relpath(filename.strip(), options.base_directory)
  581. # Check if the file belongs to one of the excluded paths.
  582. if any((pattern.match(filename) for pattern in EXCLUDED_PATHS)):
  583. continue
  584. # For now we're just interested in the license.
  585. license = license.replace('*No copyright*', '').strip()
  586. # Skip generated files.
  587. if 'GENERATED FILE' in license:
  588. continue
  589. if license in ALLOWLISTED_LICENSES:
  590. continue
  591. if not options.ignore_suppressions:
  592. matched_prefixes = [
  593. prefix for prefix in PATH_SPECIFIC_ALLOWLISTED_LICENSES
  594. if filename.startswith(prefix)
  595. and license in PATH_SPECIFIC_ALLOWLISTED_LICENSES[prefix]
  596. ]
  597. if matched_prefixes:
  598. used_suppressions.update(set(matched_prefixes))
  599. continue
  600. errors.append({'filename': filename, 'license': license})
  601. if options.json:
  602. with open(options.json, 'w') as f:
  603. json.dump(errors, f)
  604. if errors:
  605. for error in errors:
  606. print("'%s' has non-allowlisted license '%s'" %
  607. (error['filename'], error['license']))
  608. print("\nFAILED\n")
  609. print("Please read", end=' ')
  610. print("http://www.chromium.org/developers/adding-3rd-party-libraries")
  611. print("for more info how to handle the failure.")
  612. print()
  613. print("Please respect OWNERS of checklicenses.py. Changes violating")
  614. print("this requirement may be reverted.")
  615. # Do not print unused suppressions so that above message is clearly
  616. # visible and gets proper attention. Too much unrelated output
  617. # would be distracting and make the important points easier to miss.
  618. return 1
  619. print("\nSUCCESS\n")
  620. if not len(args):
  621. unused_suppressions = set(
  622. PATH_SPECIFIC_ALLOWLISTED_LICENSES.iterkeys()).difference(
  623. used_suppressions)
  624. if unused_suppressions:
  625. print("\nNOTE: unused suppressions detected:\n")
  626. print('\n'.join(unused_suppressions))
  627. return 0
  628. def main():
  629. default_root = os.path.abspath(
  630. os.path.join(os.path.dirname(__file__), '..', '..'))
  631. option_parser = optparse.OptionParser()
  632. option_parser.add_option('--root', default=default_root,
  633. dest='base_directory',
  634. help='Specifies the repository root. This defaults '
  635. 'to "../.." relative to the script file, which '
  636. 'will normally be the repository root.')
  637. option_parser.add_option('-v', '--verbose', action='store_true',
  638. default=False, help='Print debug logging')
  639. option_parser.add_option('--ignore-suppressions',
  640. action='store_true',
  641. default=False,
  642. help='Ignore path-specific license allowlist.')
  643. option_parser.add_option('--json', help='Path to JSON output file')
  644. options, args = option_parser.parse_args()
  645. return check_licenses(options, args)
  646. if '__main__' == __name__:
  647. sys.exit(main())