#!/usr/bin/python # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Checks third-party licenses for the purposes of the Android WebView build. The Android tree includes a snapshot of Chromium in order to power the system WebView. This tool checks that all code uses open-source licenses compatible with Android, and that we meet the requirements of those licenses. It can also be used to generate an Android NOTICE file for the third-party code. It makes use of src/tools/licenses.py and the README.chromium files on which it depends. It also makes use of a data file, third_party_files_whitelist.txt, which whitelists indicidual files which contain third-party code but which aren't in a third-party directory with a README.chromium file. """ import optparse import os import re import subprocess import sys import textwrap REPOSITORY_ROOT = os.path.abspath(os.path.join( os.path.dirname(__file__), '..', '..')) sys.path.append(os.path.join(REPOSITORY_ROOT, 'tools')) import licenses import known_issues def GetIncompatibleDirectories(): """Gets a list of third-party directories which use licenses incompatible with Android. This is used by the snapshot tool. Returns: A list of directories. """ whitelist = [ 'Apache( Version)? 2(\.0)?', '(New )?BSD( 3-Clause)?( with advertising clause)?', 'L?GPL ?v?2(\.[01])?( or later)?', 'MIT(/X11)?(-like)?', 'MPL 1\.1 ?/ ?GPL 2(\.0)? ?/ ?LGPL 2\.1', 'MPL 2(\.0)?', 'Microsoft Limited Public License', 'Microsoft Permissive License', 'Public Domain', 'SGI Free Software License B', 'X11', ] regex = '^(%s)$' % '|'.join(whitelist) result = [] for directory in _FindThirdPartyDirs(): if directory in known_issues.KNOWN_ISSUES: result.append(directory) continue try: metadata = licenses.ParseDir(directory, REPOSITORY_ROOT, require_license_file=False) except licenses.LicenseError as e: print 'Got LicenseError while scanning ' + directory raise if metadata.get('License Android Compatible', 'no') == 'yes': continue license = re.split(' [Ll]icenses?$', metadata['License'])[0] tokens = [x.strip() for x in re.split(' and |,', license) if len(x) > 0] for token in tokens: if not re.match(regex, token, re.IGNORECASE): result.append(directory) break return result def _CheckLicenseHeaders(directory_list, whitelisted_files): """Checks that all files which are not in a listed third-party directory, and which do not use the standard Chromium license, are whitelisted. Args: directory_list: The list of directories. whitelisted_files: The whitelist of files. Returns: True if all files with non-standard license headers are whitelisted and the whitelist contains no stale entries, otherwise false. """ # Matches one of ... # - '[Cc]opyright', but not when followed by # ' 20[0-9][0-9] The Chromium Authors.', with optional (c) and date range # - '([Cc]) (19|20)[0-9][0-9]', but not when preceeded by the word copyright, # as this is handled above regex = '[Cc]opyright(?!( \(c\))? 20[0-9][0-9](-20[0-9][0-9])? ' \ 'The Chromium Authors\. All rights reserved\.)' \ '|' \ '(?