Esempio n. 1
0
 def CountViolations(self, skip_tests):
     deps_checker = checkdeps.DepsChecker(self.checkout_root,
                                          ignore_temp_rules=True,
                                          skip_tests=skip_tests)
     deps_checker.results_formatter = results.CountViolationsFormatter()
     deps_checker.CheckDirectory(os.path.join('chrome', 'browser'))
     return int(deps_checker.results_formatter.GetResults())
Esempio n. 2
0
def CheckUnwantedDependencies(input_api, output_api):
    """Runs checkdeps on #include statements added in this
  change. Breaking - rules is an error, breaking ! rules is a
  warning.
  """
    # Copied from Chromium's src/PRESUBMIT.py.

    # We need to wait until we have an input_api object and use this
    # roundabout construct to import checkdeps because this file is
    # eval-ed and thus doesn't have __file__.
    checkdeps_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
                                            'buildtools', 'checkdeps')
    if not os.path.exists(checkdeps_path):
        return [
            output_api.PresubmitError(
                'Cannot find checkdeps at %s\nHave you run "gclient sync" to '
                'download all the DEPS entries?' % checkdeps_path)
        ]
    with _AddToPath(checkdeps_path):
        import checkdeps
        from cpp_checker import CppChecker
        from rules import Rule

    added_includes = []
    for f in input_api.AffectedFiles():
        if not CppChecker.IsCppFile(f.LocalPath()):
            continue

        changed_lines = [line for _, line in f.ChangedContents()]
        added_includes.append([f.LocalPath(), changed_lines])

    deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())

    error_descriptions = []
    warning_descriptions = []
    for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
            added_includes):
        description_with_path = '%s\n    %s' % (path, rule_description)
        if rule_type == Rule.DISALLOW:
            error_descriptions.append(description_with_path)
        else:
            warning_descriptions.append(description_with_path)

    results = []
    if error_descriptions:
        results.append(
            output_api.PresubmitError(
                'You added one or more #includes that violate checkdeps rules.\n'
                'Check that the DEPS files in these locations contain valid rules.\n'
                'See https://cs.chromium.org/chromium/src/buildtools/checkdeps/ for '
                'more details about checkdeps.', error_descriptions))
    if warning_descriptions:
        results.append(
            output_api.PresubmitPromptOrNotify(
                'You added one or more #includes of files that are temporarily\n'
                'allowed but being removed. Can you avoid introducing the\n'
                '#include? See relevant DEPS file(s) for details and contacts.\n'
                'See https://cs.chromium.org/chromium/src/buildtools/checkdeps/ for '
                'more details about checkdeps.', warning_descriptions))
    return results
Esempio n. 3
0
def _CheckDeps(input_api, output_api):
  results = []
  import sys
  original_sys_path = sys.path
  try:
    sys.path = sys.path + [input_api.os_path.join(
        input_api.PresubmitLocalPath(), 'buildtools', 'checkdeps')]
    import checkdeps
    from cpp_checker import CppChecker
    from rules import Rule
  finally:
    sys.path = original_sys_path

  added_includes = []
  for f in input_api.AffectedFiles():
    if CppChecker.IsCppFile(f.LocalPath()):
      changed_lines = [line for _, line in f.ChangedContents()]
      added_includes.append([f.AbsoluteLocalPath(), changed_lines])

  deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
  violations = deps_checker.CheckAddedCppIncludes(added_includes)
  for path, rule_type, rule_description in violations:
    relpath = input_api.os_path.relpath(path, input_api.PresubmitLocalPath())
    error_description = '%s\n    %s' % (relpath, rule_description)
    if rule_type == Rule.DISALLOW:
      results.append(output_api.PresubmitError(error_description))
    else:
      results.append(output_api.PresubmitPromptWarning(error_description))
  return results
Esempio n. 4
0
def _CheckUnwantedDependencies(input_api, output_api):
    """Runs checkdeps on #include statements added in this
    change. Breaking - rules is an error, breaking ! rules is a
    warning.
    """
    # We need to wait until we have an input_api object and use this
    # roundabout construct to import checkdeps because this file is
    # eval-ed and thus doesn't have __file__.
    original_sys_path = sys.path
    try:
        sys.path = sys.path + [
            input_api.os_path.realpath(
                input_api.os_path.join(input_api.PresubmitLocalPath(), '..',
                                       '..', 'buildtools', 'checkdeps'))
        ]
        import checkdeps
        from cpp_checker import CppChecker
        from rules import Rule
    finally:
        # Restore sys.path to what it was before.
        sys.path = original_sys_path

    added_includes = []
    for f in input_api.AffectedFiles():
        if not CppChecker.IsCppFile(f.LocalPath()):
            continue

        changed_lines = [line for line_num, line in f.ChangedContents()]
        added_includes.append([f.LocalPath(), changed_lines])

    deps_checker = checkdeps.DepsChecker(
        input_api.os_path.join(input_api.PresubmitLocalPath()))

    error_descriptions = []
    warning_descriptions = []
    for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
            added_includes):
        description_with_path = '%s\n    %s' % (path, rule_description)
        if rule_type == Rule.DISALLOW:
            error_descriptions.append(description_with_path)
        else:
            warning_descriptions.append(description_with_path)

    results = []
    if error_descriptions:
        results.append(
            output_api.PresubmitError(
                'You added one or more #includes that violate checkdeps rules.',
                error_descriptions))
    if warning_descriptions:
        results.append(
            output_api.PresubmitPromptOrNotify(
                'You added one or more #includes of files that are temporarily\n'
                'allowed but being removed. Can you avoid introducing the\n'
                '#include? See relevant DEPS file(s) for details and contacts.',
                warning_descriptions))
    return results
