Files
brave-core/script/check_chromium_src.py
T
Mario Sanchez Prada 5c7b656061 Make EXCLUDES regexp list work on non-UNIX-like shells (e.g. Windows)
To make this work well on shells like Windows' cmd.exe or PowerShell,
we add an intermediate step before matching the paths for files found
in the repository against the regular expresisons declared in EXCLUDES,
so that we use forward slashes instead of backward slashes, which will
cause errors due to the regexp interpreting paths like C:\\mypath as if
they contained the escaped '\m' character.

Once the regular expression has been used though, we still append the
unnormalized OS-dependant relative path to the list of paths built by
filter_chromium_src_filepaths(), so that further operations over those
files can be performed correctly, and so that any path printed in the
output will use the OS-dependant path separator.
2021-03-10 10:41:58 +01:00

225 lines
8.9 KiB
Python

#!/usr/bin/env python3
#
# Copyright (c) 2021 The Brave Authors. All rights reserved.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/. */
#
# This script looks for problems in chromium_src.
#
# 1. Look for files in chromium_src that don't have a corresponding
# file under src tree (or grit).
#
# 2. Look for #defines that redefine symbols that aren't present in
# the overriden file.
#
# 3. Look for #include statements of the overriden file that have
# incorrect number of ../ in the path.
#
# !!! This script does return false positives, but better check a
# !!! few of those than not check at all.
import argparse
import re
import os
import sys
"""
Look for potential problems in chromium_src overrides.
"""
BRAVE_SRC = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
BRAVE_CHROMIUM_SRC = os.path.join(BRAVE_SRC, 'chromium_src')
CHROMIUM_SRC = os.path.abspath(os.path.dirname(BRAVE_SRC))
EXCLUDES = [
'CPPLINT.cfg',
'_(unit|browser)test(_mac)?.cc',
'third_party/blink/renderer/modules/battery/navigator_batterytest.cc',
'third_party/blink/renderer/modules/bluetooth/navigator_bluetoothtest.cc',
'third_party/blink/renderer/modules/quota/navigator_storagetest.cc',
'third_party/blink/renderer/modules/storage/brave_dom_window_storage.h',
'chrome/installer/linux/common/brave-browser/chromium-browser.appdata.xml',
'chrome/installer/linux/common/brave-browser/chromium-browser.info',
]
def do_check_includes(override_filepath):
"""
Checks if |override_filepath| uses the correct number of ".." in the
include statement for the original file.
"""
with open(override_filepath, mode='r', encoding='utf-8') as override_file:
override_filename = os.path.basename(override_filepath)
override_dirpath = os.path.dirname(override_filepath)
# Calculate the expected number of parent dirs.
# -1 for the dir where the file is.
# +3 to get to chromium_src->brave->src.
expected_count = len(override_dirpath.split(os.path.sep)) - 1 + 3
# Check relative includes go up the expected amount of steps.
for line in override_file:
# We're only interested in include paths for parent directories.
regexp = r'^#include "(\.\./.*{})"'.format(override_filename)
line_match = re.search(regexp, line)
if not line_match:
continue
# Count the number of '../' elements, but don't use the OS's path
# separator here, since we're counting paths from a C++ include.
include_path = line_match.group(1)
actual_count = include_path.split('/').count('..')
# Check actual vs expected.
if actual_count != expected_count:
print("ERROR: while processing {}".format(override_filepath))
# Sanity check
saved_cwd = os.getcwd()
os.chdir(override_dirpath)
if not os.path.isfile(include_path):
print(" File {} doesn't exist".format(include_path))
os.chdir(saved_cwd)
print(" Expected {} \"..\"".format(expected_count))
print(" Found {} \"..\"".format(actual_count))
print("-------------------------")
def do_check_defines(override_filepath, original_filepath):
"""
Finds `#define TARGET REPLACEMENT` statements in |override_filepath| and
attempts to find the <TARGET> in the |original_filepath|.
"""
with open(override_filepath, mode='r', encoding='utf-8') as override_file:
for line in override_file:
line_match = re.search(r'^#define\s*(\S*)\s*(\S*)', line)
if not line_match:
continue
target = line_match.group(1)
replacement = line_match.group(2)
if not replacement:
continue
# Adjust target name for BUILDFLAG_INTERNAL_*() cases.
if target.startswith('BUILDFLAG_INTERNAL_'):
buildflag_match = re.search(r'BUILDFLAG_INTERNAL_(\S*)\(\)',
target)
target = buildflag_match.group(1)
# Report ERROR if target can't be found in the original file.
with open(original_filepath, mode='r', encoding='utf-8') as original_file:
if target not in original_file.read():
print("ERROR: Unable to find symbol {} in {}"
.format(target, original_filepath))
print("-------------------------")
def do_check_overrides(overrides_list, search_dir, check_includes=False):
"""
Checks that each path in the passed in list |overrides_list| exists in
the passed in directory (|search_dir|), optionally checking includes too.
"""
print("--------------------------------------------------")
print("Checking overrides in {} ...".format(search_dir))
print("--------------------------------------------------")
for override_filepath in overrides_list:
original_filepath = os.path.join(search_dir, override_filepath)
if not os.path.isfile(original_filepath):
print("WARNING: No source for override {}"
.format(override_filepath))
print("-------------------------")
continue
do_check_defines(override_filepath, original_filepath)
if check_includes:
do_check_includes(override_filepath)
def get_generated_builddir(build, target_os=None, target_arch=None):
"""
Returns the path to the generated build directory for a |build|, accounting
for the optional |target_os| and |target_arch| parameters, if present.
"""
build_dirname = '_'.join(filter(None,
[target_os, build, target_arch]))
return os.path.join(CHROMIUM_SRC, 'out', build_dirname, 'gen')
def filter_chromium_src_filepaths(include_regexp=None, exclude_regexp=None):
"""
Return a list of paths pointing to the files in |BRAVE_CHROMIUM_SRC|
after filtering the results according to the |include_regexp| and the
|exclude_regexp| regexp rules, where |include_regexp| takes precedence
over |exclude_regexp|.
"""
result = []
if not include_regexp and not exclude_regexp:
return result
for dir_path, _dirnames, filenames in os.walk(BRAVE_CHROMIUM_SRC):
for filename in filenames:
full_path = os.path.join(dir_path, filename)
# Strip the BRAVE_CHROMIUM_SRC prefix to match against the
# list of relative paths to be included and/or excluded
relative_path = full_path.replace(BRAVE_CHROMIUM_SRC, '')[1:]
# Normalize back slashes to forward slashes just in case we're in
# Windows before trying to match them against a regular expression.
normalized_path = relative_path.replace('\\', '/')
if include_regexp and not re.search(include_regexp, normalized_path):
continue
if exclude_regexp and re.search(exclude_regexp, normalized_path):
continue
# Append the OS-dependant relative path instead of the normalized
# one as that's what functions using this list of paths expect.
result.append(relative_path)
return result
def main(args):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('build',
help='Build type (i.e. Component|Static|Debug|Release)',
nargs='?',
default='Component')
parser.add_argument('--os',
required=False,
help='Target OS (e.g. android|win|linux|mac|ios)')
parser.add_argument('--arch',
required=False,
help='Target architecture (e.g. x86|x64|arm|arm64)')
options = parser.parse_args(args)
gen_buildir = get_generated_builddir(options.build,
options.os,
options.arch)
# Check that the required directories exist.
for dir in [BRAVE_SRC, gen_buildir]:
if not os.path.isdir(dir):
print("ERROR: {} is not a valid directory.".format(dir))
return 1
# Change into the chromium_src directory for convenience.
os.chdir(BRAVE_CHROMIUM_SRC)
# Check non-GRIT overrides.
src_overrides = filter_chromium_src_filepaths(
exclude_regexp='|'.join(EXCLUDES + ['python_modules|.*grit.*']))
do_check_overrides(src_overrides, CHROMIUM_SRC, True)
# Check GRIT overrides.
grit_overrides = filter_chromium_src_filepaths(include_regexp='.*grit.*')
do_check_overrides(grit_overrides, gen_buildir, False)
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))