-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
pre-commit: Add clang-tidy hook #2982
Conversation
This merges the clang-format and line-length hooks into a single one. Semantically, this makes way more sense. Also, this prevent multiple attempted commit that are rejected by pre-commit (pre-commit might skip the line-length hook if old clang-format hook already failed). Also, this removes any dependency on git-clang-format and implements the whole mechanism itself. It retrieves all added lines from the unified diff instead and is now capable of taking PRE_COMMIT_FROM_REF into account. By moving the git-related code into a separate githelper library, it's way easier to write additional python wrappers for new hooks, e.g. for clang-tidy.
--- | ||
Checks: '-*,modernize-use-nullptr,modernize-use-auto' | ||
WarningsAsErrors: '' | ||
HeaderFilterRegex: '' | ||
AnalyzeTemporaryDtors: false | ||
FormatStyle: none | ||
... |
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.
Don't do this! This will disable all checks for a standard run of clang-tidy across the project. The scope of checks for the hook is intentionally very narrow to be uncontroversial, but this shouldn't be the default for a normal run.
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.
You can still reenable the checks when running on the command line. We should strive to keep manual runs and the pre-commit invocations consistent. If we really add clang-tidy support, we should just add all desired checks to this config file IMHO.
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.
No, please not. Then it starts warning about all sorts of things that it can't automatically fix in the hook. Just don't.
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 main problem is that clang-tidy doesn't seem to completely restrict itself to the lines you limited it too, so it can quickly become very verbose.
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.
we should just add all desired checks to this config file IMHO.
Then it starts warning about all sorts of things that it can't automatically fix in the hook. Just don't.
The word desired is key here 😄 Support for auto-fixing is not a prerequite for using it in pre-commit though. We already have other hooks that may fail without auto-fix (certain eslint rules, qsscheck, etc.). The point is that it prevents us from committing questionable code.
Also, if we add a clang-tidy config file to the repo it also enables IDE/editors to pick it up and already warn us while writing code with the configuration tailored to Mixxx.
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.
Yes, currently my IDE is warning me about the clang tidy default checks, with this config this would all go away. If you really want a full-blown config then don't start with -*
.
But maybe we can start with a minimal one, because I am pretty sure some checks will be controversial and thus unneccessarily delay the merge.
--- | ||
Checks: '-*,modernize-use-nullptr,modernize-use-auto' | ||
WarningsAsErrors: '' | ||
HeaderFilterRegex: '' | ||
AnalyzeTemporaryDtors: false | ||
FormatStyle: none | ||
... |
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.
Yes, currently my IDE is warning me about the clang tidy default checks, with this config this would all go away. If you really want a full-blown config then don't start with -*
.
But maybe we can start with a minimal one, because I am pretty sure some checks will be controversial and thus unneccessarily delay the merge.
parser = argparse.ArgumentParser() | ||
parser.add_argument("--from-ref", help="compare against git reference") | ||
parser.add_argument("files", nargs="*", help="only check these files") | ||
args = parser.parse_args(argv) | ||
|
||
if not args.from_ref: | ||
args.from_ref = os.getenv("PRE_COMMIT_FROM_REF") or os.getenv( | ||
"PRE_COMMIT_SOURCE" | ||
) |
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.
I see repetition ;P
74d0429
to
1cfd829
Compare
1cfd829
to
c58faef
Compare
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 symlink to the compile_commands.json reveals a conceptual issue.
The pre-commit hook checks the source code independent from a build. While the test targets are checking the single build configurations config.
I think we need a different approach here. clang-tidy should become a part of the build system and should be treated the same as other compiler warnings.
Clang-tidy is then a special "warning level"
This way we have a Clang-tidy check for all our build targets.
A CI check can than verify that a build does not produce new CI warnings. Jenkins can do this, so I guess Travis and Appveyor are able to do this as well.
Interesting:
https://github.com/zemasoft/clangformat-cmake
@@ -319,6 +319,13 @@ if(CMAKE_VERSION VERSION_LESS "3.7.0") | |||
set(CMAKE_INCLUDE_CURRENT_DIR ON) | |||
endif() | |||
|
|||
# Export compile-commands.json and symlink it into the source directory (needed | |||
# for clang-tidy pre-commit hook) | |||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) |
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.
This should be remain a user option.
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.
What do you mean with a "user option"?
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.
it only creates a json-file in the cmake build directory, I don't see a need to ever disable that.
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) | ||
file(CREATE_LINK | ||
${CMAKE_BINARY_DIR}/compile_commands.json | ||
${CMAKE_SOURCE_DIR}/compile_commands.json SYMBOLIC) |
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.
This clutters the working directory. I think we should look out for an alternative solution.
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.
I struggled with this for hours, believe me. Supposedly adding the -p
argument to clang-tidy allows you to specify a directory where the json resides, but it did not work for me at all. And even if it worked - how do you know the name of the cmake build directory? It can be different for everyone.
Furthermore, this also enables you to run clang-tidy manually without any setup.
And it's not like we have a super-tidy working directory now ^^
@@ -0,0 +1,137 @@ | |||
#!/usr/bin/env python3 |
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.
Isn't this change obsolete now?
@@ -0,0 +1,85 @@ | |||
#!/usr/bin/env python3 |
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.
This file need to integrate the changes from clang_format.py form master.
I found out that this is uneeded with CMake. When running CMake you can easily do this:
Or even specify arguments:
Closing this. |
Can you describe this in the wiki? |
@Holzhaus but that way doesn't allow us to automatically update only changed lines? |
@Holzhaus please reopen. The whole point why I started this is to allow these things to be automatically fixed, which your solution doesn't do. Btw, we definitely also want this check ;) http://clang.llvm.org/extra/clang-tidy/checks/readability-braces-around-statements.html |
The problem is that his doesn't work properly because it relies on the I don't know how to solve this. I'd be in favor of adding a clang tidy config file to the repository and then relying on your editor to lint while typing, so that you can fix things manually. Using |
You can disable clang-tidy on CI - it was intended as a developer aid.
Sure, I am already doing that. But as stated above, that file should be much more generous with its checks and not start with
Maybe we can add this to pre-commit in a way that it is disabled by default and can be enabled with an environment variable? Otherwise I have to keep this local. This was an option for me from the very beginning, though it is not convenient. |
Adding braces, replacing NULL with nullptr... all mundane things that we have tools for. I don't want to keep wasting time on such things if we can easily automate them. Or as Uwe puts it: I just don't want to think about it! Every time I go from review to IDE to fix such a thing is an unnecessary context switch. |
So, we can't create a pre-commit hook that is disabled by default, but we can implement the hook in such a way that it only runs when a specific environment variable is set. Thus we shift the responsibility of making the compilation database available to the user. And if we get it working with clang-tidy, we could even use the environment variable not only as a flag, but it could contain the location of the compilation database, then we don't have to necessarily symlink it :) |
Follow up to #2981 and replaces #2975. Unsure if we want this, but I think it makes sense.