Skip to content

Commit 3fde425

Browse files
committed
Simplify parse_gitignore and parse_gitignore_str to both delegate to _parse_gitignore_lines, simplify the interface of parse_gitignore_str.
1 parent 01eeb5e commit 3fde425

File tree

2 files changed

+31
-29
lines changed

2 files changed

+31
-29
lines changed

gitignore_parser.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,19 @@ def handle_negation(file_path, rules: Reversible["IgnoreRule"]):
1313
return False
1414

1515
def parse_gitignore(full_path, base_dir=None):
16-
with open(full_path) as ignore_file:
17-
return parse_gitignore_str(ignore_file.read(), full_path, base_dir)
18-
19-
def parse_gitignore_str(gitignore_str, full_path, base_dir=None):
2016
if base_dir is None:
2117
base_dir = dirname(full_path)
22-
base_dir = _normalize_path(base_dir)
18+
with open(full_path) as ignore_file:
19+
return _parse_gitignore_lines(ignore_file, full_path, base_dir)
20+
21+
def parse_gitignore_str(gitignore_str, base_dir):
22+
full_path = os.path.join(base_dir, '.gitignore')
23+
lines = gitignore_str.splitlines()
24+
return _parse_gitignore_lines(lines, full_path, base_dir)
25+
26+
def _parse_gitignore_lines(lines, full_path, base_dir):
2327
rules = []
24-
for line_no, line in enumerate(gitignore_str.splitlines(), start=1):
28+
for line_no, line in enumerate(lines, start=1):
2529
rule = rule_from_pattern(
2630
line.rstrip('\n'), base_path=base_dir, source=(full_path, line_no))
2731
if rule:

tests.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def test_simple(self):
1212
matches = parse_gitignore_str(
1313
'__pycache__/\n'
1414
'*.py[cod]',
15-
full_path='/home/michael/.gitignore'
15+
base_dir='/home/michael/'
1616
)
1717
self.assertFalse(matches('/home/michael/main.py'))
1818
self.assertTrue(matches('/home/michael/main.pyc'))
@@ -23,14 +23,14 @@ def test_simple_parse_file(self):
2323
with patch('builtins.open', mock_open(read_data=
2424
'__pycache__/\n'
2525
'*.py[cod]')):
26-
matches = parse_gitignore(full_path='/home/michael/.gitignore')
26+
matches = parse_gitignore('/home/michael/.gitignore')
2727
self.assertFalse(matches('/home/michael/main.py'))
2828
self.assertTrue(matches('/home/michael/main.pyc'))
2929
self.assertTrue(matches('/home/michael/dir/main.pyc'))
3030
self.assertTrue(matches('/home/michael/__pycache__'))
3131

3232
def test_incomplete_filename(self):
33-
matches = parse_gitignore_str('o.py', full_path='/home/michael/.gitignore')
33+
matches = parse_gitignore_str('o.py', base_dir='/home/michael/')
3434
self.assertTrue(matches('/home/michael/o.py'))
3535
self.assertFalse(matches('/home/michael/foo.py'))
3636
self.assertFalse(matches('/home/michael/o.pyc'))
@@ -41,7 +41,7 @@ def test_incomplete_filename(self):
4141
def test_wildcard(self):
4242
matches = parse_gitignore_str(
4343
'hello.*',
44-
full_path='/home/michael/.gitignore'
44+
base_dir='/home/michael/'
4545
)
4646
self.assertTrue(matches('/home/michael/hello.txt'))
4747
self.assertTrue(matches('/home/michael/hello.foobar/'))
@@ -53,7 +53,7 @@ def test_wildcard(self):
5353
def test_anchored_wildcard(self):
5454
matches = parse_gitignore_str(
5555
'/hello.*',
56-
full_path='/home/michael/.gitignore'
56+
base_dir='/home/michael/'
5757
)
5858
self.assertTrue(matches('/home/michael/hello.txt'))
5959
self.assertTrue(matches('/home/michael/hello.c'))
@@ -66,7 +66,7 @@ def test_trailingspaces(self):
6666
'partiallyignoredspace\\ \n'
6767
'partiallyignoredspace2 \\ \n'
6868
'notignoredmultiplespace\\ \\ \\ ',
69-
full_path='/home/michael/.gitignore'
69+
base_dir='/home/michael/'
7070
)
7171
self.assertTrue(matches('/home/michael/ignoretrailingspace'))
7272
self.assertFalse(matches('/home/michael/ignoretrailingspace '))
@@ -88,7 +88,7 @@ def test_comment(self):
8888
'#realcomment\n'
8989
'othermatch\n'
9090
'\\#imnocomment',
91-
full_path='/home/michael/.gitignore'
91+
base_dir='/home/michael/'
9292
)
9393
self.assertTrue(matches('/home/michael/somematch'))
9494
self.assertFalse(matches('/home/michael/#realcomment'))
@@ -97,7 +97,7 @@ def test_comment(self):
9797

9898
def test_ignore_directory(self):
9999
matches = \
100-
parse_gitignore_str('.venv/', full_path='/home/michael/.gitignore')
100+
parse_gitignore_str('.venv/', base_dir='/home/michael/')
101101
self.assertTrue(matches('/home/michael/.venv'))
102102
self.assertTrue(matches('/home/michael/.venv/folder'))
103103
self.assertTrue(matches('/home/michael/.venv/file.txt'))
@@ -106,7 +106,7 @@ def test_ignore_directory(self):
106106

