Skip to content

Commit ae47531

Browse files
authored
Merge pull request #575 from slsyy/master
check also directories in check_case_conflict
2 parents 3db0cc5 + f681234 commit ae47531

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

pre_commit_hooks/check_case_conflict.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import argparse
2+
import os.path
23
from typing import Iterable
4+
from typing import Iterator
35
from typing import Optional
46
from typing import Sequence
57
from typing import Set
@@ -12,9 +14,22 @@ def lower_set(iterable: Iterable[str]) -> Set[str]:
1214
return {x.lower() for x in iterable}
1315

1416

17+
def parents(file: str) -> Iterator[str]:
18+
file = os.path.dirname(file)
19+
while file:
20+
yield file
21+
file = os.path.dirname(file)
22+
23+
24+
def directories_for(files: Set[str]) -> Set[str]:
25+
return {parent for file in files for parent in parents(file)}
26+
27+
1528
def find_conflicting_filenames(filenames: Sequence[str]) -> int:
1629
repo_files = set(cmd_output('git', 'ls-files').splitlines())
30+
repo_files |= directories_for(repo_files)
1731
relevant_files = set(filenames) | added_files()
32+
relevant_files |= directories_for(relevant_files)
1833
repo_files -= relevant_files
1934
retv = 0
2035

tests/check_case_conflict_test.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
1+
import sys
2+
3+
import pytest
4+
15
from pre_commit_hooks.check_case_conflict import find_conflicting_filenames
26
from pre_commit_hooks.check_case_conflict import main
7+
from pre_commit_hooks.check_case_conflict import parents
38
from pre_commit_hooks.util import cmd_output
49

10+
skip_win32 = pytest.mark.skipif(
11+
sys.platform == 'win32',
12+
reason='case conflicts between directories and files',
13+
)
14+
15+
16+
def test_parents():
17+
assert set(parents('a')) == set()
18+
assert set(parents('a/b')) == {'a'}
19+
assert set(parents('a/b/c')) == {'a/b', 'a'}
20+
assert set(parents('a/b/c/d')) == {'a/b/c', 'a/b', 'a'}
21+
522

623
def test_nothing_added(temp_git_dir):
724
with temp_git_dir.as_cwd():
@@ -26,6 +43,36 @@ def test_adding_something_with_conflict(temp_git_dir):
2643
assert find_conflicting_filenames(['f.py', 'F.py']) == 1
2744

2845

46+
@skip_win32 # pragma: win32 no cover
47+
def test_adding_files_with_conflicting_directories(temp_git_dir):
48+
with temp_git_dir.as_cwd():
49+
temp_git_dir.mkdir('dir').join('x').write('foo')
50+
temp_git_dir.mkdir('DIR').join('y').write('foo')
51+
cmd_output('git', 'add', '-A')
52+
53+
assert find_conflicting_filenames([]) == 1
54+
55+
56+
@skip_win32 # pragma: win32 no cover
57+
def test_adding_files_with_conflicting_deep_directories(temp_git_dir):
58+
with temp_git_dir.as_cwd():
59+
temp_git_dir.mkdir('x').mkdir('y').join('z').write('foo')
60+
temp_git_dir.join('X').write('foo')
61+
cmd_output('git', 'add', '-A')
62+
63+
assert find_conflicting_filenames([]) == 1
64+
65+
66+
@skip_win32 # pragma: win32 no cover
67+
def test_adding_file_with_conflicting_directory(temp_git_dir):
68+
with temp_git_dir.as_cwd():
69+
temp_git_dir.mkdir('dir').join('x').write('foo')
70+
temp_git_dir.join('DIR').write('foo')
71+
cmd_output('git', 'add', '-A')
72+
73+
assert find_conflicting_filenames([]) == 1
74+
75+
2976
def test_added_file_not_in_pre_commits_list(temp_git_dir):
3077
with temp_git_dir.as_cwd():
3178
temp_git_dir.join('f.py').write("print('hello world')")
@@ -46,6 +93,19 @@ def test_file_conflicts_with_committed_file(temp_git_dir):
4693
assert find_conflicting_filenames(['F.py']) == 1
4794

4895

96+
@skip_win32 # pragma: win32 no cover
97+
def test_file_conflicts_with_committed_dir(temp_git_dir):
98+
with temp_git_dir.as_cwd():
99+
temp_git_dir.mkdir('dir').join('x').write('foo')
100+
cmd_output('git', 'add', '-A')
101+
cmd_output('git', 'commit', '--no-gpg-sign', '-n', '-m', 'Add f.py')
102+
103+
temp_git_dir.join('DIR').write('foo')
104+
cmd_output('git', 'add', '-A')
105+
106+
assert find_conflicting_filenames([]) == 1
107+
108+
49109
def test_integration(temp_git_dir):
50110
with temp_git_dir.as_cwd():
51111
assert main(argv=[]) == 0

0 commit comments

Comments
 (0)