-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adding clang-tidy as a linter tool #2269
Open
Suyashd999
wants to merge
11
commits into
ceph:main
Choose a base branch
from
Suyashd999:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
1d93369
adding clang-tidy as linter tool
Suyashd999 f724d88
Added build steps
Suyashd999 efeb4fa
added the script clang-tidy-to-junit for report generation
Suyashd999 31aead3
refactored clang-tidy-to-junit.py execution
Suyashd999 600c035
refactored status-context
Suyashd999 9935304
renamed LICENSE and added node configuration
Suyashd999 5e54b91
added node configuration
Suyashd999 d64fdaa
configured to work with `copy_artifacts` plugin
Suyashd999 498e2a3
updated to run clang-tidy on all files
Suyashd999 84e8418
Working with new "build/boost" and "build/include" from the tar file
Suyashd999 df5dc10
uses shallow clone
Suyashd999 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2018 PSPDFKit | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
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,58 @@ | ||
#!/bin/bash | ||
set -ex | ||
|
||
cd "$WORKSPACE/ceph" | ||
|
||
# Initialize and update submodules | ||
git submodule update --init --recursive --progress | ||
|
||
# Install dependencies | ||
sudo apt-get install -y curl | ||
sudo apt-get install -y python3-routes | ||
sudo apt-get install -y clang-tidy parallel | ||
|
||
# Configure the build | ||
./do_cmake.sh -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=ON | ||
cd build | ||
|
||
# Replace the boost and include directories from the tar file | ||
tar -xzf "$WORKSPACE/ceph_build.tar.gz" -C "$WORKSPACE" | ||
rm "$WORKSPACE/ceph_build.tar.gz" | ||
sudo rm -rf boost include | ||
sudo mv "$WORKSPACE/build/boost" ./boost | ||
sudo mv "$WORKSPACE/build/include" ./include | ||
|
||
# Prepare for Clang-Tidy | ||
cd "$WORKSPACE/ceph" | ||
output_file="clang-tidy-result" | ||
file_list="files_to_check.txt" | ||
|
||
# Get list of modified files in the current commit | ||
git diff --name-only HEAD~1 HEAD > modified_files.txt | ||
|
||
# Filter for only C++ files in rgw and osd directories | ||
cat modified_files.txt | grep -E "^(src/rgw|src/osd).*\.(cpp|hpp|cc)$" > "$file_list" | ||
|
||
# Check if there are any files to analyze | ||
if [ ! -s "$file_list" ]; then | ||
echo "No C++ files were modified in rgw or osd directories in this commit." | ||
mkdir -p "$WORKSPACE/ceph/build" | ||
echo "No files to analyze" > "$WORKSPACE/ceph/build/$output_file" | ||
# Create empty report to avoid potential CI issues | ||
echo "<?xml version='1.0' encoding='UTF-8'?><testsuites></testsuites>" > "$WORKSPACE/report.xml" | ||
exit 0 | ||
fi | ||
|
||
# Run clang-tidy only on modified files and save output | ||
{ | ||
echo "Files being checked:" | ||
cat "$file_list" | ||
echo | ||
# Add full path to files | ||
sed -i "s|^|$WORKSPACE/ceph/|" "$file_list" | ||
parallel -m clang-tidy -checks="-*,bugprone-use-after-move" -p "$WORKSPACE/ceph/build" {} < "$file_list" | ||
} | tee "$WORKSPACE/ceph/build/$output_file" | ||
|
||
# Generate the Clang-Tidy report | ||
sudo chmod +x clang-tidy-to-junit.py | ||
./clang-tidy-to-junit.py "$WORKSPACE/ceph/src" < "$WORKSPACE/ceph/build/$output_file" > "$WORKSPACE/report.xml" |
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,117 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import sys | ||
import collections | ||
import re | ||
import logging | ||
import itertools | ||
from xml.sax.saxutils import escape | ||
|
||
# Create a `ErrorDescription` tuple with all the information we want to keep. | ||
ErrorDescription = collections.namedtuple( | ||
'ErrorDescription', 'file line column error error_identifier description') | ||
|
||
|
||
class ClangTidyConverter: | ||
# All the errors encountered. | ||
errors = [] | ||
|
||
# Parses the error. | ||
# Group 1: file path | ||
# Group 2: line | ||
# Group 3: column | ||
# Group 4: error message | ||
# Group 5: error identifier | ||
error_regex = re.compile( | ||
r"^([\w\/\.\-\ ]+):(\d+):(\d+): (.+) (\[[\w\-,\.]+\])$") | ||
|
||
# This identifies the main error line (it has a [the-warning-type] at the end) | ||
# We only create a new error when we encounter one of those. | ||
main_error_identifier = re.compile(r'\[[\w\-,\.]+\]$') | ||
|
||
def __init__(self, basename): | ||
self.basename = basename | ||
|
||
def print_junit_file(self, output_file): | ||
# Write the header. | ||
output_file.write("""<?xml version="1.0" encoding="UTF-8" ?> | ||
<testsuites id="1" name="Clang-Tidy" tests="{error_count}" errors="{error_count}" failures="0" time="0">""".format(error_count=len(self.errors))) | ||
|
||
sorted_errors = sorted(self.errors, key=lambda x: x.file) | ||
|
||
# Iterate through the errors, grouped by file. | ||
for file, errorIterator in itertools.groupby(sorted_errors, key=lambda x: x.file): | ||
errors = list(errorIterator) | ||
error_count = len(errors) | ||
|
||
# Each file gets a test-suite | ||
output_file.write("""\n <testsuite errors="{error_count}" name="{file}" tests="{error_count}" failures="0" time="0">\n""" | ||
.format(error_count=error_count, file=file)) | ||
for error in errors: | ||
# Write each error as a test case. | ||
output_file.write(""" | ||
<testcase id="{id}" name="{id}" time="0"> | ||
<failure message="{message}"> | ||
{htmldata} | ||
</failure> | ||
</testcase>""".format(id="[{}/{}] {}".format(error.line, error.column, error.error_identifier), | ||
message=escape(error.error, entities={"\"": """}), | ||
htmldata=escape(error.description))) | ||
output_file.write("\n </testsuite>\n") | ||
output_file.write("</testsuites>\n") | ||
|
||
def process_error(self, error_array): | ||
if len(error_array) == 0: | ||
return | ||
|
||
result = self.error_regex.match(error_array[0]) | ||
if result is None: | ||
logging.warning( | ||
'Could not match error_array to regex: %s', error_array) | ||
return | ||
|
||
# We remove the `basename` from the `file_path` to make prettier filenames in the JUnit file. | ||
file_path = result.group(1).replace(self.basename, "") | ||
error = ErrorDescription(file_path, int(result.group(2)), int( | ||
result.group(3)), result.group(4), result.group(5), "\n".join(error_array[1:])) | ||
self.errors.append(error) | ||
|
||
def convert(self, input_file, output_file): | ||
# Collect all lines related to one error. | ||
current_error = [] | ||
for line in input_file: | ||
# If the line starts with a `/`, it is a line about a file. | ||
if line[0] == '/': | ||
# Look if it is the start of a error | ||
if self.main_error_identifier.search(line, re.M): | ||
# If so, process any `current_error` we might have | ||
self.process_error(current_error) | ||
# Initialize `current_error` with the first line of the error. | ||
current_error = [line] | ||
else: | ||
# Otherwise, append the line to the error. | ||
current_error.append(line) | ||
elif len(current_error) > 0: | ||
# If the line didn't start with a `/` and we have a `current_error`, we simply append | ||
# the line as additional information. | ||
current_error.append(line) | ||
else: | ||
pass | ||
|
||
# If we still have any current_error after we read all the lines, | ||
# process it. | ||
if len(current_error) > 0: | ||
self.process_error(current_error) | ||
|
||
# Print the junit file. | ||
self.print_junit_file(output_file) | ||
|
||
|
||
if __name__ == "__main__": | ||
if len(sys.argv) < 2: | ||
logging.error("Usage: %s base-filename-path", sys.argv[0]) | ||
logging.error( | ||
" base-filename-path: Removed from the filenames to make nicer paths.") | ||
sys.exit(1) | ||
converter = ClangTidyConverter(sys.argv[1]) | ||
converter.convert(sys.stdin, sys.stdout) |
55 changes: 55 additions & 0 deletions
55
ceph-pr-clang-tidy/config/definitions/ceph-pr-clang-tidy.yml
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,55 @@ | ||
- job: | ||
name: ceph-pr-clang-tidy | ||
node: jammy && small | ||
project-type: freestyle | ||
defaults: global | ||
display-name: 'ceph: Clang-tidy checks' | ||
concurrent: true | ||
quiet-period: 5 | ||
block-downstream: false | ||
block-upstream: false | ||
retry-count: 3 | ||
properties: | ||
- build-discarder: | ||
days-to-keep: 15 | ||
artifact-days-to-keep: 15 | ||
|
||
parameters: | ||
- string: | ||
name: BRANCH | ||
default: main | ||
triggers: | ||
- github-pull-request: | ||
allow-whitelist-orgs-as-admins: true | ||
org-list: | ||
- ceph | ||
only-trigger-phrase: false | ||
status-context: "Clang-tidy lint check" | ||
started-status: "checking if bugs exist" | ||
success-status: "no bugs found" | ||
failure-status: "bugs found" | ||
|
||
scm: | ||
- git: | ||
url: https://github.com/ceph/ceph.git | ||
branches: | ||
- $BRANCH | ||
browser: auto | ||
timeout: 20 | ||
shallow-clone: true | ||
wipe-workspace: true | ||
|
||
builders: | ||
- copyartifact: | ||
project: ceph-pull-requests | ||
|
||
- shell: | ||
!include-raw: | ||
- ../../../scripts/build_utils.sh | ||
- ../../build/build | ||
- ../../build/clang-tidy-to-junit.py | ||
|
||
publishers: | ||
- junit: | ||
results: report.xml | ||
allow-empty-results: true |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is the tar file being generated?
do we control the content of the file and make sure we only add
boost
andinclude
dirs are there?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tar file is generated in the Jenkins job
make check
. Once the job finishes its execution it will zip theboost
andinclude
directories.Yes we control the content of tar file, it is being controlled in the pull request: #2276