summaryrefslogtreecommitdiffstats
path: root/chromium/tools/checkdeps/builddeps.py
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/tools/checkdeps/builddeps.py')
-rwxr-xr-xchromium/tools/checkdeps/builddeps.py348
1 files changed, 0 insertions, 348 deletions
diff --git a/chromium/tools/checkdeps/builddeps.py b/chromium/tools/checkdeps/builddeps.py
deleted file mode 100755
index 5fa37934cbb..00000000000
--- a/chromium/tools/checkdeps/builddeps.py
+++ /dev/null
@@ -1,348 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 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.
-
-"""Traverses the source tree, parses all found DEPS files, and constructs
-a dependency rule table to be used by subclasses.
-
-The format of the deps file:
-
-First you have the normal module-level deps. These are the ones used by
-gclient. An example would be:
-
- deps = {
- "base":"http://foo.bar/trunk/base"
- }
-
-DEPS files not in the top-level of a module won't need this. Then you
-have any additional include rules. You can add (using "+") or subtract
-(using "-") from the previously specified rules (including
-module-level deps). You can also specify a path that is allowed for
-now but that we intend to remove, using "!"; this is treated the same
-as "+" when check_deps is run by our bots, but a presubmit step will
-show a warning if you add a new include of a file that is only allowed
-by "!".
-
-Note that for .java files, there is currently no difference between
-"+" and "!", even in the presubmit step.
-
- include_rules = [
- # Code should be able to use base (it's specified in the module-level
- # deps above), but nothing in "base/evil" because it's evil.
- "-base/evil",
-
- # But this one subdirectory of evil is OK.
- "+base/evil/not",
-
- # And it can include files from this other directory even though there is
- # no deps rule for it.
- "+tools/crime_fighter",
-
- # This dependency is allowed for now but work is ongoing to remove it,
- # so you shouldn't add further dependencies on it.
- "!base/evil/ok_for_now.h",
- ]
-
-If you have certain include rules that should only be applied for some
-files within this directory and subdirectories, you can write a
-section named specific_include_rules that is a hash map of regular
-expressions to the list of rules that should apply to files matching
-them. Note that such rules will always be applied before the rules
-from 'include_rules' have been applied, but the order in which rules
-associated with different regular expressions is applied is arbitrary.
-
- specific_include_rules = {
- ".*_(unit|browser|api)test\.cc": [
- "+libraries/testsupport",
- ],
- }
-
-DEPS files may be placed anywhere in the tree. Each one applies to all
-subdirectories, where there may be more DEPS files that provide additions or
-subtractions for their own sub-trees.
-
-There is an implicit rule for the current directory (where the DEPS file lives)
-and all of its subdirectories. This prevents you from having to explicitly
-allow the current directory everywhere. This implicit rule is applied first,
-so you can modify or remove it using the normal include rules.
-
-The rules are processed in order. This means you can explicitly allow a higher
-directory and then take away permissions from sub-parts, or the reverse.
-
-Note that all directory separators must be slashes (Unix-style) and not
-backslashes. All directories should be relative to the source root and use
-only lowercase.
-"""
-
-import os
-import subprocess
-import copy
-
-from rules import Rule, Rules
-
-
-# Variable name used in the DEPS file to add or subtract include files from
-# the module-level deps.
-INCLUDE_RULES_VAR_NAME = 'include_rules'
-
-# Variable name used in the DEPS file to add or subtract include files
-# from module-level deps specific to files whose basename (last
-# component of path) matches a given regular expression.
-SPECIFIC_INCLUDE_RULES_VAR_NAME = 'specific_include_rules'
-
-# Optionally present in the DEPS file to list subdirectories which should not
-# be checked. This allows us to skip third party code, for example.
-SKIP_SUBDIRS_VAR_NAME = 'skip_child_includes'
-
-
-def NormalizePath(path):
- """Returns a path normalized to how we write DEPS rules and compare paths.
- """
- return path.lower().replace('\\', '/')
-
-
-class DepsBuilder(object):
- """Parses include_rules from DEPS files.
- """
-
- def __init__(self,
- base_directory=None,
- verbose=False,
- being_tested=False,
- ignore_temp_rules=False,
- ignore_specific_rules=False):
- """Creates a new DepsBuilder.
-
- Args:
- base_directory: OS-compatible path to root of checkout, e.g. C:\chr\src.
- verbose: Set to true for debug output.
- being_tested: Set to true to ignore the DEPS file at tools/checkdeps/DEPS.
- ignore_temp_rules: Ignore rules that start with Rule.TEMP_ALLOW ("!").
- """
- self.base_directory = base_directory
- self.verbose = verbose
- self._under_test = being_tested
- self._ignore_temp_rules = ignore_temp_rules
- self._ignore_specific_rules = ignore_specific_rules
-
- if not base_directory:
- self.base_directory = os.path.abspath(
- os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', '..'))
-
- self.git_source_directories = set()
- self._AddGitSourceDirectories()
-
- # Map of normalized directory paths to rules to use for those
- # directories, or None for directories that should be skipped.
- self.directory_rules = {}
- self._ApplyDirectoryRulesAndSkipSubdirs(Rules(), self.base_directory)
-
- def _ApplyRules(self, existing_rules, includes, specific_includes, cur_dir):
- """Applies the given include rules, returning the new rules.
-
- Args:
- existing_rules: A set of existing rules that will be combined.
- include: The list of rules from the "include_rules" section of DEPS.
- specific_includes: E.g. {'.*_unittest\.cc': ['+foo', '-blat']} rules
- from the "specific_include_rules" section of DEPS.
- cur_dir: The current directory, normalized path. We will create an
- implicit rule that allows inclusion from this directory.
-
- Returns: A new set of rules combining the existing_rules with the other
- arguments.
- """
- rules = copy.deepcopy(existing_rules)
-
- # First apply the implicit "allow" rule for the current directory.
- if cur_dir.startswith(
- NormalizePath(os.path.normpath(self.base_directory))):
- relative_dir = cur_dir[len(self.base_directory) + 1:]
-
- source = relative_dir
- if len(source) == 0:
- source = 'top level' # Make the help string a little more meaningful.
- rules.AddRule('+' + relative_dir,
- relative_dir,
- 'Default rule for ' + source)
- else:
- raise Exception('Internal error: base directory is not at the beginning' +
- ' for\n %s and base dir\n %s' %
- (cur_dir, self.base_directory))
-
- def ApplyOneRule(rule_str, cur_dir, dependee_regexp=None):
- """Deduces a sensible description for the rule being added, and
- adds the rule with its description to |rules|.
-
- If we are ignoring temporary rules, this function does nothing
- for rules beginning with the Rule.TEMP_ALLOW character.
- """
- if self._ignore_temp_rules and rule_str.startswith(Rule.TEMP_ALLOW):
- return
-
- rule_block_name = 'include_rules'
- if dependee_regexp:
- rule_block_name = 'specific_include_rules'
- if not relative_dir:
- rule_description = 'the top level %s' % rule_block_name
- else:
- rule_description = relative_dir + "'s %s" % rule_block_name
- rules.AddRule(rule_str, relative_dir, rule_description, dependee_regexp)
-
- # Apply the additional explicit rules.
- for (_, rule_str) in enumerate(includes):
- ApplyOneRule(rule_str, cur_dir)
-
- # Finally, apply the specific rules.
- if not self._ignore_specific_rules:
- for regexp, specific_rules in specific_includes.iteritems():
- for rule_str in specific_rules:
- ApplyOneRule(rule_str, cur_dir, regexp)
-
- return rules
-
- def _ApplyDirectoryRules(self, existing_rules, dir_name):
- """Combines rules from the existing rules and the new directory.
-
- Any directory can contain a DEPS file. Toplevel DEPS files can contain
- module dependencies which are used by gclient. We use these, along with
- additional include rules and implicit rules for the given directory, to
- come up with a combined set of rules to apply for the directory.
-
- Args:
- existing_rules: The rules for the parent directory. We'll add-on to these.
- dir_name: The directory name that the deps file may live in (if
- it exists). This will also be used to generate the
- implicit rules. This is a non-normalized path.
-
- Returns: A tuple containing: (1) the combined set of rules to apply to the
- sub-tree, and (2) a list of all subdirectories that should NOT be
- checked, as specified in the DEPS file (if any).
- """
- norm_dir_name = NormalizePath(dir_name)
-
- # Check for a .svn directory in this directory or check this directory is
- # contained in git source direcotries. This will tell us if it's a source
- # directory and should be checked.
- if not (os.path.exists(os.path.join(dir_name, ".svn")) or
- (norm_dir_name in self.git_source_directories)):
- return (None, [])
-
- # Check the DEPS file in this directory.
- if self.verbose:
- print 'Applying rules from', dir_name
- def FromImpl(_unused, _unused2):
- pass # NOP function so "From" doesn't fail.
-
- def FileImpl(_unused):
- pass # NOP function so "File" doesn't fail.
-
- class _VarImpl:
- def __init__(self, local_scope):
- self._local_scope = local_scope
-
- def Lookup(self, var_name):
- """Implements the Var syntax."""
- if var_name in self._local_scope.get('vars', {}):
- return self._local_scope['vars'][var_name]
- raise Exception('Var is not defined: %s' % var_name)
-
- local_scope = {}
- global_scope = {
- 'File': FileImpl,
- 'From': FromImpl,
- 'Var': _VarImpl(local_scope).Lookup,
- }
- deps_file = os.path.join(dir_name, 'DEPS')
-
- # The second conditional here is to disregard the
- # tools/checkdeps/DEPS file while running tests. This DEPS file
- # has a skip_child_includes for 'testdata' which is necessary for
- # running production tests, since there are intentional DEPS
- # violations under the testdata directory. On the other hand when
- # running tests, we absolutely need to verify the contents of that
- # directory to trigger those intended violations and see that they
- # are handled correctly.
- if os.path.isfile(deps_file) and (
- not self._under_test or not os.path.split(dir_name)[1] == 'checkdeps'):
- execfile(deps_file, global_scope, local_scope)
- elif self.verbose:
- print ' No deps file found in', dir_name
-
- # Even if a DEPS file does not exist we still invoke ApplyRules
- # to apply the implicit "allow" rule for the current directory
- include_rules = local_scope.get(INCLUDE_RULES_VAR_NAME, [])
- specific_include_rules = local_scope.get(SPECIFIC_INCLUDE_RULES_VAR_NAME,
- {})
- skip_subdirs = local_scope.get(SKIP_SUBDIRS_VAR_NAME, [])
-
- return (self._ApplyRules(existing_rules, include_rules,
- specific_include_rules, norm_dir_name),
- skip_subdirs)
-
- def _ApplyDirectoryRulesAndSkipSubdirs(self, parent_rules, dir_path):
- """Given |parent_rules| and a subdirectory |dir_path| from the
- directory that owns the |parent_rules|, add |dir_path|'s rules to
- |self.directory_rules|, and add None entries for any of its
- subdirectories that should be skipped.
- """
- directory_rules, excluded_subdirs = self._ApplyDirectoryRules(parent_rules,
- dir_path)
- self.directory_rules[NormalizePath(dir_path)] = directory_rules
- for subdir in excluded_subdirs:
- self.directory_rules[NormalizePath(
- os.path.normpath(os.path.join(dir_path, subdir)))] = None
-
- def GetDirectoryRules(self, dir_path):
- """Returns a Rules object to use for the given directory, or None
- if the given directory should be skipped. This takes care of
- first building rules for parent directories (up to
- self.base_directory) if needed.
-
- Args:
- dir_path: A real (non-normalized) path to the directory you want
- rules for.
- """
- norm_dir_path = NormalizePath(dir_path)
-
- if not norm_dir_path.startswith(
- NormalizePath(os.path.normpath(self.base_directory))):
- dir_path = os.path.join(self.base_directory, dir_path)
- norm_dir_path = NormalizePath(dir_path)
-
- parent_dir = os.path.dirname(dir_path)
- parent_rules = None
- if not norm_dir_path in self.directory_rules:
- parent_rules = self.GetDirectoryRules(parent_dir)
-
- # We need to check for an entry for our dir_path again, in case we
- # are at a path e.g. A/B/C where A/B/DEPS specifies the C
- # subdirectory to be skipped; in this case, the invocation to
- # GetDirectoryRules(parent_dir) has already filled in an entry for
- # A/B/C.
- if not norm_dir_path in self.directory_rules:
- if not parent_rules:
- # If the parent directory should be skipped, then the current
- # directory should also be skipped.
- self.directory_rules[norm_dir_path] = None
- else:
- self._ApplyDirectoryRulesAndSkipSubdirs(parent_rules, dir_path)
- return self.directory_rules[norm_dir_path]
-
- def _AddGitSourceDirectories(self):
- """Adds any directories containing sources managed by git to
- self.git_source_directories.
- """
- if not os.path.exists(os.path.join(self.base_directory, '.git')):
- return
-
- popen_out = os.popen('cd %s && git ls-files --full-name .' %
- subprocess.list2cmdline([self.base_directory]))
- for line in popen_out.readlines():
- dir_name = os.path.join(self.base_directory, os.path.dirname(line))
- # Add the directory as well as all the parent directories. Use
- # forward slashes and lower case to normalize paths.
- while dir_name != self.base_directory:
- self.git_source_directories.add(NormalizePath(dir_name))
- dir_name = os.path.dirname(dir_name)
- self.git_source_directories.add(NormalizePath(self.base_directory))