From 9a35b62ab7309a87fb7d74d8c6e99b067cf8d54b Mon Sep 17 00:00:00 2001 From: Krystian Chmura Date: Fri, 19 Mar 2021 00:59:31 +0100 Subject: [PATCH] check also directories in check_case_conflict fix #70 --- pre_commit_hooks/check_case_conflict.py | 22 ++++++++++---- tests/check_case_conflict_test.py | 39 +++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/pre_commit_hooks/check_case_conflict.py b/pre_commit_hooks/check_case_conflict.py index 6b8ba82f..a6b986b3 100644 --- a/pre_commit_hooks/check_case_conflict.py +++ b/pre_commit_hooks/check_case_conflict.py @@ -1,4 +1,5 @@ import argparse +import pathlib from typing import Iterable from typing import Optional from typing import Sequence @@ -12,9 +13,20 @@ def lower_set(iterable: Iterable[str]) -> Set[str]: return {x.lower() for x in iterable} +def add_directories(files: Set[str]) -> Set[str]: + directories = { + parent.as_posix() + for file in files + for parent in pathlib.PurePosixPath(file).parents + } + return files | directories + + def find_conflicting_filenames(filenames: Sequence[str]) -> int: - repo_files = set(cmd_output('git', 'ls-files').splitlines()) - relevant_files = set(filenames) | added_files() + repo_files = add_directories( + set(cmd_output('git', 'ls-files').splitlines()), + ) + relevant_files = add_directories(set(filenames) | added_files()) repo_files -= relevant_files retv = 0 @@ -31,8 +43,7 @@ def find_conflicting_filenames(filenames: Sequence[str]) -> int: if conflicts: conflicting_files = [ - x for x in repo_files | relevant_files - if x.lower() in conflicts + x for x in repo_files | relevant_files if x.lower() in conflicts ] for filename in sorted(conflicting_files): print(f'Case-insensitivity conflict found: {filename}') @@ -44,7 +55,8 @@ def find_conflicting_filenames(filenames: Sequence[str]) -> int: def main(argv: Optional[Sequence[str]] = None) -> int: parser = argparse.ArgumentParser() parser.add_argument( - 'filenames', nargs='*', + 'filenames', + nargs='*', help='Filenames pre-commit believes are changed.', ) diff --git a/tests/check_case_conflict_test.py b/tests/check_case_conflict_test.py index 53de852e..6125bb3f 100644 --- a/tests/check_case_conflict_test.py +++ b/tests/check_case_conflict_test.py @@ -26,6 +26,33 @@ def test_adding_something_with_conflict(temp_git_dir): assert find_conflicting_filenames(['f.py', 'F.py']) == 1 +def test_adding_files_with_conflicting_directories(temp_git_dir): + with temp_git_dir.as_cwd(): + temp_git_dir.mkdir('dir').join('x').write('foo') + temp_git_dir.mkdir('DIR').join('y').write('foo') + cmd_output('git', 'add', '-A') + + assert find_conflicting_filenames([]) == 1 + + +def test_adding_files_with_conflicting_deep_directories(temp_git_dir): + with temp_git_dir.as_cwd(): + temp_git_dir.mkdir('x').mkdir('y').join('z').write('foo') + temp_git_dir.join('X').write('foo') + cmd_output('git', 'add', '-A') + + assert find_conflicting_filenames([]) == 1 + + +def test_adding_file_with_conflicting_directory(temp_git_dir): + with temp_git_dir.as_cwd(): + temp_git_dir.mkdir('dir').join('x').write('foo') + temp_git_dir.join('DIR').write('foo') + cmd_output('git', 'add', '-A') + + assert find_conflicting_filenames([]) == 1 + + def test_added_file_not_in_pre_commits_list(temp_git_dir): with temp_git_dir.as_cwd(): temp_git_dir.join('f.py').write("print('hello world')") @@ -46,6 +73,18 @@ def test_file_conflicts_with_committed_file(temp_git_dir): assert find_conflicting_filenames(['F.py']) == 1 +def test_file_conflicts_with_committed_dir(temp_git_dir): + with temp_git_dir.as_cwd(): + temp_git_dir.mkdir('dir').join('x').write('foo') + cmd_output('git', 'add', '-A') + cmd_output('git', 'commit', '--no-gpg-sign', '-n', '-m', 'Add f.py') + + temp_git_dir.join('DIR').write('foo') + cmd_output('git', 'add', '-A') + + assert find_conflicting_filenames([]) == 1 + + def test_integration(temp_git_dir): with temp_git_dir.as_cwd(): assert main(argv=[]) == 0