Esempio n. 5
0
def _CheckDeps(input_api, output_api):
    results = []
    import sys
    original_sys_path = sys.path
    try:
        sys.path = sys.path + [
            input_api.os_path.join(input_api.PresubmitLocalPath(),
                                   'buildtools', 'checkdeps')
        ]
        import checkdeps
        from cpp_checker import CppChecker
        from rules import Rule
    finally:
        sys.path = original_sys_path

    deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
    deps_checker.CheckDirectory(input_api.PresubmitLocalPath())
    deps_results = deps_checker.results_formatter.GetResults()
    for violation in deps_results:
        results.append(output_api.PresubmitError(violation))
    return results
Esempio n. 6
0
def _CheckUnwantedDependencies(input_api, output_api):
    """Runs checkdeps on #include statements added in this
  change. Breaking - rules is an error, breaking ! rules is a
  warning.
  """
    # We need to wait until we have an input_api object and use this
    # roundabout construct to import checkdeps because this file is
    # eval-ed and thus doesn't have __file__.
    original_sys_path = sys.path
    try:
        sys.path = sys.path + [
            input_api.os_path.join(input_api.PresubmitLocalPath(),
                                   'buildtools', 'checkdeps')
        ]
        import checkdeps
        from cpp_checker import CppChecker
        from rules import Rule
    finally:
        # Restore sys.path to what it was before.
        sys.path = original_sys_path

    def _FilesImpactedByDepsChange(files):
        all_files = [f.AbsoluteLocalPath() for f in files]
        deps_files = [p for p in all_files if IsDepsFile(p)]
        impacted_files = union(
            [_CollectImpactedFiles(path) for path in deps_files])
        impacted_file_objs = [ImpactedFile(path) for path in impacted_files]
        return impacted_file_objs

    def IsDepsFile(p):
        return os.path.isfile(p) and os.path.basename(p) == 'DEPS'

    def union(list_of_lists):
        """Ensure no duplicates"""
        return set(sum(list_of_lists, []))

    def _CollectImpactedFiles(deps_file):
        # TODO(liviurau): Do not walk paths twice. Then we have no duplicates.
        # Higher level DEPS changes may dominate lower level DEPS changes.
        # TODO(liviurau): Check if DEPS changed in the right way.
        # 'include_rules' impact c++ files but 'vars' or 'deps' do not.
        # Maybe we just eval both old and new DEPS content and check
        # if the list are the same.
        result = []
        parent_dir = os.path.dirname(deps_file)
        for relative_f in input_api.change.AllFiles(parent_dir):
            abs_f = os.path.join(parent_dir, relative_f)
            if CppChecker.IsCppFile(abs_f):
                result.append(abs_f)
        return result

    class ImpactedFile(object):
        """Duck type version of AffectedFile needed to check files under directories
    where a DEPS file changed. Extend the interface along the line of
    AffectedFile if you need it for other checks."""
        def __init__(self, path):
            self._path = path

        def LocalPath(self):
            path = self._path.replace(os.sep, '/')
            return os.path.normpath(path)

        def ChangedContents(self):
            with open(self._path) as f:
                # TODO(liviurau): read only '#include' lines
                lines = f.readlines()
            return enumerate(lines, start=1)

    def _FilterDuplicates(impacted_files, affected_files):
        """"We include all impacted files but exclude affected files that are also
    impacted. Files impacted by DEPS changes take precedence before files
    affected by direct changes."""
        result = impacted_files[:]
        only_paths = set([imf.LocalPath() for imf in impacted_files])
        for af in affected_files:
            if not af.LocalPath() in only_paths:
                result.append(af)
        return result

    added_includes = []
    affected_files = input_api.AffectedFiles()
    impacted_by_deps = _FilesImpactedByDepsChange(affected_files)
    for f in _FilterDuplicates(impacted_by_deps, affected_files):
        if not CppChecker.IsCppFile(f.LocalPath()):
            continue

        changed_lines = [line for line_num, line in f.ChangedContents()]
        added_includes.append([f.LocalPath(), changed_lines])

    deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())

    error_descriptions = []
    warning_descriptions = []
    for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
            added_includes):
        description_with_path = '%s\n    %s' % (path, rule_description)
        if rule_type == Rule.DISALLOW:
            error_descriptions.append(description_with_path)
        else:
            warning_descriptions.append(description_with_path)

    results = []
    if error_descriptions:
        results.append(
            output_api.PresubmitError(
                'You added one or more #includes that violate checkdeps rules.',
                error_descriptions))
    if warning_descriptions:
        results.append(
            output_api.PresubmitPromptOrNotify(
                'You added one or more #includes of files that are temporarily\n'
                'allowed but being removed. Can you avoid introducing the\n'
                '#include? See relevant DEPS file(s) for details and contacts.',
                warning_descriptions))
    return results
Esempio n. 7
0
 def setUp(self):
     self.deps_checker = checkdeps.DepsChecker(
         being_tested=True,
         base_directory=os.path.join(os.path.dirname(__file__),
                                     os.path.pardir))
Esempio n. 8
0
 def testBadBaseDirectoryNotCheckoutRoot(self):
     # This assumes git. It's not a valid test if buildtools is fetched via svn.
     with self.assertRaises(builddeps.DepsBuilderError):
         checkdeps.DepsChecker(being_tested=True,
                               base_directory=os.path.dirname(__file__))
Esempio n. 9
0
 def setUp(self):
   self.deps_checker = checkdeps.DepsChecker(being_tested=True)