Skip to content

Commit

Permalink
Fix issue with globstar not returning some dotfiles when it should (#111
Browse files Browse the repository at this point in the history
)
  • Loading branch information
facelessuser authored Jun 23, 2020
1 parent e5d6123 commit 3b3511c
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 13 deletions.
5 changes: 5 additions & 0 deletions docs/src/markdown/about/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 6.0.2

- **FIX**: Fix login related to dot files and `GLOBSTAR`. Recursive directory search should return all dot files, which
should then be filtered by the patterns. They should not be excluded before being filtered by the pattern.

## 6.0.1

- **FIX**: If we only have one pattern (exclusion patterns not included) we can disable unique path filtering on returns
Expand Down
31 changes: 31 additions & 0 deletions tests/test_glob.py
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,31 @@ class TestGlobMarked(Testglob):
DEFAULT_FLAGS = glob.BRACE | glob.EXTGLOB | glob.GLOBSTAR | glob.FOLLOW | glob.MARK


class TestHidden(_TestGlob):
"""Test hidden specific cases."""

cases = [
[('**', '.*'), [('a', '.'), ('a', '..'), ('.aa',), ('.bb',), ('.',), ('..',)]],
[('*', '.*'), [('a', '.'), ('a', '..')]],
[('.*',), [('.aa',), ('.bb',), ('.',), ('..',)]]
]

@classmethod
def setup_fs(cls):
"""Setup file system."""

cls.mktemp('a', 'D')
cls.mktemp('a', 'a')
cls.mktemp('.aa', 'G')
cls.mktemp('.bb', 'H')

@pytest.mark.parametrize("case", cases)
def test_glob_cases(self, case):
"""Test glob cases."""

self.eval_glob_cases(case)


class TestCWD(_TestGlob):
"""Test files in the current working directory."""

Expand All @@ -908,6 +933,12 @@ def setup_fs(cls):
os.symlink('broken', cls.norm('sym2'))
os.symlink(os.path.join('a', 'bcd'), cls.norm('sym3'))

def test_dots_cwd(self):
"""Test capture of dot files with recursive glob."""

with change_cwd(self.tempdir):
self.assert_equal(sorted(glob.glob(['**/.*', '!**/.', '!**/..'], flags=glob.G | glob.N)), ['.aa', '.bb'])

def test_cwd(self):
"""Test root level glob on current working directory."""

Expand Down
22 changes: 9 additions & 13 deletions wcmatch/glob.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ def _iter(self, curdir, dir_only, deep):

# Python will never return . or .., so fake it.
for special in self.specials:
yield special, True
yield special, True, True

try:
if NO_SCANDIR_WORKAROUND:
Expand All @@ -288,9 +288,7 @@ def _iter(self, curdir, dir_only, deep):
with os.scandir(scandir) as scan:
for f in scan:
try:
# Quicker to just test this way than to run through `fnmatch`.
if deep and self._is_hidden(f.name):
continue
hidden = self._is_hidden(f.name)
try:
is_dir = f.is_dir()
except OSError: # pragma: no cover
Expand All @@ -303,14 +301,12 @@ def _iter(self, curdir, dir_only, deep):
if deep and not self.follow_links and is_link:
continue
if (not dir_only or is_dir):
yield f.name, is_dir
yield f.name, is_dir, hidden
except OSError: # pragma: no cover
pass
else:
for f in os.listdir(scandir):
# Quicker to just test this way than to run through `fnmatch`.
if deep and self._is_hidden(f):
continue
hidden = self._is_hidden(f)
path = os.path.join(scandir, f)
try:
is_dir = os.path.isdir(path)
Expand All @@ -323,7 +319,7 @@ def _iter(self, curdir, dir_only, deep):
if deep and not self.follow_links and is_link:
continue
if (not dir_only or is_dir):
yield f, is_dir
yield f, is_dir, hidden

except OSError: # pragma: no cover
pass
Expand All @@ -332,17 +328,17 @@ def _glob_dir(self, curdir, matcher, dir_only=False, deep=False):
"""Recursive directory glob."""

files = list(self._iter(curdir, dir_only, deep))
for file, is_dir in files:
for file, is_dir, hidden in files:
if file in self.specials:
if matcher is not None and matcher(file):
yield os.path.join(curdir, file), True
continue

path = os.path.join(curdir, file)
if matcher is None or matcher(file):
if (matcher is None and not hidden) or (matcher and matcher(file)):
yield path, is_dir

if deep and is_dir:
if deep and not hidden and is_dir:
yield from self._glob_dir(path, matcher, dir_only, deep)

def _glob(self, curdir, this, rest):
Expand Down Expand Up @@ -434,7 +430,7 @@ def _get_starting_paths(self, curdir, dir_only):
results = []
matcher = self._get_matcher(curdir)
files = list(self._iter(None, dir_only, False))
for file, is_dir in files:
for file, is_dir, hidden in files:
if file not in self.specials and (matcher is None or matcher(file)):
results.append((file, is_dir))
else:
Expand Down

0 comments on commit 3b3511c

Please sign in to comment.