Skip to content

Commit

Permalink
Fixes #45.
Browse files Browse the repository at this point in the history
The discover function now no longer traverses directories when it's
passed the specified `depth` or `treantdepth` parameters. Added proper
tests to make sure these parameters function as expected.
  • Loading branch information
dotsdl committed Apr 11, 2016
1 parent 03fad6e commit 6ec7679
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 14 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ Fixes
automatically get all limbs of the object they were obtained from;
set operations between Views/Bundles will give unions of their attached
limbs
* ``datreant.core.discover`` no longer traverses directories beyond given
depth, or beyond treantdepth. These parameters now work as expected. #45


Changes
Expand Down
34 changes: 20 additions & 14 deletions src/datreant/core/manipulators.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
import scandir
import fnmatch
from six.moves import range

from . import _TREANTS

Expand Down Expand Up @@ -45,30 +46,35 @@ def discover(dirpath='.', depth=None, treantdepth=None):
treantdirs = set()

for root, dirs, files in scandir.walk(dirpath):
# depth check; if too deep, next iteration
if depth and len(root.split(os.sep)) - startdepth > depth:
for treanttype in _TREANTS:
outnames = fnmatch.filter(files,
"{}.*.json".format(treanttype))

if treantdepth is not None and outnames:
treantdirs.add(root)

paths = [os.path.join(root, file) for file in outnames]
found.extend(paths)

# depth check; if too deep, empty dirs to avoid downward traversal
if depth is not None and len(root.split(os.sep)) - startdepth >= depth:
for i in range(len(dirs)):
dirs.pop()
continue

# Treant depth checking
if treantdepth:
if treantdepth is not None:

# remove Treant dirs from our set of them if we've backed out
for treantdir in list(treantdirs):
if treantdir not in root:
treantdirs.remove(treantdir)

# actual depth check
# actual depth check; if too deep, empty dirs to avoid downward
# traversal
if len(treantdirs) > treantdepth:
for i in range(len(dirs)):
dirs.pop()
continue

for treanttype in _TREANTS:
outnames = fnmatch.filter(files,
"{}.*.json".format(treanttype))

if treantdepth and outnames:
treantdirs.add(root)

paths = [os.path.join(root, file) for file in outnames]
found.extend(paths)

return Bundle(found)
72 changes: 72 additions & 0 deletions src/datreant/core/tests/test_manipulators.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,75 @@ def test_discover(tmpdir):

for name in ghosts:
assert name in b.names


def test_discover_depth(tmpdir):
"""Check that using `depth` parameter gives expected result."""
with tmpdir.as_cwd():

ghosts = ('something/inky',
'something/else/blinky',
'pinky',
'something/clyde')

for name in ghosts:
dtr.Treant(name)

assert len(discover('.', depth=0)) == 0
assert len(discover('pinky', depth=0)) == 1

assert len(discover('.', depth=1)) == 1
assert len(discover('.', depth=2)) == 3
assert len(discover('.', depth=3)) == 4


def test_discover_treantdepth(tmpdir):
"""Check that using `treantdepth` parameter gives expected result."""
with tmpdir.as_cwd():

ghosts = ('inky',
'inky/blinky',
'pinky',
'inky/blinky/clyde')

for name in ghosts:
dtr.Treant(name)

assert len(discover('.', treantdepth=0)) == 2
assert len(discover('pinky', treantdepth=0)) == 1
assert len(discover('inky', treantdepth=0)) == 1

assert len(discover('.', treantdepth=1)) == 3
assert len(discover('.', treantdepth=2)) == 4
assert len(discover('inky', treantdepth=1)) == 2
assert len(discover('inky/blinky', treantdepth=1)) == 2

assert len(discover('inky/blinky', treantdepth=1)) == 2


def test_discover_depth_treantdepth(tmpdir):
"""Check that using `treantdepth` and `depth` parameters together gives
expected result.
"""
with tmpdir.as_cwd():

ghosts = ('inky',
'inky/blinky',
'pinky',
'inky/blinky/nothing/clyde')

for name in ghosts:
dtr.Treant(name)

assert len(discover('.', treantdepth=0, depth=0)) == 0
assert len(discover('.', treantdepth=0, depth=1)) == 2
assert len(discover('pinky', treantdepth=0, depth=0)) == 1
assert len(discover('inky', treantdepth=0, depth=2)) == 1

assert len(discover('.', treantdepth=1, depth=1)) == 2
assert len(discover('inky', treantdepth=1, depth=1)) == 2
assert len(discover('inky', treantdepth=1, depth=0)) == 1

assert len(discover('inky', treantdepth=2)) == 3
assert len(discover('inky', treantdepth=2, depth=2)) == 2
assert len(discover('inky', treantdepth=2, depth=3)) == 3

0 comments on commit 6ec7679

Please sign in to comment.