107107
def test_ignore_directory_asterisk(self):
108108
matches = \
109-
parse_gitignore_str('.venv/*', full_path='/home/michael/.gitignore')
109+
parse_gitignore_str('.venv/*', base_dir='/home/michael/')
110110
self.assertFalse(matches('/home/michael/.venv'))
111111
self.assertTrue(matches('/home/michael/.venv/folder'))
112112
self.assertTrue(matches('/home/michael/.venv/file.txt'))
@@ -117,23 +117,23 @@ def test_negation(self):
117117
*.ignore
118118
!keep.ignore
119119
''',
120-
full_path='/home/michael/.gitignore'
120+
base_dir='/home/michael/'
121121
)
122122
self.assertTrue(matches('/home/michael/trash.ignore'))
123123
self.assertFalse(matches('/home/michael/keep.ignore'))
124124
self.assertTrue(matches('/home/michael/waste.ignore'))
125125

126126
def test_literal_exclamation_mark(self):
127127
matches = parse_gitignore_str(
128-
'\\!ignore_me!', full_path='/home/michael/.gitignore'
128+
'\\!ignore_me!', base_dir='/home/michael/'
129129
)
130130
self.assertTrue(matches('/home/michael/!ignore_me!'))
131131
self.assertFalse(matches('/home/michael/ignore_me!'))
132132
self.assertFalse(matches('/home/michael/ignore_me'))
133133

134134
def test_double_asterisks(self):
135135
matches = parse_gitignore_str(
136-
'foo/**/Bar', full_path='/home/michael/.gitignore'
136+
'foo/**/Bar', base_dir='/home/michael/'
137137
)
138138
self.assertTrue(matches('/home/michael/foo/hello/Bar'))
139139
self.assertTrue(matches('/home/michael/foo/world/Bar'))
@@ -142,7 +142,7 @@ def test_double_asterisks(self):
142142

143143
def test_double_asterisk_without_slashes_handled_like_single_asterisk(self):
144144
matches = \
145-
parse_gitignore_str('a/b**c/d', full_path='/home/michael/.gitignore')
145+
parse_gitignore_str('a/b**c/d', base_dir='/home/michael/')
146146
self.assertTrue(matches('/home/michael/a/bc/d'))
147147
self.assertTrue(matches('/home/michael/a/bXc/d'))
148148
self.assertTrue(matches('/home/michael/a/bbc/d'))
@@ -154,11 +154,11 @@ def test_double_asterisk_without_slashes_handled_like_single_asterisk(self):
154154

155155
def test_more_asterisks_handled_like_single_asterisk(self):
156156
matches = \
157-
parse_gitignore_str('***a/b', full_path='/home/michael/.gitignore')
157+
parse_gitignore_str('***a/b', base_dir='/home/michael/')
158158
self.assertTrue(matches('/home/michael/XYZa/b'))
159159
self.assertFalse(matches('/home/michael/foo/a/b'))
160160
matches = \
161-
parse_gitignore_str('a/b***', full_path='/home/michael/.gitignore')
161+
parse_gitignore_str('a/b***', base_dir='/home/michael/')
162162
self.assertTrue(matches('/home/michael/a/bXYZ'))
163163
self.assertFalse(matches('/home/michael/a/b/foo'))
164164

@@ -169,7 +169,7 @@ def test_directory_only_negation(self):
169169
!.gitkeep
170170
!data/01_raw/*
171171
''',
172-
full_path='/home/michael/.gitignore'
172+
base_dir='/home/michael/'
173173
)
174174
self.assertFalse(matches('/home/michael/data/01_raw/'))
175175
self.assertFalse(matches('/home/michael/data/01_raw/.gitkeep'))
@@ -181,21 +181,21 @@ def test_directory_only_negation(self):
181181
)
182182

183183
def test_single_asterisk(self):
184-
matches = parse_gitignore_str('*', full_path='/home/michael/.gitignore')
184+
matches = parse_gitignore_str('*', base_dir='/home/michael/')
185185
self.assertTrue(matches('/home/michael/file.txt'))
186186
self.assertTrue(matches('/home/michael/directory'))
187187
self.assertTrue(matches('/home/michael/directory-trailing/'))
188188

189189
def test_supports_path_type_argument(self):
190190
matches = parse_gitignore_str(
191-
'file1\n!file2', full_path='/home/michael/.gitignore'
191+
'file1\n!file2', base_dir='/home/michael/'
192192
)
193193
self.assertTrue(matches(Path('/home/michael/file1')))
194194
self.assertFalse(matches(Path('/home/michael/file2')))
195195

196196
def test_slash_in_range_does_not_match_dirs(self):
197197
matches = parse_gitignore_str(
198-
'abc[X-Z/]def', full_path='/home/michael/.gitignore'
198+
'abc[X-Z/]def', base_dir='/home/michael/'
199199
)
200200
self.assertFalse(matches('/home/michael/abcdef'))
201201
self.assertTrue(matches('/home/michael/abcXdef'))
@@ -207,8 +207,7 @@ def test_slash_in_range_does_not_match_dirs(self):
207207
def test_symlink_to_another_directory(self):
208208
with TemporaryDirectory() as project_dir:
209209
with TemporaryDirectory() as another_dir:
210-
matches = \
211-
parse_gitignore_str('link', full_path=f"{project_dir}/.gitignore")
210+
matches = parse_gitignore_str('link', base_dir=project_dir)
212211

213212
# Create a symlink to another directory.
214213
link = Path(project_dir, 'link')
@@ -227,8 +226,7 @@ def test_symlink_to_symlink_directory(self):
227226
link = Path(link_dir, 'link')
228227
link.symlink_to(project_dir)
229228
file = Path(link, 'file.txt')
230-
matches = \
231-
parse_gitignore_str('file.txt', full_path=f"{link_dir}/.gitignore")
229+
matches = parse_gitignore_str('file.txt', base_dir=str(link_dir))
232230
self.assertTrue(matches(file))
233231

234232

0 commit comments

Comments
 (0)