Add bpfmt builtin hook
This tool is identical to the gofmt tool, but for *.bp build files
instead (usually Android.bp).
Bug: 132785638
Test: turn on bpfmt, repo upload
Change-Id: I974c30e101d9e01cc69d357f9b5f60a1403f8bf6
diff --git a/README.md b/README.md
index ea25702..20e4d5a 100644
--- a/README.md
+++ b/README.md
@@ -140,6 +140,7 @@
This section allows for turning on common/builtin hooks. There are a bunch of
canned hooks already included geared towards AOSP style guidelines.
+* `bpfmt`: Run Blueprint files (.bp) through `bpfmt`.
* `checkpatch`: Run commits through the Linux kernel's `checkpatch.pl` script.
* `clang_format`: Run git-clang-format against the commit. The default style is
`file`.
@@ -197,6 +198,7 @@
provide consistent behavior for developers across different OS and Linux
distros/versions. The following tools are recognized:
+* `bpfmt`: used for the `bpfmt` builtin hook.
* `clang-format`: used for the `clang_format` builtin hook.
* `cpplint`: used for the `cpplint` builtin hook.
* `git-clang-format`: used for the `clang_format` builtin hook.
diff --git a/rh/hooks.py b/rh/hooks.py
index dc3e3ac..e2eed96 100644
--- a/rh/hooks.py
+++ b/rh/hooks.py
@@ -286,6 +286,25 @@
**kwargs)
+def check_bpfmt(project, commit, _desc, diff, options=None):
+ """Checks that Blueprint files are formatted with bpfmt."""
+ filtered = _filter_diff(diff, [r'\.bp$'])
+ if not filtered:
+ return None
+
+ bpfmt = options.tool_path('bpfmt')
+ cmd = [bpfmt, '-l'] + options.args((), filtered)
+ ret = []
+ for d in filtered:
+ data = rh.git.get_file_content(commit, d.file)
+ result = _run_command(cmd, input=data)
+ if result.output:
+ ret.append(rh.results.HookResult(
+ 'bpfmt', project, commit, error=result.output,
+ files=(d.file,)))
+ return ret
+
+
def check_checkpatch(project, commit, _desc, diff, options=None):
"""Run |diff| through the kernel's checkpatch.pl tool."""
tool = get_helper_path('checkpatch.pl')
@@ -628,6 +647,7 @@
# Note: Make sure to keep the top level README.md up to date when adding more!
BUILTIN_HOOKS = {
'android_test_mapping_format': check_android_test_mapping,
+ 'bpfmt': check_bpfmt,
'checkpatch': check_checkpatch,
'clang_format': check_clang_format,
'commit_msg_bug_field': check_commit_msg_bug_field,
@@ -649,6 +669,7 @@
TOOL_PATHS = {
'android-test-mapping-format':
os.path.join(TOOLS_DIR, 'android_test_mapping_format.py'),
+ 'bpfmt': 'bpfmt',
'clang-format': 'clang-format',
'cpplint': os.path.join(TOOLS_DIR, 'cpplint.py'),
'git-clang-format': 'git-clang-format',
diff --git a/rh/hooks_unittest.py b/rh/hooks_unittest.py
index 2045363..2864088 100755
--- a/rh/hooks_unittest.py
+++ b/rh/hooks_unittest.py
@@ -291,6 +291,20 @@
self.assertIn('test_%s' % (hook,), dir(self),
msg='Missing unittest for builtin hook %s' % (hook,))
+ def test_bpfmt(self, mock_check, _mock_run):
+ """Verify the bpfmt builtin hook."""
+ # First call should do nothing as there are no files to check.
+ ret = rh.hooks.check_bpfmt(
+ self.project, 'commit', 'desc', (), options=self.options)
+ self.assertIsNone(ret)
+ self.assertFalse(mock_check.called)
+
+ # Second call will have some results.
+ diff = [rh.git.RawDiffEntry(file='Android.bp')]
+ ret = rh.hooks.check_bpfmt(
+ self.project, 'commit', 'desc', diff, options=self.options)
+ self.assertIsNotNone(ret)
+
def test_checkpatch(self, mock_check, _mock_run):
"""Verify the checkpatch builtin hook."""
ret = rh.hooks.check_checkpatch(