Skip to content

Commit

Permalink
Fix matching absolute paths
Browse files Browse the repository at this point in the history
  • Loading branch information
cpburnz committed Jun 12, 2021
1 parent 0761fac commit 4d6c0bd
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 9 deletions.
5 changes: 4 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
Change History
==============

0.8.2 (TDB)
0.9.0 (TDB)
-----------

- `Issue #45`_: Fix for duplicate leading double-asterisk, and edge cases.
- `Issue #46`_: Fix matching absolute paths.
- API change: `util.normalize_files()` now returns a `Dict[str, List[pathlike]]` instead of a `Dict[str, pathlike]`.

.. _`Issue #45`: https://github.com/cpburnz/python-path-specification/pull/45
.. _`Issue #46`: https://github.com/cpburnz/python-path-specification/issues/46


0.8.1 (2020-11-07)
Expand Down
5 changes: 3 additions & 2 deletions pathspec/pathspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,9 @@ def match_files(self, files, separators=None):

file_map = util.normalize_files(files, separators=separators)
matched_files = util.match_files(self.patterns, iterkeys(file_map))
for path in matched_files:
yield file_map[path]
for norm_file in matched_files:
for orig_file in file_map[norm_file]:
yield orig_file

def match_tree_entries(self, root, on_error=None, follow_links=None):
"""
Expand Down
46 changes: 46 additions & 0 deletions pathspec/tests/test_pathspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,52 @@ class PathSpecTest(unittest.TestCase):
The ``PathSpecTest`` class tests the ``PathSpec`` class.
"""

def test_01_absolute_dir_paths_1(self):
"""
Tests that absolute paths will be properly normalized and matched.
"""
spec = pathspec.PathSpec.from_lines('gitwildmatch', [
'foo',
])
results = set(spec.match_files([
'/a.py',
'/foo/a.py',
'/x/a.py',
'/x/foo/a.py',
'a.py',
'foo/a.py',
'x/a.py',
'x/foo/a.py',
]))
self.assertEqual(results, {
'/foo/a.py',
'/x/foo/a.py',
'foo/a.py',
'x/foo/a.py',
})

def test_01_absolute_dir_paths_2(self):
"""
Tests that absolute paths will be properly normalized and matched.
"""
spec = pathspec.PathSpec.from_lines('gitwildmatch', [
'/foo',
])
results = set(spec.match_files([
'/a.py',
'/foo/a.py',
'/x/a.py',
'/x/foo/a.py',
'a.py',
'foo/a.py',
'x/a.py',
'x/foo/a.py',
]))
self.assertEqual(results, {
'/foo/a.py',
'foo/a.py',
})

def test_01_current_dir_paths(self):
"""
Tests that paths referencing the current directory will be properly
Expand Down
23 changes: 17 additions & 6 deletions pathspec/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ def _normalize_entries(entries, separators=None):

def normalize_file(file, separators=None):
"""
Normalizes the file path to use the POSIX path separator (i.e., ``'/'``).
Normalizes the file path to use the POSIX path separator (i.e.,
``'/'``), and make the paths relative (remove leading ``'/'``).
*file* (:class:`str` or :class:`pathlib.PurePath`) is the file path.
Expand All @@ -323,8 +324,12 @@ def normalize_file(file, separators=None):
for sep in separators:
norm_file = norm_file.replace(sep, posixpath.sep)

# Remove current directory prefix.
if norm_file.startswith('./'):
if norm_file.startswith('/'):
# Make path relative.
norm_file = norm_file[1:]

elif norm_file.startswith('./'):
# Remove current directory prefix.
norm_file = norm_file[2:]

return norm_file
Expand All @@ -341,12 +346,18 @@ def normalize_files(files, separators=None):
:data:`None`) optionally contains the path separators to normalize.
See :func:`normalize_file` for more information.
Returns a :class:`dict` mapping the each normalized file path (:class:`str`)
to the original file path (:class:`str`)
Returns a :class:`dict` mapping the each normalized file path
(:class:`str`) to the original file paths (:class:`list` of
:class:`str`).
"""
norm_files = {}
for path in files:
norm_files[normalize_file(path, separators=separators)] = path
norm_file = normalize_file(path, separators=separators)
if norm_file in norm_files:
norm_files[norm_file].append(path)
else:
norm_files[norm_file] = [path]

return norm_files


Expand Down

0 comments on commit 4d6c0bd

Please sign in to comment.