blob: 2794b3ea2d88cc582d8e48a12ac3e5d246fb8491 [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 analyzers."""
from recipe_engine.config import ConfigList, ConfigGroup, Single
from recipe_engine.recipe_api import Property
DEPS = [
"fuchsia/checkout",
"fuchsia/git",
"fuchsia/jiri",
"fuchsia/tricium_analyze",
"recipe_engine/buildbucket",
"recipe_engine/cipd",
"recipe_engine/context",
"recipe_engine/path",
"recipe_engine/platform",
"recipe_engine/properties",
"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,
# Tricium should always be triggered on CLs that affect projects in
# the checkout, so we shouldn't skip patching any CLs.
skip_patch_projects=(),
)
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.black = cipd_dir.join("black")
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(
"get changed files",
"diff-tree",
"--no-commit-id",
"--name-only",
"--diff-filter=d",
"-r",
"HEAD",
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 of %s" % path,
"check-attr",
"tricium",
"--",
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):
DIFF = """diff --git a/{0} b/{0}
index e684c1e..a76a10e 100644
--- a/{0}
+++ b/{0}
@@ -1,2 +1,4 @@
+ foo
+ bar
"""
changed_files_data = lambda files: api.step_data(
"get changed files", api.raw_io.stream_output("\n".join(files)),
)
get_changed_files_data = lambda files: api.step_data(
"analyze %s.get changed files" % files[0],
api.raw_io.stream_output("\n".join(DIFF.format(f) for f in files)),
)
formatted_files_data = lambda files: api.step_data(
"analyze %s.get formatted files" % files[0],
api.raw_io.stream_output("\n".join(DIFF.format(f) for f in 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"])
+ get_changed_files_data(["BUILD.gn"])
+ formatted_files_data(["BUILD.gn"])
)
yield (
api.test("with_cipd_packages")
+ try_build
+ basic_properties
+ api.properties(
analyses=["GoFmt"],
cipd_packages=[
{
"name": "fuchsia/go/${platform}",
"version": "integration",
"subdir": "go",
}
],
)
+ changed_files_data(["BUILD.gn", "hello.go"])
+ get_changed_files_data(["hello.go"])
+ formatted_files_data(["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"),
)
)