mirror of https://github.com/milvus-io/milvus.git
Add cpplint and optimize the check of c++ code
Signed-off-by: cai.zhang <cai.zhang@zilliz.com>pull/4973/head^2
parent
84f3d974fa
commit
a13638b172
|
@ -0,0 +1,43 @@
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
|
||||||
|
# The checks defined here will be run and will display by default as warnings.
|
||||||
|
Checks: >
|
||||||
|
-*, clang-diagnostic-*, -clang-diagnostic-error,
|
||||||
|
clang-analyzer-*, -clang-analyzer-alpha*,
|
||||||
|
google-*, -google-runtime-references, -google-readability-todo,
|
||||||
|
modernize-*, -modernize-pass-by-value, -modernize-use-equals-default,
|
||||||
|
performance-faster-string-find, performance-for-range-copy,
|
||||||
|
performance-implicit-conversion-in-loop, performance-inefficient-algorithm,
|
||||||
|
performance-trivially-destructible, performance-inefficient-vector-operation,
|
||||||
|
performance-move-const-arg, performance-move-constructor-init,
|
||||||
|
performance-noexcept-move-constructor, performance-no-automatic-move,
|
||||||
|
performance-type-promotion-in-math-fn
|
||||||
|
|
||||||
|
# produce HeaderFilterRegex from core/build-support/lint_exclusions.txt with:
|
||||||
|
# echo -n '^?!('; sed -e 's/*/\.*/g' core/build-support/lint_exclusions.txt | tr '\n' '|'; echo ')$'
|
||||||
|
HeaderFilterRegex: '^?!(.*cmake-build-debug.*|.*cmake-build-release.*|.*cmake_build.*|.*thirdparty.*|.*src/grpc.*|.*output.*|.*unittest.*|.*src/pb.*)$'
|
||||||
|
AnalyzeTemporaryDtors: true
|
||||||
|
CheckOptions:
|
||||||
|
- key: google-readability-braces-around-statements.ShortStatementLines
|
||||||
|
value: '1'
|
||||||
|
- key: google-readability-function-size.StatementThreshold
|
||||||
|
value: '800'
|
||||||
|
- key: google-readability-namespace-comments.ShortNamespaceLines
|
||||||
|
value: '10'
|
||||||
|
- key: google-readability-namespace-comments.SpacesBeforeComments
|
||||||
|
value: '2'
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
#
|
7
Makefile
7
Makefile
|
@ -21,9 +21,8 @@ all: build-cpp build-go
|
||||||
get-build-deps:
|
get-build-deps:
|
||||||
@(env bash $(PWD)/scripts/install_deps.sh)
|
@(env bash $(PWD)/scripts/install_deps.sh)
|
||||||
|
|
||||||
clang-format:
|
cppcheck:
|
||||||
@echo "Running $@ check"
|
@(env bash ${PWD}/scripts/core_build.sh -l)
|
||||||
@(env bash ${PWD}/scripts/run_clang_format.sh internal/core)
|
|
||||||
|
|
||||||
generated-proto-go:export protoc:=${PWD}/cmake_build/thirdparty/protobuf/protobuf-build/protoc
|
generated-proto-go:export protoc:=${PWD}/cmake_build/thirdparty/protobuf/protobuf-build/protoc
|
||||||
generated-proto-go: build-cpp
|
generated-proto-go: build-cpp
|
||||||
|
@ -52,7 +51,7 @@ ruleguard:
|
||||||
@${GOPATH}/bin/ruleguard -rules ruleguard.rules.go ./cmd/...
|
@${GOPATH}/bin/ruleguard -rules ruleguard.rules.go ./cmd/...
|
||||||
@${GOPATH}/bin/ruleguard -rules ruleguard.rules.go ./test/...
|
@${GOPATH}/bin/ruleguard -rules ruleguard.rules.go ./test/...
|
||||||
|
|
||||||
verifiers: clang-format fmt lint ruleguard
|
verifiers: cppcheck fmt lint ruleguard
|
||||||
|
|
||||||
# Builds various components locally.
|
# Builds various components locally.
|
||||||
build-go:
|
build-go:
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<code_scheme name="milvus" version="173">
|
||||||
|
<Objective-C>
|
||||||
|
<option name="INDENT_NAMESPACE_MEMBERS" value="0" />
|
||||||
|
<option name="INDENT_VISIBILITY_KEYWORDS" value="1" />
|
||||||
|
<option name="KEEP_STRUCTURES_IN_ONE_LINE" value="true" />
|
||||||
|
<option name="KEEP_CASE_EXPRESSIONS_IN_ONE_LINE" value="true" />
|
||||||
|
<option name="FUNCTION_NON_TOP_AFTER_RETURN_TYPE_WRAP" value="0" />
|
||||||
|
<option name="FUNCTION_TOP_AFTER_RETURN_TYPE_WRAP" value="2" />
|
||||||
|
<option name="FUNCTION_PARAMETERS_WRAP" value="5" />
|
||||||
|
<option name="FUNCTION_CALL_ARGUMENTS_WRAP" value="5" />
|
||||||
|
<option name="TEMPLATE_CALL_ARGUMENTS_WRAP" value="5" />
|
||||||
|
<option name="TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE" value="true" />
|
||||||
|
<option name="CLASS_CONSTRUCTOR_INIT_LIST_WRAP" value="5" />
|
||||||
|
<option name="ALIGN_INIT_LIST_IN_COLUMNS" value="false" />
|
||||||
|
<option name="SPACE_BEFORE_PROTOCOLS_BRACKETS" value="false" />
|
||||||
|
<option name="SPACE_BEFORE_POINTER_IN_DECLARATION" value="false" />
|
||||||
|
<option name="SPACE_AFTER_POINTER_IN_DECLARATION" value="true" />
|
||||||
|
<option name="SPACE_BEFORE_REFERENCE_IN_DECLARATION" value="false" />
|
||||||
|
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
||||||
|
<option name="KEEP_BLANK_LINES_BEFORE_END" value="1" />
|
||||||
|
</Objective-C>
|
||||||
|
<codeStyleSettings language="ObjectiveC">
|
||||||
|
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
|
||||||
|
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||||
|
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
|
||||||
|
<option name="BLANK_LINES_AROUND_CLASS" value="0" />
|
||||||
|
<option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0" />
|
||||||
|
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
|
||||||
|
<option name="SPACE_AFTER_TYPE_CAST" value="false" />
|
||||||
|
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
|
||||||
|
<option name="KEEP_SIMPLE_BLOCKS_IN_ONE_LINE" value="false" />
|
||||||
|
<option name="FOR_STATEMENT_WRAP" value="1" />
|
||||||
|
<option name="ASSIGNMENT_WRAP" value="1" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
||||||
|
clang-diagnostic-error
|
|
@ -0,0 +1,8 @@
|
||||||
|
*cmake-build-debug*
|
||||||
|
*cmake-build-release*
|
||||||
|
*cmake_build*
|
||||||
|
*thirdparty*
|
||||||
|
*src/grpc*
|
||||||
|
*output*
|
||||||
|
*unittest*
|
||||||
|
*src/pb*
|
|
@ -0,0 +1,110 @@
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
|
||||||
|
import multiprocessing as mp
|
||||||
|
import os
|
||||||
|
from fnmatch import fnmatch
|
||||||
|
from subprocess import Popen
|
||||||
|
|
||||||
|
|
||||||
|
def chunk(seq, n):
|
||||||
|
"""
|
||||||
|
divide a sequence into equal sized chunks
|
||||||
|
(the last chunk may be smaller, but won't be empty)
|
||||||
|
"""
|
||||||
|
chunks = []
|
||||||
|
some = []
|
||||||
|
for element in seq:
|
||||||
|
if len(some) == n:
|
||||||
|
chunks.append(some)
|
||||||
|
some = []
|
||||||
|
some.append(element)
|
||||||
|
if len(some) > 0:
|
||||||
|
chunks.append(some)
|
||||||
|
return chunks
|
||||||
|
|
||||||
|
|
||||||
|
def dechunk(chunks):
|
||||||
|
"flatten chunks into a single list"
|
||||||
|
seq = []
|
||||||
|
for chunk in chunks:
|
||||||
|
seq.extend(chunk)
|
||||||
|
return seq
|
||||||
|
|
||||||
|
|
||||||
|
def run_parallel(cmds, **kwargs):
|
||||||
|
"""
|
||||||
|
Run each of cmds (with shared **kwargs) using subprocess.Popen
|
||||||
|
then wait for all of them to complete.
|
||||||
|
Runs batches of multiprocessing.cpu_count() * 2 from cmds
|
||||||
|
returns a list of tuples containing each process'
|
||||||
|
returncode, stdout, stderr
|
||||||
|
"""
|
||||||
|
complete = []
|
||||||
|
for cmds_batch in chunk(cmds, mp.cpu_count() * 2):
|
||||||
|
procs_batch = [Popen(cmd, **kwargs) for cmd in cmds_batch]
|
||||||
|
for proc in procs_batch:
|
||||||
|
stdout, stderr = proc.communicate()
|
||||||
|
complete.append((proc.returncode, stdout, stderr))
|
||||||
|
return complete
|
||||||
|
|
||||||
|
|
||||||
|
_source_extensions = '''
|
||||||
|
.h
|
||||||
|
.cc
|
||||||
|
.cpp
|
||||||
|
'''.split()
|
||||||
|
|
||||||
|
|
||||||
|
def get_sources(source_dir, exclude_globs=[]):
|
||||||
|
sources = []
|
||||||
|
for directory, subdirs, basenames in os.walk(source_dir):
|
||||||
|
for path in [os.path.join(directory, basename)
|
||||||
|
for basename in basenames]:
|
||||||
|
# filter out non-source files
|
||||||
|
if os.path.splitext(path)[1] not in _source_extensions:
|
||||||
|
continue
|
||||||
|
|
||||||
|
path = os.path.abspath(path)
|
||||||
|
|
||||||
|
# filter out files that match the globs in the globs file
|
||||||
|
if any([fnmatch(path, glob) for glob in exclude_globs]):
|
||||||
|
continue
|
||||||
|
|
||||||
|
sources.append(path)
|
||||||
|
return sources
|
||||||
|
|
||||||
|
|
||||||
|
def stdout_pathcolonline(completed_process, filenames):
|
||||||
|
"""
|
||||||
|
given a completed process which may have reported some files as problematic
|
||||||
|
by printing the path name followed by ':' then a line number, examine
|
||||||
|
stdout and return the set of actually reported file names
|
||||||
|
"""
|
||||||
|
returncode, stdout, stderr = completed_process
|
||||||
|
bfilenames = set()
|
||||||
|
for filename in filenames:
|
||||||
|
bfilenames.add(filename.encode('utf-8') + b':')
|
||||||
|
problem_files = set()
|
||||||
|
for line in stdout.splitlines():
|
||||||
|
for filename in bfilenames:
|
||||||
|
if line.startswith(filename):
|
||||||
|
problem_files.add(filename.decode('utf-8'))
|
||||||
|
bfilenames.remove(filename)
|
||||||
|
break
|
||||||
|
return problem_files, stdout
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import lintutils
|
||||||
|
from subprocess import PIPE
|
||||||
|
import argparse
|
||||||
|
import difflib
|
||||||
|
import multiprocessing as mp
|
||||||
|
import sys
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
|
||||||
|
# examine the output of clang-format and if changes are
|
||||||
|
# present assemble a (unified)patch of the difference
|
||||||
|
def _check_one_file(completed_processes, filename):
|
||||||
|
with open(filename, "rb") as reader:
|
||||||
|
original = reader.read()
|
||||||
|
|
||||||
|
returncode, stdout, stderr = completed_processes[filename]
|
||||||
|
formatted = stdout
|
||||||
|
if formatted != original:
|
||||||
|
# Run the equivalent of diff -u
|
||||||
|
diff = list(difflib.unified_diff(
|
||||||
|
original.decode('utf8').splitlines(True),
|
||||||
|
formatted.decode('utf8').splitlines(True),
|
||||||
|
fromfile=filename,
|
||||||
|
tofile="{} (after clang format)".format(
|
||||||
|
filename)))
|
||||||
|
else:
|
||||||
|
diff = None
|
||||||
|
|
||||||
|
return filename, diff
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Runs clang-format on all of the source "
|
||||||
|
"files. If --fix is specified enforce format by "
|
||||||
|
"modifying in place, otherwise compare the output "
|
||||||
|
"with the existing file and output any necessary "
|
||||||
|
"changes as a patch in unified diff format")
|
||||||
|
parser.add_argument("--clang_format_binary",
|
||||||
|
required=True,
|
||||||
|
help="Path to the clang-format binary")
|
||||||
|
parser.add_argument("--exclude_globs",
|
||||||
|
help="Filename containing globs for files "
|
||||||
|
"that should be excluded from the checks")
|
||||||
|
parser.add_argument("--source_dir",
|
||||||
|
required=True,
|
||||||
|
help="Root directory of the source code")
|
||||||
|
parser.add_argument("--fix", default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="If specified, will re-format the source "
|
||||||
|
"code instead of comparing the re-formatted "
|
||||||
|
"output, defaults to %(default)s")
|
||||||
|
parser.add_argument("--quiet", default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="If specified, only print errors")
|
||||||
|
arguments = parser.parse_args()
|
||||||
|
|
||||||
|
exclude_globs = []
|
||||||
|
if arguments.exclude_globs:
|
||||||
|
for line in open(arguments.exclude_globs):
|
||||||
|
exclude_globs.append(line.strip())
|
||||||
|
|
||||||
|
formatted_filenames = []
|
||||||
|
for path in lintutils.get_sources(arguments.source_dir, exclude_globs):
|
||||||
|
formatted_filenames.append(str(path))
|
||||||
|
|
||||||
|
if arguments.fix:
|
||||||
|
if not arguments.quiet:
|
||||||
|
print("\n".join(map(lambda x: "Formatting {}".format(x),
|
||||||
|
formatted_filenames)))
|
||||||
|
|
||||||
|
# Break clang-format invocations into chunks: each invocation formats
|
||||||
|
# 16 files. Wait for all processes to complete
|
||||||
|
results = lintutils.run_parallel([
|
||||||
|
[arguments.clang_format_binary, "-i"] + some
|
||||||
|
for some in lintutils.chunk(formatted_filenames, 16)
|
||||||
|
])
|
||||||
|
for returncode, stdout, stderr in results:
|
||||||
|
# if any clang-format reported a parse error, bubble it
|
||||||
|
if returncode != 0:
|
||||||
|
sys.exit(returncode)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# run an instance of clang-format for each source file in parallel,
|
||||||
|
# then wait for all processes to complete
|
||||||
|
results = lintutils.run_parallel([
|
||||||
|
[arguments.clang_format_binary, filename]
|
||||||
|
for filename in formatted_filenames
|
||||||
|
], stdout=PIPE, stderr=PIPE)
|
||||||
|
for returncode, stdout, stderr in results:
|
||||||
|
# if any clang-format reported a parse error, bubble it
|
||||||
|
if returncode != 0:
|
||||||
|
sys.exit(returncode)
|
||||||
|
|
||||||
|
error = False
|
||||||
|
checker = partial(_check_one_file, {
|
||||||
|
filename: result
|
||||||
|
for filename, result in zip(formatted_filenames, results)
|
||||||
|
})
|
||||||
|
pool = mp.Pool()
|
||||||
|
try:
|
||||||
|
# check the output from each invocation of clang-format in parallel
|
||||||
|
for filename, diff in pool.imap(checker, formatted_filenames):
|
||||||
|
if not arguments.quiet:
|
||||||
|
print("Checking {}".format(filename))
|
||||||
|
if diff:
|
||||||
|
print("{} had clang-format style issues".format(filename))
|
||||||
|
# Print out the diff to stderr
|
||||||
|
error = True
|
||||||
|
# pad with a newline
|
||||||
|
print(file=sys.stderr)
|
||||||
|
diff_out = []
|
||||||
|
for diff_str in diff:
|
||||||
|
diff_out.append(diff_str.encode('raw_unicode_escape'))
|
||||||
|
sys.stderr.writelines(diff_out)
|
||||||
|
except Exception:
|
||||||
|
error = True
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
pool.terminate()
|
||||||
|
pool.join()
|
||||||
|
sys.exit(1 if error else 0)
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import argparse
|
||||||
|
import multiprocessing as mp
|
||||||
|
import lintutils
|
||||||
|
from subprocess import PIPE
|
||||||
|
import sys
|
||||||
|
from functools import partial
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
def _get_chunk_key(filenames):
|
||||||
|
# lists are not hashable so key on the first filename in a chunk
|
||||||
|
return filenames[0]
|
||||||
|
|
||||||
|
def _count_key(str, key):
|
||||||
|
m = re.findall(key, str)
|
||||||
|
return len(m)
|
||||||
|
|
||||||
|
# clang-tidy outputs complaints in '/path:line_number: complaint' format,
|
||||||
|
# so we can scan its output to get a list of files to fix
|
||||||
|
def _check_some_files(completed_processes, filenames):
|
||||||
|
result = completed_processes[_get_chunk_key(filenames)]
|
||||||
|
return lintutils.stdout_pathcolonline(result, filenames)
|
||||||
|
|
||||||
|
|
||||||
|
def _check_all(cmd, filenames, ignore_checks):
|
||||||
|
# each clang-tidy instance will process 16 files
|
||||||
|
chunks = lintutils.chunk(filenames, 16)
|
||||||
|
cmds = [cmd + some for some in chunks]
|
||||||
|
results = lintutils.run_parallel(cmds, stderr=PIPE, stdout=PIPE)
|
||||||
|
error = False
|
||||||
|
# record completed processes (keyed by the first filename in the input
|
||||||
|
# chunk) for lookup in _check_some_files
|
||||||
|
completed_processes = {
|
||||||
|
_get_chunk_key(some): result
|
||||||
|
for some, result in zip(chunks, results)
|
||||||
|
}
|
||||||
|
checker = partial(_check_some_files, completed_processes)
|
||||||
|
pool = mp.Pool()
|
||||||
|
error = False
|
||||||
|
try:
|
||||||
|
cnt_error = 0
|
||||||
|
cnt_warning = 0
|
||||||
|
cnt_ignore = 0
|
||||||
|
# check output of completed clang-tidy invocations in parallel
|
||||||
|
for problem_files, stdout in pool.imap(checker, chunks):
|
||||||
|
if problem_files:
|
||||||
|
msg = "clang-tidy suggested fixes for {}"
|
||||||
|
print("\n".join(map(msg.format, problem_files)))
|
||||||
|
# ignore thirdparty header file not found issue, such as:
|
||||||
|
# error: 'fiu.h' file not found [clang-diagnostic-error]
|
||||||
|
cnt_info = ""
|
||||||
|
for line in stdout.splitlines():
|
||||||
|
if any([len(re.findall(check, line)) > 0 for check in ignore_checks]):
|
||||||
|
cnt_info += line.replace(" error: ", " ignore: ").decode("utf-8") + "\n"
|
||||||
|
else:
|
||||||
|
cnt_info += line.decode("utf-8") + "\n"
|
||||||
|
cnt_error += _count_key(cnt_info, " error: ")
|
||||||
|
cnt_warning += _count_key(cnt_info, " warning: ")
|
||||||
|
cnt_ignore += _count_key(cnt_info, " ignore: ")
|
||||||
|
print(cnt_info)
|
||||||
|
print("clang-tidy - error: {}, warning: {}, ignore {}".
|
||||||
|
format(cnt_error, cnt_warning, cnt_ignore))
|
||||||
|
error = error or (cnt_error > 0 or cnt_warning > 0)
|
||||||
|
except Exception:
|
||||||
|
error = True
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
pool.terminate()
|
||||||
|
pool.join()
|
||||||
|
|
||||||
|
if error:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Runs clang-tidy on all ")
|
||||||
|
parser.add_argument("--clang_tidy_binary",
|
||||||
|
required=True,
|
||||||
|
help="Path to the clang-tidy binary")
|
||||||
|
parser.add_argument("--exclude_globs",
|
||||||
|
help="Filename containing globs for files "
|
||||||
|
"that should be excluded from the checks")
|
||||||
|
parser.add_argument("--ignore_checks",
|
||||||
|
help="Checkname containing checklist for files "
|
||||||
|
"that should be ignore from the checks")
|
||||||
|
parser.add_argument("--compile_commands",
|
||||||
|
required=True,
|
||||||
|
help="compile_commands.json to pass clang-tidy")
|
||||||
|
parser.add_argument("--source_dir",
|
||||||
|
required=True,
|
||||||
|
help="Root directory of the source code")
|
||||||
|
parser.add_argument("--fix", default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="If specified, will attempt to fix the "
|
||||||
|
"source code instead of recommending fixes, "
|
||||||
|
"defaults to %(default)s")
|
||||||
|
parser.add_argument("--quiet", default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="If specified, only print errors")
|
||||||
|
arguments = parser.parse_args()
|
||||||
|
|
||||||
|
exclude_globs = []
|
||||||
|
if arguments.exclude_globs:
|
||||||
|
for line in open(arguments.exclude_globs):
|
||||||
|
exclude_globs.append(line.strip())
|
||||||
|
|
||||||
|
ignore_checks = []
|
||||||
|
if arguments.ignore_checks:
|
||||||
|
for line in open(arguments.ignore_checks):
|
||||||
|
ignore_checks.append(line.strip())
|
||||||
|
|
||||||
|
linted_filenames = []
|
||||||
|
for path in lintutils.get_sources(arguments.source_dir, exclude_globs):
|
||||||
|
linted_filenames.append(path)
|
||||||
|
|
||||||
|
if not arguments.quiet:
|
||||||
|
msg = 'Tidying {}' if arguments.fix else 'Checking {}'
|
||||||
|
print("\n".join(map(msg.format, linted_filenames)))
|
||||||
|
|
||||||
|
cmd = [
|
||||||
|
arguments.clang_tidy_binary,
|
||||||
|
'-p',
|
||||||
|
arguments.compile_commands
|
||||||
|
]
|
||||||
|
if arguments.fix:
|
||||||
|
cmd.append('-fix')
|
||||||
|
results = lintutils.run_parallel(
|
||||||
|
[cmd + some for some in lintutils.chunk(linted_filenames, 16)])
|
||||||
|
for returncode, stdout, stderr in results:
|
||||||
|
if returncode != 0:
|
||||||
|
sys.exit(returncode)
|
||||||
|
|
||||||
|
else:
|
||||||
|
_check_all(cmd, linted_filenames, ignore_checks)
|
|
@ -0,0 +1,132 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import lintutils
|
||||||
|
from subprocess import PIPE, STDOUT
|
||||||
|
import argparse
|
||||||
|
import multiprocessing as mp
|
||||||
|
import sys
|
||||||
|
import platform
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE(wesm):
|
||||||
|
#
|
||||||
|
# * readability/casting is disabled as it aggressively warns about functions
|
||||||
|
# with names like "int32", so "int32(x)", where int32 is a function name,
|
||||||
|
# warns with
|
||||||
|
_filters = '''
|
||||||
|
-whitespace/comments
|
||||||
|
-readability/casting
|
||||||
|
-readability/todo
|
||||||
|
-readability/alt_tokens
|
||||||
|
-build/header_guard
|
||||||
|
-build/c++11
|
||||||
|
-runtime/references
|
||||||
|
-build/include_order
|
||||||
|
'''.split()
|
||||||
|
|
||||||
|
|
||||||
|
def _get_chunk_key(filenames):
|
||||||
|
# lists are not hashable so key on the first filename in a chunk
|
||||||
|
return filenames[0]
|
||||||
|
|
||||||
|
|
||||||
|
def _check_some_files(completed_processes, filenames):
|
||||||
|
# cpplint outputs complaints in '/path:line_number: complaint' format,
|
||||||
|
# so we can scan its output to get a list of files to fix
|
||||||
|
result = completed_processes[_get_chunk_key(filenames)]
|
||||||
|
return lintutils.stdout_pathcolonline(result, filenames)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Runs cpplint on all of the source files.")
|
||||||
|
parser.add_argument("--cpplint_binary",
|
||||||
|
required=True,
|
||||||
|
help="Path to the cpplint binary")
|
||||||
|
parser.add_argument("--exclude_globs",
|
||||||
|
help="Filename containing globs for files "
|
||||||
|
"that should be excluded from the checks")
|
||||||
|
parser.add_argument("--source_dir",
|
||||||
|
required=True,
|
||||||
|
help="Root directory of the source code")
|
||||||
|
parser.add_argument("--quiet", default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="If specified, only print errors")
|
||||||
|
arguments = parser.parse_args()
|
||||||
|
|
||||||
|
exclude_globs = []
|
||||||
|
if arguments.exclude_globs:
|
||||||
|
for line in open(arguments.exclude_globs):
|
||||||
|
exclude_globs.append(line.strip())
|
||||||
|
|
||||||
|
linted_filenames = []
|
||||||
|
for path in lintutils.get_sources(arguments.source_dir, exclude_globs):
|
||||||
|
linted_filenames.append(str(path))
|
||||||
|
|
||||||
|
cmd = [
|
||||||
|
arguments.cpplint_binary,
|
||||||
|
'--verbose=2',
|
||||||
|
'--linelength=120',
|
||||||
|
'--filter=' + ','.join(_filters)
|
||||||
|
]
|
||||||
|
if (arguments.cpplint_binary.endswith('.py') and
|
||||||
|
platform.system() == 'Windows'):
|
||||||
|
# Windows doesn't support executable scripts; execute with
|
||||||
|
# sys.executable
|
||||||
|
cmd.insert(0, sys.executable)
|
||||||
|
if arguments.quiet:
|
||||||
|
cmd.append('--quiet')
|
||||||
|
else:
|
||||||
|
print("\n".join(map(lambda x: "Linting {}".format(x),
|
||||||
|
linted_filenames)))
|
||||||
|
|
||||||
|
# lint files in chunks: each invocation of cpplint will process 16 files
|
||||||
|
chunks = lintutils.chunk(linted_filenames, 16)
|
||||||
|
cmds = [cmd + some for some in chunks]
|
||||||
|
results = lintutils.run_parallel(cmds, stdout=PIPE, stderr=STDOUT)
|
||||||
|
|
||||||
|
error = False
|
||||||
|
# record completed processes (keyed by the first filename in the input
|
||||||
|
# chunk) for lookup in _check_some_files
|
||||||
|
completed_processes = {
|
||||||
|
_get_chunk_key(filenames): result
|
||||||
|
for filenames, result in zip(chunks, results)
|
||||||
|
}
|
||||||
|
checker = partial(_check_some_files, completed_processes)
|
||||||
|
pool = mp.Pool()
|
||||||
|
try:
|
||||||
|
# scan the outputs of various cpplint invocations in parallel to
|
||||||
|
# distill a list of problematic files
|
||||||
|
for problem_files, stdout in pool.imap(checker, chunks):
|
||||||
|
if problem_files:
|
||||||
|
if isinstance(stdout, bytes):
|
||||||
|
stdout = stdout.decode('utf8')
|
||||||
|
print(stdout, file=sys.stderr)
|
||||||
|
error = True
|
||||||
|
except Exception:
|
||||||
|
error = True
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
pool.terminate()
|
||||||
|
pool.join()
|
||||||
|
|
||||||
|
sys.exit(1 if error else 0)
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
|
|
||||||
find_program(CLANG_TIDY_BIN
|
find_program(CLANG_TIDY_BIN
|
||||||
NAMES
|
NAMES
|
||||||
|
clang-tidy-10
|
||||||
|
clang-tidy-9
|
||||||
|
clang-tidy-8
|
||||||
clang-tidy-7.0
|
clang-tidy-7.0
|
||||||
clang-tidy-7
|
clang-tidy-7
|
||||||
clang-tidy-6.0
|
clang-tidy-6.0
|
||||||
|
@ -86,6 +89,9 @@ if (CLANG_FORMAT_VERSION)
|
||||||
else()
|
else()
|
||||||
find_program(CLANG_FORMAT_BIN
|
find_program(CLANG_FORMAT_BIN
|
||||||
NAMES
|
NAMES
|
||||||
|
clang-format-10
|
||||||
|
clang-format-9
|
||||||
|
clang-format-8
|
||||||
clang-format-7.0
|
clang-format-7.0
|
||||||
clang-format-7
|
clang-format-7
|
||||||
clang-format-6.0
|
clang-format-6.0
|
||||||
|
|
|
@ -34,11 +34,7 @@
|
||||||
#### Generate the go files from proto file
|
#### Generate the go files from proto file
|
||||||
|
|
||||||
```shell script
|
```shell script
|
||||||
cd milvus-distributed
|
make check-proto-product
|
||||||
pwd_dir=`pwd`
|
|
||||||
export PATH=$PATH:$(go env GOPATH)/bin
|
|
||||||
export protoc=${pwd_dir}/cmake_build/thirdparty/protobuf/protobuf-build/protoc
|
|
||||||
./scripts/proto_gen_go.sh
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Check code specifications
|
#### Check code specifications
|
||||||
|
@ -53,6 +49,16 @@
|
||||||
make all
|
make all
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Install docker-compose
|
||||||
|
|
||||||
|
refer: https://docs.docker.com/compose/install/
|
||||||
|
```shell script
|
||||||
|
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||||
|
sudo chmod +x /usr/local/bin/docker-compose
|
||||||
|
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
|
||||||
|
docker-compose --version
|
||||||
|
```
|
||||||
|
|
||||||
#### Start service
|
#### Start service
|
||||||
|
|
||||||
```shell script
|
```shell script
|
||||||
|
|
|
@ -138,7 +138,7 @@ ${CMAKE_CMD}
|
||||||
|
|
||||||
if [[ ${RUN_CPPLINT} == "ON" ]]; then
|
if [[ ${RUN_CPPLINT} == "ON" ]]; then
|
||||||
# cpplint check
|
# cpplint check
|
||||||
make lint
|
make lint || true
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "ERROR! cpplint check failed"
|
echo "ERROR! cpplint check failed"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -154,7 +154,7 @@ if [[ ${RUN_CPPLINT} == "ON" ]]; then
|
||||||
echo "clang-format check passed!"
|
echo "clang-format check passed!"
|
||||||
|
|
||||||
# clang-tidy check
|
# clang-tidy check
|
||||||
make check-clang-tidy
|
make check-clang-tidy || true
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "ERROR! clang-tidy check failed"
|
echo "ERROR! clang-tidy check failed"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
if [ -z $1 ]; then
|
|
||||||
echo "usage: $0 <path_to_core>"
|
|
||||||
exit -1
|
|
||||||
fi
|
|
||||||
CorePath=$1
|
|
||||||
|
|
||||||
formatThis() {
|
|
||||||
find "$1" | grep -E "(*\.cpp|*\.h|*\.cc)$" | grep -v "gen_tools/templates" | grep -v "/thirdparty" | grep -v "\.pb\." | xargs clang-format-10 -i
|
|
||||||
}
|
|
||||||
|
|
||||||
formatThis "${CorePath}/src"
|
|
||||||
formatThis "${CorePath}/unittest"
|
|
||||||
|
|
||||||
if test -z "$(git status | grep -E "*\.c|*\.h")"; then
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo "Please format your code by clang-format!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
Loading…
Reference in New Issue