blob: 0e25a32bf15c76a91bdea2ae020871f14369f5ae [file] [log] [blame]
# Copyright (c) 2012 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
import sys
def add_typ_dir_to_sys_path():
path_to_typ = get_typ_dir()
if path_to_typ not in sys.path:
sys.path.append(path_to_typ)
def add_bindings_scripts_dir_to_sys_path():
path_to_bindings_scripts = get_bindings_scripts_dir()
if path_to_bindings_scripts not in sys.path:
sys.path.append(path_to_bindings_scripts)
def get_bindings_scripts_dir():
return os.path.join(get_source_dir(), 'bindings', 'scripts')
def get_blink_dir():
return os.path.dirname(os.path.dirname(get_scripts_dir()))
def get_chromium_src_dir():
return os.path.dirname(os.path.dirname(get_blink_dir()))
def get_scripts_dir():
return os.path.dirname(
os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
def get_source_dir():
return os.path.join(get_blink_dir(), 'Source')
def get_typ_dir():
return os.path.join(get_chromium_src_dir(), 'third_party', 'typ')
def get_webkitpy_thirdparty_dir():
return os.path.join(get_scripts_dir(), 'webkitpy', 'thirdparty')
class WebKitFinder(object):
def __init__(self, filesystem):
self._filesystem = filesystem
self._dirsep = filesystem.sep
self._sys_path = sys.path
self._env_path = os.environ['PATH'].split(os.pathsep)
self._webkit_base = None
self._chromium_base = None
self._depot_tools = None
def webkit_base(self):
"""Returns the absolute path to the top of the WebKit tree.
Raises an AssertionError if the top dir can't be determined.
"""
# Note: This code somewhat duplicates the code in
# git.find_checkout_root(). However, that code only works if the top
# of the SCM repository also matches the top of the WebKit tree. Some SVN users
# (the chromium test bots, for example), might only check out subdirectories like
# Tools/Scripts. This code will also work if there is no SCM system at all.
# TODO(qyearsley): Remove duplicate code; we're not concerned with SVN users anymore.
# Also, instead of caching the result with a private instance variable, we can use
# the memoized decorator.
if not self._webkit_base:
self._webkit_base = self._webkit_base
module_path = self._filesystem.abspath(self._filesystem.path_to_module(self.__module__))
tools_index = module_path.rfind('Tools')
assert tools_index != -1, 'could not find location of this checkout from %s' % module_path
self._webkit_base = self._filesystem.normpath(module_path[0:tools_index - 1])
return self._webkit_base
def chromium_base(self):
if not self._chromium_base:
self._chromium_base = self._filesystem.dirname(self._filesystem.dirname(self.webkit_base()))
return self._chromium_base
def path_from_webkit_base(self, *comps):
return self._filesystem.join(self.webkit_base(), *comps)
def path_from_chromium_base(self, *comps):
return self._filesystem.join(self.chromium_base(), *comps)
def path_to_script(self, script_name):
"""Returns the relative path to the script from the top of the WebKit tree."""
# This is intentionally relative in order to force callers to consider what
# their current working directory is (and change to the top of the tree if necessary).
return self._filesystem.join('Tools', 'Scripts', script_name)
def layout_tests_dir(self):
return self.path_from_webkit_base('LayoutTests')
def perf_tests_dir(self):
return self.path_from_webkit_base('PerformanceTests')
def layout_test_name(self, file_path):
"""Returns a layout test name, given the path from the repo root.
Note: this appears to not work on Windows; see crbug.com/658795.
Also, this function duplicates functionality that's in
Port.relative_test_filename.
TODO(qyearsley): De-duplicate this and Port.relative_test_filename,
and ensure that it works properly with Windows paths.
Args:
file_path: A relative path from the root of the Chromium repo.
Returns:
The normalized layout test name, which is just the relative path from
the LayoutTests directory, using forward slash as the path separator.
Returns None if the given file is not in the LayoutTests directory.
"""
layout_tests_abs_path = self._filesystem.join(self.webkit_base(), self.layout_tests_dir())
layout_tests_rel_path = self._filesystem.relpath(layout_tests_abs_path, self.chromium_base())
if not file_path.startswith(layout_tests_rel_path):
return None
return file_path[len(layout_tests_rel_path) + 1:]
def depot_tools_base(self):
if not self._depot_tools:
# This basically duplicates src/build/find_depot_tools.py without the side effects
# (adding the directory to sys.path and importing breakpad).
self._depot_tools = (self._check_paths_for_depot_tools(self._sys_path) or
self._check_paths_for_depot_tools(self._env_path) or
self._check_upward_for_depot_tools())
return self._depot_tools
def _check_paths_for_depot_tools(self, paths):
for path in paths:
if path.rstrip(self._dirsep).endswith('depot_tools'):
return path
return None
def _check_upward_for_depot_tools(self):
fs = self._filesystem
prev_dir = ''
current_dir = fs.dirname(self._webkit_base)
while current_dir != prev_dir:
if fs.exists(fs.join(current_dir, 'depot_tools', 'pylint.py')):
return fs.join(current_dir, 'depot_tools')
prev_dir = current_dir
current_dir = fs.dirname(current_dir)
def path_from_depot_tools_base(self, *comps):
return self._filesystem.join(self.depot_tools_base(), *comps)