Skip to content
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

tools: Refactor python clang-format wrapping #2981

Merged
merged 7 commits into from
Aug 5, 2020

Conversation

Holzhaus
Copy link
Member

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.

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.
tools/clang_format.py Outdated Show resolved Hide resolved
Copy link
Member

@daschuer daschuer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for jumping in here.
I have left some comments.

tools/clang_format.py Outdated Show resolved Hide resolved
tools/clang_format.py Outdated Show resolved Hide resolved
tools/clang_format.py Outdated Show resolved Hide resolved
tools/clang_format.py Outdated Show resolved Hide resolved
tools/clang_format.py Outdated Show resolved Hide resolved
tools/clang_format.py Show resolved Hide resolved
start_added, _, length_added = match_lineno.group(2).partition(",")
lineno_removed = int(start_removed)
lineno_added = int(start_added)
lines_left = int(length_removed) if length_removed else 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lines_in_diff?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, i decrement this in the code below, so it's the remaing lines to parse. I renamed it to hunk_lines_left.

continue

if lines_left and line:
lines_left -= 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why -1?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use this for counting if we still need to parse lines of the hunk (to ignore lines that are not interesting for us)


logger = logging.getLogger(__name__)

cmd = ["git", "diff", "--unified=0", from_ref if from_ref else "HEAD"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot only use git diff, because in case of merge commits, the automatic merged lines are also reformatted.
In merge commits, we only want to check the resolution of merge conflicts.
This can be done with "git show"

Lines with conflict resolutions are marked with ++ or --

I think we can only do it with a single revision.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was original done with the
"git status --porcelain" call

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is worth the hassle, for various reasons:

  1. This is what the original git-clang-format does, too and wasn't aware of any issue with that.
  2. git show will only work for a single commit, so implementing --from-ref/PRE_COMMIT_FROM_REF will be a mess (and we adding support for that is the whole point of our custom script)
  3. For FF-only merges, this won't be an issue
  4. For merges this would re-run clang-format on the changed lines, but tbh all those lines should be pre-commit-clean anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. We already had strong issues with it in the PR of @hacksdump.
    Due to a merge with master many unrelated files have been reformatted. This must not happen, because it makes a PR hard to review.

  2. We have no use case for this, so it is fine to use it fro single commits only. At the users machine the user will commit only a single merge commit, so it is fine. In CI check it will check the PR against the master, so intermediate master merges are not considered.

  3. right

  4. No, If we merge master we merge legacy lines which are not clean. We must only check lines with solved conflicts.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have no use case for this, so it is fine to use it fro single commits only. At the users machine the user will commit only a single merge commit, so it is fine. In CI check it will check the PR against the master, so intermediate master merges are not considered.

Using git show is not possible. You can only use it to show a commit's diff, but this runs before committing, so we need to compare the working tree to a commit. I looked into the git documentation, but I see no real alternative.

No, If we merge master we merge legacy lines which are not clean. We must only check lines with solved conflicts.

This is only true for very old branches that didn't merge master since we introduced the clang-format pre-commit hook in January. Any code committed since then needs to be pre-commit clean anyway. I'm not sure that we even have such branches that are likely to be merged, and if so you can just SKIP=clang-format git pull upstream master for the merge.

We already had strong issues with it in the PR of @hacksdump.
Due to a merge with master many unrelated files have been reformatted. This must not happen, because it makes a PR hard to review.

In this case it's probably because the branch was old, so the merge included commits that were not formatted properly. I think this is unfortunate, but not critical and the clang-format hook can be skipped in that case.

"--patch",
"--unified=0",
from_ref if from_ref else "HEAD",
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow up of: #2981 (comment)

In case of merge commits we need to use here "git show" and use only ++lines containing resolved conflicts.

In case of the Travis check, we need to use:

git diff PRE_COMMIT_FROM_REF...PRE_COMMIT_TO_REF

to not include merge commits into the diff.

tools/githelper.py Show resolved Hide resolved
@Holzhaus Holzhaus requested a review from daschuer August 5, 2020 08:53
Copy link
Member

@daschuer daschuer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. LGTM.

Maybe it is time to propose this upstream.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants