mirror of
https://boringssl.googlesource.com/boringssl
synced 2026-07-21 14:43:51 +00:00
f998a843ab
PRESUBMIT.py is run by depot_tools as part of `git cl presubmit` or `git cl upload`. It runs util/pregenerate.go to check pregenerated files. This CL uses shutil.which() to find the clang path and pass it to util/pregenerate.go, which may result in skipping the clang steps if clang cannot be found in the $PATH. In that case, it also adds a message to tell the user that results may not be complete. Also switches to shutil.which() to find "buildifier" and "go", and fixes a lack of return value in CheckBuildifier. Change-Id: Id9bfbc753ce3f7618abf26c958ac37586a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/87430 Auto-Submit: Lily Chen <chlily@google.com> Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com>
151 lines
5.1 KiB
Python
151 lines
5.1 KiB
Python
# Copyright 2025 The BoringSSL Authors
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# https://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
"""Presubmit checks for BoringSSL.
|
|
|
|
Run by the presubmit API in depot_tools, e.g. by running `git cl presubmit`.
|
|
"""
|
|
|
|
import shutil
|
|
|
|
PRESUBMIT_VERSION = '2.0.0'
|
|
USE_PYTHON3 = True
|
|
|
|
|
|
def _PassResult(stdout, stderr, retcode):
|
|
del stdout, stderr, retcode # Function does nothing.
|
|
return [] # Check passed.
|
|
|
|
|
|
def _RunTool(input_api,
|
|
output_api,
|
|
command,
|
|
handle_result=_PassResult):
|
|
"""
|
|
Runs a command and processes its result.
|
|
|
|
handle_result(stdout, stderr, retcode) and explain_error(error) should each
|
|
return a list of output_api.PresubmitResult.
|
|
|
|
Args:
|
|
input_api: API to read CL contents.
|
|
output_api: API to generate presubmit errors/warning to return.
|
|
handle_result: function receiving (stdout, stderr, retcode) parsing the
|
|
command result and turning it into a list of output_api.PresubmitResult.
|
|
|
|
Returns:
|
|
List of presubmit errors.
|
|
"""
|
|
try:
|
|
out, retcode = input_api.subprocess.communicate(
|
|
command,
|
|
stdout=input_api.subprocess.PIPE,
|
|
stderr=input_api.subprocess.PIPE,
|
|
encoding='utf-8')
|
|
return handle_result(out[0], out[1], retcode)
|
|
except input_api.subprocess.CalledProcessError as e:
|
|
return [
|
|
output_api.PresubmitPromptOrNotify(
|
|
'Command "%s" returned exit code %d. Output: \n\n%s' %
|
|
' '.join(command), e.returncode, e.output)
|
|
]
|
|
|
|
|
|
def CheckPregeneratedFiles(input_api, output_api):
|
|
"""Checks that pregenerated files are properly updated."""
|
|
# TODO(chlily): Make this compatible with the util/bot environment for CI/CQ.
|
|
# Check that `go` is available on the $PATH.
|
|
go_path = shutil.which('go')
|
|
if not go_path:
|
|
return [
|
|
output_api.PresubmitPromptOrNotify(
|
|
'Could not check pregenerated files: Command "go" not found.')
|
|
]
|
|
|
|
# Find `clang` path. If not found, turn off the clang steps in pregenerate.
|
|
clang_path = shutil.which('clang')
|
|
|
|
pregenerate_script_path = input_api.os_path.join(
|
|
input_api.change.RepositoryRoot(), 'util', 'pregenerate')
|
|
command = [go_path, 'run', pregenerate_script_path,
|
|
'-check', f'-clang={clang_path if clang_path is not None else ""}']
|
|
|
|
def HandlePregenerateResult(stdout, stderr, retcode):
|
|
del stdout # All output we care for is in stderr.
|
|
results = []
|
|
if not clang_path:
|
|
results.append(output_api.PresubmitPromptOrNotify(
|
|
('Ran `go run ./util/pregenerate -check` but could not find "clang": '
|
|
'CheckPregeneratedFiles results may not be complete.')))
|
|
if retcode:
|
|
results.append(output_api.PresubmitError(
|
|
('Found out-of-date generated files. '
|
|
'Run `go run ./util/pregenerate` to update them.'),
|
|
stderr.splitlines()))
|
|
return results
|
|
|
|
return _RunTool(input_api,
|
|
output_api,
|
|
command,
|
|
handle_result=HandlePregenerateResult)
|
|
|
|
|
|
def CheckBuildifier(input_api, output_api):
|
|
"""
|
|
Runs Buildifier formatting check if the affected files include
|
|
*.bazel or *.bzl files.
|
|
|
|
Args:
|
|
input_api: API to read CL contents.
|
|
output_api: API to generate presubmit errors/warning to return.
|
|
|
|
Returns:
|
|
List of presubmit errors.
|
|
"""
|
|
file_paths = []
|
|
for affected_file in input_api.AffectedFiles(include_deletes=False):
|
|
affected_file_path = affected_file.LocalPath()
|
|
if not affected_file_path.endswith(('.bzl', '.bazel')):
|
|
continue
|
|
if 'third_party' in affected_file_path or 'gen' in affected_file_path:
|
|
continue
|
|
file_paths.append(affected_file_path)
|
|
if not file_paths:
|
|
return [] # Check passed.
|
|
|
|
# Check that `buildifier` is available on the $PATH.
|
|
# TODO(chlily): Make this compatible with the util/bot environment for CI/CQ.
|
|
buildifier_path = shutil.which('buildifier')
|
|
if not buildifier_path:
|
|
return [
|
|
output_api.PresubmitPromptOrNotify(
|
|
'Could not check *.bzl and *.bazel formatting: '
|
|
'Command "buildifier" not found. You can download buildifier from '
|
|
'https://github.com/bazelbuild/buildtools/releases')
|
|
]
|
|
|
|
def HandleBuildifierResult(stdout, stderr, retcode):
|
|
del stderr # This only parses stdout, as nothing failed.
|
|
if retcode == 4: # check mode failed (reformat is needed).
|
|
return [
|
|
output_api.PresubmitError(
|
|
('Found incorrectly formatted *.bzl or *.bazel files. '
|
|
'Run `buildifier` to update them.'), stdout.splitlines())
|
|
]
|
|
return [] # Check passed.
|
|
|
|
return _RunTool(input_api,
|
|
output_api, [buildifier_path, '--mode=check'] + file_paths,
|
|
handle_result=HandleBuildifierResult)
|