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

Support checking executable bit without Git. #750

Closed
wants to merge 2 commits into from
Closed

Support checking executable bit without Git. #750

wants to merge 2 commits into from

Conversation

Kurt-von-Laven
Copy link
Contributor

@Kurt-von-Laven Kurt-von-Laven commented Apr 10, 2022

The check-shebang-scripts-are-executable hook already avoided false negatives in a Git repository by looking up the Git file mode rather than relying on the file mode in the file system. Git already automatically probes the file system for executable bit support. Use the file mode in the file system when we are not in a Git clone or it is trusted by Git according to its core.fileMode config variable.

Also, fix previously asymptomatic copy/paste bug in check_shebang_scripts_are_executable_test.test_git_executable_shebang exposed by the other commit. This test manually filtered executable files out before calling check_shebang_scripts_are_executable. This makes sense in the test it was copied from, check_executables_have_shebangs.test_git_executable_shebang, because the check-executables-have-shebangs hook only runs on executable files. However, check-shebang-scripts-are-executable correctly runs on all text files, so the test shouldn't filter executable files out. The test still passed because when git ls-files is passed no files in particular, it
lists all files in the Git repository that satisfy the given filters.

Closes #749.

@@ -9,6 +9,62 @@
from pre_commit_hooks.check_shebang_scripts_are_executable import main
from pre_commit_hooks.util import cmd_output

skip_win32 = pytest.mark.skipif(
Copy link
Member

Choose a reason for hiding this comment

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

these should be xfail if anything -- then you shouldn't need the no cover

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Neat function. I tried removing the no cover in the hook and the no covers in the test and got test coverage failures though. Did I miss something here?

Comment on lines -86 to -87
# simulate how identify chooses that something is executable
filenames = [path for path in [str(path)] if os.access(path, os.X_OK)]
Copy link
Member

Choose a reason for hiding this comment

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

this bit was important to demonstrate the windows behaviour

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Purely considering the -x case, I don't understand how assert main([]) == expected demonstrates behavior on Windows as opposed to demonstrating behavior when running the hook with pass_filenames: false. check-shebang-scripts-are-executable parses the mode from the output of git ls-files -z --stage -- in this case, which is why it still sees the one file. Maybe a more convincing test of behavior on Windows would be to set the filesystem mode to +x and the Git mode to -x to prove that it's reading from the latter. I believe the fact that your test matrix includes Windows already achieves the same effect though. In the +x case, the line above simplifies to filenames = [str(path)].

Comment on lines 20 to 23
return _check_git_filemode(paths) \
if fs_tracks_executable_bit == 'false' \
else _check_fs_filemode(paths)
Copy link
Member

Choose a reason for hiding this comment

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

don't use backslashes please

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed.

check_shebang_scripts_are_executable_test.test_git_executable_shebang
manually filtered executable files out before calling
check_shebang_scripts_are_executable. This makes sense in
check_executables_have_shebangs.test_git_executable_shebang, because
the check-executables-have-shebangs hook only runs on executable files.
However, check-shebang-scripts-are-executable correctly runs on all text
files, so the test shouldn't filter executable files out. The test still
passed because when git ls-files is passed no files in particular, it
lists all files in the Git repository that satisfy the given filters.
Copy link
Contributor Author

@Kurt-von-Laven Kurt-von-Laven 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 taking a look.

Comment on lines -86 to -87
# simulate how identify chooses that something is executable
filenames = [path for path in [str(path)] if os.access(path, os.X_OK)]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Purely considering the -x case, I don't understand how assert main([]) == expected demonstrates behavior on Windows as opposed to demonstrating behavior when running the hook with pass_filenames: false. check-shebang-scripts-are-executable parses the mode from the output of git ls-files -z --stage -- in this case, which is why it still sees the one file. Maybe a more convincing test of behavior on Windows would be to set the filesystem mode to +x and the Git mode to -x to prove that it's reading from the latter. I believe the fact that your test matrix includes Windows already achieves the same effect though. In the +x case, the line above simplifies to filenames = [str(path)].

Comment on lines 20 to 23
return _check_git_filemode(paths) \
if fs_tracks_executable_bit == 'false' \
else _check_fs_filemode(paths)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed.

@@ -9,6 +9,62 @@
from pre_commit_hooks.check_shebang_scripts_are_executable import main
from pre_commit_hooks.util import cmd_output

skip_win32 = pytest.mark.skipif(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Neat function. I tried removing the no cover in the hook and the no covers in the test and got test coverage failures though. Did I miss something here?

The check-shebang-scripts-are-executable hook already avoided false
negatives in a Git repository by looking up the Git file mode rather
than relying on the file mode in the file system. Git already
automatically probes the file system for executable bit support. Use the
file mode in the file system when we are not in a Git clone or it is
trusted by Git according to its core.fileMode config variable.
@Kurt-von-Laven
Copy link
Contributor Author

@asotille, please let me know if there's anything I should change about this pull request.

@Kurt-von-Laven Kurt-von-Laven closed this by deleting the head repository Nov 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

check-shebang-scripts-are-executable Assumes Git Repo
2 participants