blob: 01cbc32ecf40fc4d875c79ee6519aadf8e0a4178 [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.
load("./common.star", "FORMATTER_MSG", "cipd_platform_name", "get_fuchsia_dir", "os_exec")
def _buildifier(ctx):
"""Checks Starlark/Bazel file formatting using buildifier."""
starlark_files = [
f
for f in ctx.scm.affected_files()
if (
f.endswith((".star", ".bzl", ".bazel", ".bzlmod", ".BUILD", ".WORKSPACE")) or
f.split("/")[-1] in ("/BUILD", "/WORKSPACE")
) and
not f.startswith("third_party/")
]
if not starlark_files:
return
base_cmd = [
"%s/prebuilt/third_party/buildifier/%s/buildifier" % (
get_fuchsia_dir(ctx),
cipd_platform_name(ctx),
),
"-lint=off",
]
res = os_exec(
ctx,
base_cmd + ["-mode=check"] + starlark_files,
ok_retcodes = (0, 4),
).wait()
if res.retcode == 0:
return
lines = res.stderr.splitlines()
suffix = " # reformat"
tempfiles = {}
for line in lines:
if not line.endswith(suffix):
continue
filepath = line[:-len(suffix)]
# Buildifier doesn't have a dry-run mode that prints the formatted file
# to stdout, so copy each file to a temporary file and format the
# temporary file in-place to obtain the formatted result.
tempfiles[filepath] = ctx.io.tempfile(
ctx.io.read_file(filepath),
name = filepath,
)
os_exec(ctx, base_cmd + tempfiles.values()).wait()
for filepath, temp in tempfiles.items():
formatted = ctx.io.read_file(temp)
ctx.emit.finding(
level = "error",
filepath = filepath,
message = FORMATTER_MSG,
replacements = [str(formatted)],
)
def _fuchsia_shac_style_guide(ctx):
"""Enforces shac conventions that are specific to the fuchsia project."""
starlark_files = [
f
for f in ctx.scm.affected_files()
if f.endswith(".star")
]
procs = []
for f in starlark_files:
procs.append(
(f, os_exec(ctx, [
"%s/prebuilt/third_party/python3/%s/bin/python3" % (
get_fuchsia_dir(ctx),
cipd_platform_name(ctx),
),
"scripts/shac/fuchsia_shac_style_guide.py",
f,
])),
)
for f, proc in procs:
res = proc.wait()
for finding in json.decode(res.stdout):
ctx.emit.finding(
level = "error",
filepath = f,
message = finding["message"],
line = finding["line"],
col = finding["col"],
end_line = finding["end_line"],
end_col = finding["end_col"],
)
def register_starlark_checks():
shac.register_check(shac.check(_buildifier, formatter = True))
shac.register_check(shac.check(_fuchsia_shac_style_guide))