blob: c9a27c00bca6ace896445da443228b6bcd22ba4c [file] [log] [blame]
# Copyright 2023 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.
def black(ctx):
install_dir = ctx.scm.root + "/.tools"
ctx.os.exec([
"cipd",
"ensure",
"-ensure-file",
"black.ensure",
"-root",
install_dir,
], allow_network = True).wait()
res = ctx.os.exec([install_dir + "/black", "--check", "."], ok_retcodes = [0, 1]).wait()
found_file = False
for line in res.stderr.splitlines():
match = ctx.re.match(r"would reformat %s/(.*)" % ctx.scm.root, line)
if not match:
continue
found_file = True
filepath = match.groups[1]
ctx.emit.annotation(
filepath = filepath,
message = "File not formatted, run `black %s`" % filepath,
level = "error",
)
if res.retcode == 1 and not found_file:
fail("black had a retcode of 1 but could not parse files from output:\n%s" % res.stderr)
def recipe_style_guide(ctx):
"""Enforces http://go/fuchsia-recipe-docs#style-guide."""
procs = []
for f in ctx.scm.affected_files():
if f.endswith(".json") and ".expected" in f:
test_name = f.split("/")[-1].rsplit(".", 1)[0]
if " " in test_name:
# It would be nicer to parse the recipe file to find test case
# names because then we could emit the annotation at the place
# where the test name is defined. But because tests are
# generated by arbitrary Python code, it's practically
# impossible to parse out their names in a foolproof way.
ctx.emit.annotation(
filepath = f,
message = "Test name %r should not contain spaces" % test_name,
level = "error",
)
if not f.endswith(".py"):
continue
procs.append(ctx.os.exec(["python3", "scripts/enforce_style_guide.py", f]))
for proc in procs:
res = proc.wait()
for finding in json.decode(res.stdout):
ctx.emit.annotation(**finding)
shac.register_check(black)
shac.register_check(recipe_style_guide)