| """Recipe for running clang-tidy-diff on the given build.""" |
| import logging |
| from slave import base_recipe |
| from slave import base_step |
| from slave.step import clang_tidy_step |
| from slave.step import compdb_gen_step |
| from slave.step import cast_shell_step |
| from slave.step import unittest_step |
| from slave.recipe import clang_builder |
| from slave.recipe import ota_builder |
| from slave.step import ota_resign_step |
| |
| # Note that the keys are Gerrit project names. |
| # TODO(mingcl): Allow configuring build-specific filters to avoid reporting |
| # duplicate clang-tidy suggestions from different builds. |
| PROJECT_CONFIGS = { |
| 'chromecast/internal': { |
| 'deny_list_filter': [ |
| r'vendor/media/google3/(.*)', 'android/prebuilt', |
| r'(.*)/third_party/(.*)' |
| ] |
| }, |
| } |
| |
| BUILD_CONFIGS = { |
| 'audioassistant_x64_eng_rbe_clang_tidy': { |
| 'build_args_product': 'audioassistant_x64_eng', |
| 'build_args_official': False, |
| # TODO(b/145840052): Remove once the build is fast enough. |
| 'timeout_secs_build_gtests': 5 * 60 * 60, |
| 'run_gtests': False, |
| }, |
| 'nq-eng_clang_tidy': { |
| 'resign': ota_resign_step.NQ_RESIGN, |
| 'factory': ota_resign_step.NQ_FACTORY, |
| 'usbstick': ota_resign_step.NQ_USBSTICK, |
| 'partner_bucket': ['cast-partner-amlogic-internal'], |
| }, |
| } |
| |
| # The name of build directory used by actual build recipe. |
| # Since the build directory name could change when the build recipe/script get |
| # changed, the best we can do is to update this dictionary when needed. |
| # This should be fine since clang tidy check is non-blocking. |
| BUILD_DIRECTORIES = { |
| 'audioassistant_x64_eng_rbe_clang_tidy': 'out_clang_audio_gn/Debug/', |
| 'nq-eng_clang_tidy': 'out_chromecast_nq/release/', |
| } |
| |
| # Specifies the recipe which will be used to make sure all files required for |
| # compilation is available before running clang-tidy |
| BUILD_RECIPE_NAME = { |
| 'audioassistant_x64_eng_rbe_clang_tidy': 'clang_builder', |
| 'nq-eng_clang_tidy': 'ota_builder', |
| } |
| |
| |
| def GetValidBuildNames(): |
| return [ |
| 'audioassistant_x64_eng_rbe_clang_tidy', |
| 'nq-eng_clang_tidy', |
| ] |
| |
| |
| def CreateRecipe(build_name: str, **kwargs): |
| """Builds a recipe object.""" |
| # Extracts default_properties from build config and adds it to the overall |
| # properties in kwargs. |
| config = BUILD_CONFIGS[build_name] |
| return ClangTidyRecipe( |
| build_name, |
| build_config=config, |
| build_dir=BUILD_DIRECTORIES[build_name], |
| build_recipe_name=BUILD_RECIPE_NAME[build_name], |
| **kwargs) |
| |
| |
| def RemoveClangTidySuffix(text): |
| if text.endswith('_clang_tidy'): |
| return text[:-len('_clang_tidy')] |
| return text |
| |
| |
| class ClangTidyRecipe(base_recipe.BaseRecipe): |
| """Recipe to clang-tidy a change.""" |
| |
| def __init__(self, build_name, build_config, build_dir, build_recipe_name, |
| **kwargs): |
| base_recipe.BaseRecipe.__init__( |
| self, enable_build_accelerator=True, **kwargs) |
| self._properties = kwargs.get('properties', {}) |
| self._build_name = build_name |
| self._build_config = build_config |
| self._build_dir = build_dir |
| self._build_recipe_name = build_recipe_name |
| self._builder_kwargs = kwargs |
| |
| def get_steps(self): |
| allow_list_filter = PROJECT_CONFIGS.get(self._properties['patch_project'], |
| {}).get('allow_list_filter', None) |
| deny_list_filter = PROJECT_CONFIGS.get(self._properties['patch_project'], |
| {}).get('deny_list_filter', None) |
| |
| # Build cast shell and unittests to generate necessary header files |
| if self._build_recipe_name == 'clang_builder': |
| build_steps = clang_builder.ClangRecipe( |
| self._build_config, **self._builder_kwargs).get_steps() |
| elif self._build_recipe_name == 'ota_builder': |
| build_steps = ota_builder.OtaRecipe( |
| RemoveClangTidySuffix(self._build_name), self._build_config, |
| **self._builder_kwargs).get_steps() |
| else: |
| logging.error('Unknown build recipe name: ' + self._build_recipe_name + |
| '. Might need to update BUILD_RECIPE_NAME.') |
| build_steps = [] |
| |
| return build_steps + [ |
| # Generate compilation database from the build directory. |
| compdb_gen_step.CompdbGenStep( |
| build_dir=self._build_dir, **self._step_kwargs), |
| # Then clang tidy can use the compilation database to check the code. |
| clang_tidy_step.ClangTidyStep( |
| allow_list_filter=allow_list_filter, |
| deny_list_filter=deny_list_filter, |
| **self._step_kwargs), |
| ] |