blob: 09269ed656d26d4437d989c859ffccde20678940 [file] [log] [blame]
# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Recipe for running Tricium clang-format analyzer."""
from contextlib import contextmanager
from recipe_engine.recipe_api import Property
DEPS = [
'infra/checkout',
'infra/clang_tidy',
'infra/git',
'infra/jiri',
'recipe_engine/buildbucket',
'recipe_engine/context',
'recipe_engine/json',
'recipe_engine/path',
'recipe_engine/properties',
'recipe_engine/raw_io',
'recipe_engine/step',
'recipe_engine/tricium',
]
from recipe_engine.config import List
from recipe_engine.recipe_api import Property
PROPERTIES = {
'project':
Property(kind=str, help='Gerrit patch ref', default=None),
'manifest':
Property(kind=str, help='Jiri manifest to use', default=None),
'checks':
Property(
kind=List(basestring),
help='Checks for clang-tidy to run',
default=['*']),
}
def RunSteps(api, project, manifest, checks):
api.clang_tidy.ensure_clang()
api.jiri.ensure_jiri()
with api.context(infra_steps=True):
# TODO(juliehockett): This is a hack to make the checkout work as expected, since
# Tricium still uses the v1 scheduling API and thus doesn't set the Gerrit project.
# Remove this once we fully switch Tricium over to the v2 API.
api.buildbucket.build.input.gerrit_changes[0].project = project
api.checkout(
manifest=manifest,
remote=api.tricium.repository,
project=project,
build_input=api.buildbucket.build.input)
checkout_dir = api.path['start_dir'].join(project)
compile_commands = api.clang_tidy.gen_compile_commands(checkout_dir)
errors = []
with api.step.nest('clang-tidy'):
for f in api.tricium.paths:
errors.append(api.clang_tidy.run(f, f, compile_commands, checks))
# We iterate through all produced error sets...
for path_errors in errors:
# ...and iterate through all checks that had errors...
for check in path_errors:
# ...and for each check, iterate through all the errors it produced...
for err in path_errors[check]:
# ...and extract the information from that error for a comment.
sline, schar = api.clang_tidy.get_line_from_offset(
err['FilePath'], err['FileOffset'])
api.tricium.add_comment(
'ClangTidy/%s' % err['DiagnosticName'],
'%s: %s' % (err['DiagnosticName'], err['Message']),
err['FilePath'],
start_line=sline,
start_char=schar,
)
api.tricium.write_comments()
def GenTests(api):
diff_output = '''path/to/file
other/path/to/file'''
read_output = '''test
newline output
'''
has_errors = '''- DiagnosticName: "fuchsia-default"
Message: "error"
FileOffset: 1
FilePath: "path/to/file"
'''
has_errors_json = [{
'FileOffset': 1,
'DiagnosticName': 'fuchsia-default',
'Message': 'error',
'FilePath': 'path/to/file'
}]
yield (api.test('default') + api.buildbucket.try_build(
git_repo='https://fuchsia.googlesource.com/topaz',) + api.properties(
manifest='project/topaz',
project='topaz',
repository='https://fuchsia.googlesource.com/topaz',
ref='HEAD',
paths=['path/to/file', 'other/path/to/file']) + api.step_data(
'clang-tidy.path/to/file.load yaml', stdout=api.json.output('')) +
api.step_data(
'clang-tidy.other/path/to/file.load yaml',
stdout=api.json.output(has_errors_json)))