| # 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 analyzers.""" |
| |
| from recipe_engine.config import ConfigList, ConfigGroup, Single |
| from recipe_engine.recipe_api import Property |
| |
| DEPS = [ |
| 'fuchsia/checkout', |
| 'fuchsia/jiri', |
| 'fuchsia/git', |
| 'fuchsia/tricium_analyze', |
| 'recipe_engine/buildbucket', |
| 'recipe_engine/cipd', |
| 'recipe_engine/context', |
| 'recipe_engine/json', |
| 'recipe_engine/file', |
| 'recipe_engine/path', |
| 'recipe_engine/platform', |
| 'recipe_engine/properties', |
| 'recipe_engine/python', |
| 'recipe_engine/raw_io', |
| 'recipe_engine/step', |
| 'recipe_engine/tricium', |
| ] |
| |
| PROPERTIES = { |
| 'manifest': |
| Property(kind=str, help='Jiri manifest to use', default=None), |
| 'remote': |
| Property(kind=str, help='Manifest project remote', default=None), |
| 'cipd_packages': |
| Property( |
| help='CIPD packages containing necessary binaries.', |
| kind=ConfigList(lambda: ConfigGroup( |
| # Package name. |
| name=Single(str), |
| # Version. |
| version=Single(str), |
| # Language subdirectory (e.g. clang) in which to put the package. The Tricium modules assume a Fuchsia prebuilts-like layout. |
| subdir=Single(str), |
| )), |
| default={}, |
| ), |
| } |
| |
| |
| def RunSteps(api, manifest, remote, cipd_packages): |
| with api.context(infra_steps=True): |
| checkout_root = api.path['start_dir'] |
| checkout = api.checkout.fuchsia_with_options( |
| path=checkout_root, |
| build=api.buildbucket.build, |
| manifest=manifest, |
| remote=remote, |
| ) |
| |
| project_name = api.buildbucket.build.input.gerrit_changes[0].project |
| |
| # If specified, download CIPD packages. |
| if cipd_packages: |
| with api.step.nest('ensure_packages'): |
| with api.context(infra_steps=True): |
| cipd_dir = checkout_root.join('cipd') |
| pkgs = api.cipd.EnsureFile() |
| for package in cipd_packages: |
| pkgs.add_package( |
| package['name'], package['version'], subdir=package['subdir']) |
| api.cipd.ensure(cipd_dir, pkgs) |
| platform = '%s-%s' % ( |
| api.platform.name.replace('win', 'windows'), |
| { |
| 'intel': { |
| 32: '386', |
| # Note that this is different from the CIPD norm (this is how |
| # //prebuilt/third_party is laid out). |
| 64: 'x64', |
| }, |
| 'arm': { |
| 32: 'armv6', |
| 64: 'arm64', |
| }, |
| }[api.platform.arch][api.platform.bits]) |
| # Only these tools are being downloaded from CIPD, so directly set the |
| # paths if cipd_packages is defined. |
| api.tricium_analyze.go = cipd_dir.join('go', platform, 'bin', 'go') |
| api.tricium_analyze.gofmt = cipd_dir.join('go', platform, 'bin', |
| 'gofmt') |
| api.tricium_analyze.yapf = cipd_dir.join('yapf') |
| |
| jiri_projects = api.jiri.project(projects=[project_name]).json.output |
| assert len(jiri_projects) == 1, str(jiri_projects) |
| project_dir = checkout_root.join(jiri_projects[0]['path']) |
| |
| with api.context(cwd=project_dir): |
| # --diff-filter=d excludes deleted files, because we don't want to |
| # check those. |
| paths = api.git( |
| 'diff-tree', |
| '--no-commit-id', |
| '--name-only', |
| '--diff-filter=d', |
| '-r', |
| 'HEAD', |
| name='get changed files', |
| stdout=api.raw_io.output()).stdout.splitlines() |
| |
| api.tricium_analyze.suggest_fx = api.path.exists( |
| checkout_root.join('scripts', 'fx')) |
| api.tricium_analyze.checkout = checkout |
| for path in paths: |
| # TODO(haowei): fxb/44823 Call git-check-attr on all files at once to speed it up |
| attr_result = api.git( |
| 'check-attr', |
| 'tricium', |
| '--', |
| path, |
| name='check attr of %s' % path, |
| stdout=api.raw_io.output()).stdout.strip() |
| if attr_result.endswith(': unset'): |
| continue |
| api.tricium_analyze(path) |
| |
| api.tricium.write_comments() |
| |
| |
| def GenTests(api): |
| changed_files_data = lambda files: api.step_data( |
| 'get changed files', |
| api.raw_io.stream_output('\n'.join(files)), |
| ) |
| |
| try_build = api.buildbucket.try_build( |
| git_repo='https://fuchsia.googlesource.com/topaz') |
| basic_properties = api.properties( |
| manifest='flower', |
| project='integration', |
| remote='https://fuchsia.googlesource.com/integration', |
| ref='refs/changes/12345/2', |
| ) |
| |
| yield (api.test('default') + try_build + basic_properties + |
| api.properties(analyses=['ClangFormat', 'GNFormat'],) + |
| changed_files_data(['BUILD.gn', 'hello.go']) + api.step_data( |
| 'analyze BUILD.gn.check file formatting', |
| api.raw_io.stream_output('BUILD.gn'), |
| )) |
| |
| yield (api.test('with_cipd_packages') + try_build + basic_properties + |
| api.properties( |
| analyses=['GoFmt'], |
| cipd_packages=[{ |
| 'name': 'fuchsia/go/${platform}', |
| 'version': 'goma', |
| 'subdir': 'go', |
| }]) + changed_files_data(['BUILD.gn', 'hello.go']) + api.step_data( |
| 'analyze hello.go.check file formatting', |
| api.raw_io.stream_output('hello.go'), |
| )) |
| |
| yield (api.test('attribute disable') + try_build + basic_properties + |
| api.properties(analyses=['ClangFormat', 'GNFormat'],) + |
| changed_files_data(['BUILD.gn', 'hello.go']) + api.step_data( |
| 'check attr of BUILD.gn', |
| api.raw_io.stream_output('BUILD.gn: tricium: unset\n'), |
| )) |