forked from ray-project/ray
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CI] Add clang-tidy to lint (ray-project#18124)
* clang-tidy * fix * fix script * test clang compiler * fix clang-tidy rules * Fix windows and other issues. * Fix * Improve information when running check-git-clang-tidy-output.sh on different OS
- Loading branch information
Showing
12 changed files
with
656 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Disable the following checks due to frequent false positives, noisiness, | ||
# inconsistent style with existing codebase and other reasons: | ||
# -misc-non-private-member-variables-in-classes (potentially too restrictive) | ||
# -misc-unused-parameters (can be cleaned up in batch and enabled) | ||
# -modernize-avoid-c-arrays (too restrictive) | ||
# -modernize-pass-by-value (too restrictive) | ||
# -modernize-return-braced-init-list (inconsistent style) | ||
# -modernize-use-emplace (more subtle behavior) | ||
# -modernize-use-trailing-return-type (inconsistent style) | ||
# | ||
# TODO: enable google-* and readability-* families of checks. | ||
Checks: > | ||
abseil-*, | ||
bugprone-*, | ||
misc-*, | ||
-misc-non-private-member-variables-in-classes, | ||
-misc-unused-parameters, | ||
modernize-*, | ||
-modernize-avoid-c-arrays, | ||
-modernize-pass-by-value, | ||
-modernize-return-braced-init-list, | ||
-modernize-use-emplace, | ||
-modernize-use-trailing-return-type, | ||
performance-*, | ||
CheckOptions: | ||
# Reduce noisiness of the bugprone-narrowing-conversions check. | ||
- key: bugprone-narrowing-conversions.IgnoreConversionFromTypes | ||
value: 'size_t;ptrdiff_t;size_type;difference_type' | ||
- key: bugprone-narrowing-conversions.WarnOnEquivalentBitWidth | ||
value: 'false' | ||
|
||
# Turn all the warnings from the checks above into errors. | ||
WarningsAsErrors: "*" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
licenses(["notice"]) | ||
|
||
package(default_visibility = ["//visibility:public"]) | ||
|
||
filegroup( | ||
name = "license", | ||
srcs = ["license.txt"], | ||
) | ||
|
||
cc_library( | ||
name = "rapidjson", | ||
hdrs = glob([ | ||
"include/rapidjson/*.h", | ||
"include/rapidjson/*/*.h", | ||
]), | ||
copts = [ | ||
"-Wno-non-virtual-dtor", | ||
"-Wno-unused-variable", | ||
"-Wno-implicit-fallthrough", | ||
], | ||
includes = ["include"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Tool for listening on Bazel actions and generate compile commands database. | ||
# | ||
# Using Bazel aspect to generate compile commands would be faster. Also Bazel | ||
# action listeners are deprecated. We can switch to that if a stable solution | ||
# exists, e.g. https://github.com/grailbio/bazel-compilation-database | ||
|
||
cc_binary( | ||
name = "extract_compile_command", | ||
srcs = ["extract_compile_command.cc"], | ||
# Build fails on Windows, and not part of Ray either. | ||
tags = ["manual"], | ||
deps = [ | ||
"//:extra_actions_cc_proto_lib", | ||
"@com_google_protobuf//:protobuf", | ||
"@rapidjson", | ||
], | ||
) | ||
|
||
action_listener( | ||
name = "compile_command_listener", | ||
extra_actions = [":compile_command_action"], | ||
mnemonics = ["CppCompile"], | ||
) | ||
|
||
extra_action( | ||
name = "compile_command_action", | ||
cmd = "$(location :extract_compile_command) \ | ||
$(EXTRA_ACTION_FILE) \ | ||
$(output $(ACTION_ID).compile_command.json)", | ||
out_templates = ["$(ACTION_ID).compile_command.json"], | ||
tools = [":extract_compile_command"], | ||
) |
121 changes: 121 additions & 0 deletions
121
ci/generate_compile_commands/extract_compile_command.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/* | ||
* Copyright 2016 The Kythe Authors. All rights reserved. | ||
* | ||
* 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 | ||
* | ||
* http://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. | ||
* | ||
* Adapted from | ||
* https://github.com/xulongwu4/bazel-compilation-database/blob/master/kythe/generate_compile_commands/extract_compile_command.cc | ||
*/ | ||
#include <fcntl.h> | ||
#include <sys/stat.h> | ||
#include <sys/types.h> | ||
#include <unistd.h> | ||
|
||
#include <cstdio> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include "google/protobuf/io/coded_stream.h" | ||
#include "google/protobuf/io/zero_copy_stream.h" | ||
#include "google/protobuf/io/zero_copy_stream_impl.h" | ||
#include "google/protobuf/stubs/common.h" | ||
#include "rapidjson/stringbuffer.h" | ||
#include "rapidjson/writer.h" | ||
#include "thirdparty/protobuf/extra_actions_base.pb.h" | ||
|
||
namespace { | ||
using ::google::protobuf::io::CodedInputStream; | ||
using ::google::protobuf::io::FileInputStream; | ||
|
||
bool ReadExtraAction(const std::string &path, blaze::ExtraActionInfo *info, | ||
blaze::CppCompileInfo *cpp_info) { | ||
int fd = ::open(path.c_str(), O_RDONLY, S_IREAD | S_IWRITE); | ||
if (fd < 0) { | ||
perror("Failed to open input: "); | ||
return false; | ||
} | ||
FileInputStream file_input(fd); | ||
file_input.SetCloseOnDelete(true); | ||
|
||
CodedInputStream input(&file_input); | ||
if (!info->ParseFromCodedStream(&input)) return false; | ||
if (!info->HasExtension(blaze::CppCompileInfo::cpp_compile_info)) return false; | ||
*cpp_info = info->GetExtension(blaze::CppCompileInfo::cpp_compile_info); | ||
return true; | ||
} | ||
|
||
std::string JoinCommand(const std::vector<std::string> &command) { | ||
std::string output; | ||
if (command.empty()) return output; | ||
|
||
// TODO(shahms): Deal with embedded spaces and quotes. | ||
auto iter = command.begin(); | ||
output = *iter++; | ||
for (; iter != command.end(); ++iter) { | ||
output += " " + *iter; | ||
} | ||
return output; | ||
} | ||
|
||
std::string FormatCompilationCommand(const std::string &source_file, | ||
const std::vector<std::string> &command) { | ||
rapidjson::StringBuffer buffer; | ||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | ||
writer.StartObject(); | ||
writer.Key("file"); | ||
writer.String(source_file.c_str()); | ||
writer.Key("directory"); | ||
writer.String("@BAZEL_ROOT@"); | ||
writer.Key("command"); | ||
writer.String(JoinCommand(command).c_str()); | ||
writer.EndObject(); | ||
return buffer.GetString(); | ||
} | ||
} // namespace | ||
|
||
int main(int argc, char **argv) { | ||
GOOGLE_PROTOBUF_VERIFY_VERSION; | ||
if (argc != 3) { | ||
std::cerr << "usage: " << argv[0] << " extra-action-file output-file" << std::endl; | ||
return 1; | ||
} | ||
std::string extra_action_file = argv[1]; | ||
std::string output_file = argv[2]; | ||
blaze::ExtraActionInfo info; | ||
blaze::CppCompileInfo cpp_info; | ||
if (!ReadExtraAction(extra_action_file, &info, &cpp_info)) return 1; | ||
|
||
std::vector<std::string> args; | ||
args.push_back(cpp_info.tool()); | ||
args.insert(args.end(), cpp_info.compiler_option().begin(), | ||
cpp_info.compiler_option().end()); | ||
if (std::find(args.begin(), args.end(), "-c") == args.end()) { | ||
args.push_back("-c"); | ||
args.push_back(cpp_info.source_file()); | ||
} | ||
if (std::find(args.begin(), args.end(), "-o") == args.end()) { | ||
args.push_back("-o"); | ||
args.push_back(cpp_info.output_file()); | ||
} | ||
|
||
FILE *output = ::fopen(output_file.c_str(), "w"); | ||
if (output == nullptr) { | ||
perror("Unable to open file for writing: "); | ||
return 1; | ||
} | ||
::fputs(FormatCompilationCommand(cpp_info.source_file(), args).c_str(), output); | ||
::fclose(output); | ||
|
||
google::protobuf::ShutdownProtobufLibrary(); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#!/bin/bash | ||
|
||
# TODO: integrate this script into pull request workflow. | ||
|
||
printError() { | ||
printf '\033[31mERROR:\033[0m %s\n' "$@" | ||
} | ||
|
||
printInfo() { | ||
printf '\033[32mINFO:\033[0m %s\n' "$@" | ||
} | ||
|
||
log_err() { | ||
printError "Setting up clang-tidy encountered an error" | ||
} | ||
|
||
set -eo pipefail | ||
|
||
trap '[ $? -eq 0 ] || log_err' EXIT | ||
|
||
printInfo "Fetching workspace info ..." | ||
|
||
WORKSPACE=$(bazel info workspace) | ||
BAZEL_ROOT=$(bazel info execution_root) | ||
|
||
printInfo "Generating compilation database ..." | ||
|
||
case "${OSTYPE}" in | ||
linux*) | ||
printInfo " Running on Linux, using clang to build C++ targets. Please make sure it is installed ..." | ||
CC=clang bazel build //ci/generate_compile_commands:extract_compile_command //:ray_pkg \ | ||
--experimental_action_listener=//ci/generate_compile_commands:compile_command_listener;; | ||
darwin*) | ||
printInfo " Running on MacOS, assuming default C++ compiler is clang ..." | ||
bazel build //ci/generate_compile_commands:extract_compile_command //:ray_pkg \ | ||
--experimental_action_listener=//ci/generate_compile_commands:compile_command_listener;; | ||
msys*) | ||
printInfo " Running on Windows, using clang-cl to build C++ targets. Please make sure it is installed ..." | ||
CC=clang-cl bazel build //ci/generate_compile_commands:extract_compile_command //:ray_pkg \ | ||
--experimental_action_listener=//ci/generate_compile_commands:compile_command_listener;; | ||
esac | ||
|
||
printInfo "Assembling compilation database ..." | ||
|
||
TMPFILE=$(mktemp) | ||
printf '[\n' >"$TMPFILE" | ||
find "$BAZEL_ROOT" -name '*.compile_command.json' -exec cat {} + >>"$TMPFILE" | ||
printf '\n]\n' >>"$TMPFILE" | ||
|
||
if [[ "${OSTYPE}" =~ darwin* ]]; then | ||
sed -i '' "s|@BAZEL_ROOT@|$BAZEL_ROOT|g" "$TMPFILE" | ||
sed -i '' "s/}{/},\n{/g" "$TMPFILE" | ||
else | ||
sed -i "s|@BAZEL_ROOT@|$BAZEL_ROOT|g" "$TMPFILE" | ||
sed -i "s/}{/},\n{/g" "$TMPFILE" | ||
fi | ||
|
||
OUTFILE=$WORKSPACE/compile_commands.json | ||
|
||
if hash jq 2>/dev/null; then | ||
printInfo "Formatting compilation database ..." | ||
jq . "$TMPFILE" >"$OUTFILE" | ||
else | ||
printInfo "Can not find jq. Skip formatting compilation database." | ||
cp --no-preserve=mode "$TMPFILE" "$OUTFILE" | ||
fi | ||
|
||
# Compare against the master branch, because most development is done against it. | ||
base_commit="$(git merge-base HEAD master)" | ||
if [ "$base_commit" = "$(git rev-parse HEAD)" ]; then | ||
# Prefix of master branch, so compare against parent commit | ||
base_commit="$(git rev-parse HEAD^)" | ||
printInfo "Running clang-tidy against parent commit $base_commit" | ||
else | ||
printInfo "Running clang-tidy against parent commit $base_commit from master branch" | ||
fi | ||
|
||
trap - EXIT | ||
|
||
if git diff -U0 "$base_commit" | ci/travis/clang-tidy-diff.py -p1 -fix; then | ||
printInfo "clang-tidy passed." | ||
else | ||
printError "clang-tidy failed. See above for details including suggested fixes." | ||
printError | ||
printError "If you think the warning is too aggressive, the proposed fix is incorrect or are unsure about how to" | ||
printError "fix, feel free to raise the issue on the PR or Anyscale #learning-cplusplus Slack channel." | ||
printError | ||
printError "To run clang-tidy locally with fix suggestions, make sure clang and clang-tidy are installed and" | ||
printError "available in PATH (version 12 is preferred). Then run" | ||
printError "scripts/check-git-clang-tidy-output.sh" | ||
printError "from repo root." | ||
fi |
Oops, something went wrong.