Index: tools/checkdeps/checkdeps.py |
diff --git a/tools/checkdeps/checkdeps.py b/tools/checkdeps/checkdeps.py |
index 9624812086a0d732db98a5a0e5825d4bad09b739..7661d9d04b398dd7f4c0e23e9a745c783007517d 100755 |
--- a/tools/checkdeps/checkdeps.py |
+++ b/tools/checkdeps/checkdeps.py |
@@ -18,9 +18,17 @@ gclient. An example would be: |
"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). |
+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 |
@@ -32,7 +40,11 @@ from the previously specified rules (including module-level deps). |
# And it can include files from this other directory even though there is |
# no deps rule for it. |
- "+tools/crime_fighter" |
+ "+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", |
} |
DEPS files may be placed anywhere in the tree. Each one applies to all |
@@ -54,12 +66,13 @@ only lowercase. |
import os |
import optparse |
-import pipes |
+import subprocess |
import sys |
import copy |
import cpp_checker |
import java_checker |
+from rules import Rule, Rules |
# Variable name used in the DEPS file to add or subtract include files from |
@@ -70,257 +83,296 @@ INCLUDE_RULES_VAR_NAME = "include_rules" |
# be checked. This allows us to skip third party code, for example. |
SKIP_SUBDIRS_VAR_NAME = "skip_child_includes" |
-# Set to true for more output. This is set by the command line options. |
-VERBOSE = False |
-# In lowercase, using forward slashes as directory separators, ending in a |
-# forward slash. Set by the command line options. |
-BASE_DIRECTORY = "" |
+def NormalizePath(path): |
+ """Returns a path normalized to how we write DEPS rules and compare paths. |
+ """ |
+ return path.lower().replace('\\', '/') |
-# The directories which contain the sources managed by git. |
-GIT_SOURCE_DIRECTORY = set() |
+class DepsChecker(object): |
+ """Parses include_rules from DEPS files and can verify files in the |
+ source tree against them. |
+ """ |
-# Specifies a single rule for an include, which can be either allow or disallow. |
-class Rule(object): |
- def __init__(self, allow, directory, source): |
- self.allow = allow |
- self._dir = directory |
- self._source = source |
+ def __init__(self, base_directory=None, verbose=False, being_tested=False): |
+ """Creates a new DepsChecker. |
- def __str__(self): |
- if (self.allow): |
- return '"+%s" from %s.' % (self._dir, self._source) |
- return '"-%s" from %s.' % (self._dir, self._source) |
+ 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. |
+ """ |
+ self.base_directory = base_directory |
+ if not base_directory: |
+ self.base_directory = os.path.abspath( |
+ os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', '..')) |
- def ParentOrMatch(self, other): |
- """Returns true if the input string is an exact match or is a parent |
- of the current rule. For example, the input "foo" would match "foo/bar".""" |
- return self._dir == other or self._dir.startswith(other + "/") |
+ self.verbose = verbose |
- def ChildOrMatch(self, other): |
- """Returns true if the input string would be covered by this rule. For |
- example, the input "foo/bar" would match the rule "foo".""" |
- return self._dir == other or other.startswith(self._dir + "/") |
+ self.git_source_directories = set() |
+ self._AddGitSourceDirectories() |
+ self._under_test = being_tested |
-def ParseRuleString(rule_string, source): |
- """Returns a tuple of a boolean indicating whether the directory is an allow |
- rule, and a string holding the directory name. |
- """ |
- if len(rule_string) < 1: |
- raise Exception('The rule string "%s" is too short\nin %s' % |
- (rule_string, source)) |
+ def _ApplyRules(self, existing_rules, includes, cur_dir): |
+ """Applies the given include rules, returning the new rules. |
- if rule_string[0] == "+": |
- return (True, rule_string[1:]) |
- if rule_string[0] == "-": |
- return (False, rule_string[1:]) |
- raise Exception('The rule string "%s" does not begin with a "+" or a "-"' % |
- rule_string) |
+ Args: |
+ existing_rules: A set of existing rules that will be combined. |
+ include: The list of rules from the "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.copy(existing_rules) |
-class Rules: |
- def __init__(self): |
- """Initializes the current rules with an empty rule list.""" |
- self._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:] |
- def __str__(self): |
- ret = "Rules = [\n" |
- ret += "\n".join([" %s" % x for x in self._rules]) |
- ret += "]\n" |
- return ret |
+ source = relative_dir |
+ if len(source) == 0: |
+ source = "top level" # Make the help string a little more meaningful. |
+ rules.AddRule("+" + 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 AddRule(self, rule_string, source): |
- """Adds a rule for the given rule string. |
+ # Last, apply the additional explicit rules. |
+ for (_, rule_str) in enumerate(includes): |
+ if not relative_dir: |
+ rule_description = "the top level include_rules" |
+ else: |
+ rule_description = relative_dir + "'s include_rules" |
+ rules.AddRule(rule_str, rule_description) |
- Args: |
- rule_string: The include_rule string read from the DEPS file to apply. |
- source: A string representing the location of that string (filename, etc.) |
- so that we can give meaningful errors. |
- """ |
- (add_rule, rule_dir) = ParseRuleString(rule_string, source) |
- # Remove any existing rules or sub-rules that apply. For example, if we're |
- # passed "foo", we should remove "foo", "foo/bar", but not "foobar". |
- self._rules = [x for x in self._rules if not x.ParentOrMatch(rule_dir)] |
- self._rules.insert(0, Rule(add_rule, rule_dir, source)) |
- |
- def DirAllowed(self, allowed_dir): |
- """Returns a tuple (success, message), where success indicates if the given |
- directory is allowed given the current set of rules, and the message tells |
- why if the comparison failed.""" |
- for rule in self._rules: |
- if rule.ChildOrMatch(allowed_dir): |
- # This rule applies. |
- if rule.allow: |
- return (True, "") |
- return (False, rule.__str__()) |
- # No rules apply, fail. |
- return (False, "no rule applying") |
- |
- |
-def ApplyRules(existing_rules, 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. |
- cur_dir: The current directory. 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.copy(existing_rules) |
- |
- # First apply the implicit "allow" rule for the current directory. |
- if cur_dir.lower().startswith(BASE_DIRECTORY): |
- relative_dir = cur_dir[len(BASE_DIRECTORY) + 1:] |
- # Normalize path separators to slashes. |
- relative_dir = relative_dir.replace("\\", "/") |
- source = relative_dir |
- if len(source) == 0: |
- source = "top level" # Make the help string a little more meaningful. |
- rules.AddRule("+" + 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, BASE_DIRECTORY)) |
- |
- # Last, apply the additional explicit rules. |
- for (_, rule_str) in enumerate(includes): |
- if not len(relative_dir): |
- rule_description = "the top level include_rules" |
- else: |
- rule_description = relative_dir + "'s include_rules" |
- rules.AddRule(rule_str, rule_description) |
+ return rules |
- 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. |
-def ApplyDirectoryRules(existing_rules, dir_name): |
- """Combines rules from the existing rules and the new 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, []) |
+ skip_subdirs = local_scope.get(SKIP_SUBDIRS_VAR_NAME, []) |
+ |
+ return (self._ApplyRules(existing_rules, include_rules, norm_dir_name), |
+ skip_subdirs) |
+ |
+ def CheckDirectory(self, start_dir): |
+ """Checks all relevant source files in the specified directory and |
+ its subdirectories for compliance with DEPS rules throughout the |
+ tree (starting at |self.base_directory|). |start_dir| must be a |
+ subdirectory of |self.base_directory|. |
+ |
+ Returns an empty array on success. On failure, the array contains |
+ strings that can be printed as human-readable error messages. |
+ """ |
+ # TODO(joi): Make this work for start_dir != base_dir (I have a |
+ # subsequent change in flight to do this). |
+ base_rules = Rules() |
+ java = java_checker.JavaChecker(self.base_directory, self.verbose) |
+ cpp = cpp_checker.CppChecker(self.verbose) |
+ checkers = dict( |
+ (extension, checker) |
+ for checker in [java, cpp] for extension in checker.EXTENSIONS) |
+ return self._CheckDirectoryImpl(base_rules, checkers, start_dir) |
+ |
+ def _CheckDirectoryImpl(self, parent_rules, checkers, dir_name): |
+ (rules, skip_subdirs) = self._ApplyDirectoryRules(parent_rules, dir_name) |
+ if rules == None: |
+ return [] |
+ |
+ # Collect a list of all files and directories to check. |
+ files_to_check = [] |
+ dirs_to_check = [] |
+ results = [] |
+ contents = os.listdir(dir_name) |
+ for cur in contents: |
+ if cur in skip_subdirs: |
+ continue # Don't check children that DEPS has asked us to skip. |
+ full_name = os.path.join(dir_name, cur) |
+ if os.path.isdir(full_name): |
+ dirs_to_check.append(full_name) |
+ elif os.path.splitext(full_name)[1] in checkers: |
+ files_to_check.append(full_name) |
+ |
+ # First check all files in this directory. |
+ for cur in files_to_check: |
+ checker = checkers[os.path.splitext(cur)[1]] |
+ file_status = checker.CheckFile(rules, cur) |
+ if file_status: |
+ results.append("ERROR in " + cur + "\n" + file_status) |
+ |
+ # Next recurse into the subdirectories. |
+ for cur in dirs_to_check: |
+ results.extend(self._CheckDirectoryImpl(rules, checkers, cur)) |
+ return results |
+ |
+ def CheckAddedCppIncludes(self, added_includes): |
+ """This is used from PRESUBMIT.py to check new #include statements added in |
+ the change being presubmit checked. |
- 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: |
+ added_includes: ((file_path, (include_line, include_line, ...), ...) |
- 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. |
+ Return: |
+ A list of tuples, (bad_file_path, rule_type, rule_description) |
+ where rule_type is one of Rule.DISALLOW or Rule.TEMP_ALLOW and |
+ rule_description is human-readable. Empty if no problems. |
+ """ |
+ # Map of normalized directory paths to rules to use for those |
+ # directories, or None for directories that should be skipped. |
+ directory_rules = {} |
+ |
+ def ApplyDirectoryRulesAndSkipSubdirs(parent_rules, dir_path): |
+ rules_tuple = self._ApplyDirectoryRules(parent_rules, dir_path) |
+ directory_rules[NormalizePath(dir_path)] = rules_tuple[0] |
+ for subdir in rules_tuple[1]: |
+ # We skip this one case for running tests. |
+ directory_rules[NormalizePath( |
+ os.path.normpath(os.path.join(dir_path, subdir)))] = None |
+ |
+ ApplyDirectoryRulesAndSkipSubdirs(Rules(), self.base_directory) |
+ |
+ def GetDirectoryRules(dir_path): |
+ """Returns a Rules object to use for the given directory, or None |
+ if the given directory should be skipped. |
+ """ |
+ norm_dir_path = NormalizePath(dir_path) |
+ |
+ if not 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 directory_rules: |
+ parent_rules = 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 directory_rules: |
+ if not parent_rules: |
+ # If the parent directory should be skipped, then the current |
+ # directory should also be skipped. |
+ directory_rules[norm_dir_path] = None |
+ else: |
+ ApplyDirectoryRulesAndSkipSubdirs(parent_rules, dir_path) |
+ return directory_rules[norm_dir_path] |
+ |
+ cpp = cpp_checker.CppChecker(self.verbose) |
+ |
+ problems = [] |
+ for file_path, include_lines in added_includes: |
+ # TODO(joi): Make this cover Java as well. |
+ if not os.path.splitext(file_path)[1] in cpp.EXTENSIONS: |
+ pass |
+ rules_for_file = GetDirectoryRules(os.path.dirname(file_path)) |
+ if rules_for_file: |
+ for line in include_lines: |
+ is_include, line_status, rule_type = cpp.CheckLine( |
+ rules_for_file, line, True) |
+ if rule_type != Rule.ALLOW: |
+ problems.append((file_path, rule_type, line_status)) |
+ return problems |
+ |
+ 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 |
- 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). |
- """ |
- # 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 |
- (dir_name.lower() in GIT_SOURCE_DIRECTORY)): |
- return (None, []) |
- |
- # Check the DEPS file in this directory. |
- if 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") |
- |
- if os.path.isfile(deps_file): |
- execfile(deps_file, global_scope, local_scope) |
- elif 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, []) |
- skip_subdirs = local_scope.get(SKIP_SUBDIRS_VAR_NAME, []) |
- |
- return (ApplyRules(existing_rules, include_rules, dir_name), skip_subdirs) |
- |
- |
-def CheckDirectory(parent_rules, checkers, dir_name): |
- (rules, skip_subdirs) = ApplyDirectoryRules(parent_rules, dir_name) |
- if rules == None: |
- return True |
- |
- # Collect a list of all files and directories to check. |
- files_to_check = [] |
- dirs_to_check = [] |
- success = True |
- contents = os.listdir(dir_name) |
- for cur in contents: |
- if cur in skip_subdirs: |
- continue # Don't check children that DEPS has asked us to skip. |
- full_name = os.path.join(dir_name, cur) |
- if os.path.isdir(full_name): |
- dirs_to_check.append(full_name) |
- elif os.path.splitext(full_name)[1] in checkers: |
- files_to_check.append(full_name) |
- |
- # First check all files in this directory. |
- for cur in files_to_check: |
- checker = checkers[os.path.splitext(cur)[1]] |
- file_status = checker.CheckFile(rules, cur) |
- if file_status: |
- print "ERROR in " + cur + "\n" + file_status |
- success = False |
- |
- # Next recurse into the subdirectories. |
- for cur in dirs_to_check: |
- if not CheckDirectory(rules, checkers, cur): |
- success = False |
- |
- return success |
- |
- |
-def GetGitSourceDirectory(root): |
- """Returns a set of the directories to be checked. |
- |
- Args: |
- root: The repository root where .git directory exists. |
- |
- Returns: |
- A set of directories which contain sources managed by git. |
- """ |
- git_source_directory = set() |
- popen_out = os.popen("cd %s && git ls-files --full-name ." % |
- pipes.quote(root)) |
- for line in popen_out.readlines(): |
- dir_name = os.path.join(root, os.path.dirname(line)) |
- # Add the directory as well as all the parent directories. |
- while dir_name != root: |
- git_source_directory.add(dir_name) |
- dir_name = os.path.dirname(dir_name) |
- git_source_directory.add(root) |
- return git_source_directory |
+ 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)) |
def PrintUsage(): |
print """Usage: python checkdeps.py [--root <root>] [tocheck] |
+ |
--root Specifies the repository root. This defaults to "../../.." relative |
to the script file. This will be correct given the normal location |
of the script in "<root>/tools/checkdeps". |
@@ -334,73 +386,42 @@ Examples: |
python checkdeps.py --root c:\\source chrome""" |
-def checkdeps(options, args): |
- global VERBOSE |
- if options.verbose: |
- VERBOSE = True |
+def main(): |
+ option_parser = optparse.OptionParser() |
+ option_parser.add_option("", "--root", default="", dest="base_directory", |
+ help='Specifies the repository root. This defaults ' |
+ 'to "../../.." relative to the script file, which ' |
+ 'will normally be the repository root.') |
+ option_parser.add_option("-v", "--verbose", action="store_true", |
+ default=False, help="Print debug logging") |
+ options, args = option_parser.parse_args() |
- # Optional base directory of the repository. |
- global BASE_DIRECTORY |
- if not options.base_directory: |
- BASE_DIRECTORY = os.path.abspath( |
- os.path.join(os.path.abspath(os.path.dirname(__file__)), "../..")) |
- else: |
- BASE_DIRECTORY = os.path.abspath(options.base_directory) |
+ deps_checker = DepsChecker(options.base_directory, options.verbose) |
# Figure out which directory we have to check. |
- if len(args) == 0: |
- # No directory to check specified, use the repository root. |
- start_dir = BASE_DIRECTORY |
- elif len(args) == 1: |
+ start_dir = deps_checker.base_directory |
+ if len(args) == 1: |
# Directory specified. Start here. It's supposed to be relative to the |
# base directory. |
- start_dir = os.path.abspath(os.path.join(BASE_DIRECTORY, args[0])) |
- else: |
+ start_dir = os.path.abspath( |
+ os.path.join(deps_checker.base_directory, args[0])) |
+ elif len(args) >= 2: |
# More than one argument, we don't handle this. |
PrintUsage() |
return 1 |
- print "Using base directory:", BASE_DIRECTORY |
+ print "Using base directory:", deps_checker.base_directory |
print "Checking:", start_dir |
- base_rules = Rules() |
- |
- # The base directory should be lower case from here on since it will be used |
- # for substring matching on the includes, and we compile on case-insensitive |
- # systems. Plus, we always use slashes here since the include parsing code |
- # will also normalize to slashes. |
- BASE_DIRECTORY = BASE_DIRECTORY.lower() |
- BASE_DIRECTORY = BASE_DIRECTORY.replace("\\", "/") |
- start_dir = start_dir.replace("\\", "/") |
- |
- if os.path.exists(os.path.join(BASE_DIRECTORY, ".git")): |
- global GIT_SOURCE_DIRECTORY |
- GIT_SOURCE_DIRECTORY = GetGitSourceDirectory(BASE_DIRECTORY) |
- |
- java = java_checker.JavaChecker(BASE_DIRECTORY, VERBOSE) |
- cpp = cpp_checker.CppChecker(VERBOSE) |
- checkers = dict( |
- (extension, checker) |
- for checker in [java, cpp] for extension in checker.EXTENSIONS) |
- success = CheckDirectory(base_rules, checkers, start_dir) |
- if not success: |
+ results = deps_checker.CheckDirectory(start_dir) |
+ if results: |
+ for result in results: |
+ print result |
print "\nFAILED\n" |
return 1 |
print "\nSUCCESS\n" |
return 0 |
-def main(): |
- option_parser = optparse.OptionParser() |
- option_parser.add_option("", "--root", default="", dest="base_directory", |
- help='Specifies the repository root. This defaults ' |
- 'to "../../.." relative to the script file, which ' |
- 'will normally be the repository root.') |
- option_parser.add_option("-v", "--verbose", action="store_true", |
- default=False, help="Print debug logging") |
- options, args = option_parser.parse_args() |
- return checkdeps(options, args) |
- |
- |
if '__main__' == __name__: |
sys.exit(main()) |