Bug 1168607 - Add get method to finders; r=glandium

Today, the *Finder classes are optimized for doing matching and
returning multiple results. However, sometimes only looking for a
single file is wanted.

This commit implements the "get" method on all the *Finder classes.
It returns a BaseFile or None.

FileFinder._find_file has been refactored into FileFinder.get
to avoid code duplication.
This commit is contained in:
Gregory Szorc 2015-06-04 11:24:03 -07:00
parent 921ab27a26
commit b4a637bb54
2 changed files with 37 additions and 10 deletions

View File

@ -713,6 +713,20 @@ class BaseFinder(object):
for p, f in self._find(pattern):
yield p, self._minify_file(p, f)
def get(self, path):
"""Obtain a single file.
Where ``find`` is tailored towards matching multiple files, this method
is used for retrieving a single file. Use this method when performance
is critical.
Returns a ``BaseFile`` if at most one file exists or ``None`` otherwise.
"""
files = list(self.find(path))
if len(files) != 1:
return None
return files[0][1]
def __iter__(self):
'''
Iterates over all files under the base directory (excluding files
@ -788,7 +802,8 @@ class FileFinder(BaseFinder):
elif os.path.isdir(os.path.join(self.base, pattern)):
return self._find_dir(pattern)
else:
return self._find_file(pattern)
f = self.get(pattern)
return ((pattern, f),) if f else ()
def _find_dir(self, path):
'''
@ -810,23 +825,19 @@ class FileFinder(BaseFinder):
for p_, f in self._find(mozpath.join(path, p)):
yield p_, f
def _find_file(self, path):
'''
Actual implementation of FileFinder.find() when the given pattern
corresponds to an existing file under the base directory.
'''
def get(self, path):
srcpath = os.path.join(self.base, path)
if not os.path.exists(srcpath):
return
return None
for p in self.ignore:
if mozpath.match(path, p):
return
return None
if self.find_executables and is_executable(srcpath):
yield path, ExecutableFile(srcpath)
return ExecutableFile(srcpath)
else:
yield path, File(srcpath)
return File(srcpath)
def _find_glob(self, base, pattern):
'''

View File

@ -911,6 +911,16 @@ class TestFileFinder(MatchTestTemplate, TestWithTmpDir):
self.do_match_test()
self.do_finder_test(self.finder)
def test_get(self):
self.prepare_match_test()
finder = FileFinder(self.tmpdir)
self.assertIsNone(finder.get('does-not-exist'))
res = finder.get('bar')
self.assertIsInstance(res, File)
self.assertEqual(mozpath.normpath(res.path),
mozpath.join(self.tmpdir, 'bar'))
def test_ignored_dirs(self):
"""Ignored directories should not have results returned."""
self.prepare_match_test()
@ -969,6 +979,9 @@ class TestJarFinder(MatchTestTemplate, TestWithTmpDir):
self.finder = JarFinder(self.tmppath('test.jar'), reader)
self.do_match_test()
self.assertIsNone(self.finder.get('does-not-exist'))
self.assertIsInstance(self.finder.get('bar'), DeflatedFile)
class TestComposedFinder(MatchTestTemplate, TestWithTmpDir):
def add(self, path, content=None):
@ -1000,6 +1013,9 @@ class TestComposedFinder(MatchTestTemplate, TestWithTmpDir):
})
self.do_match_test()
self.assertIsNone(self.finder.get('does-not-exist'))
self.assertIsInstance(self.finder.get('bar'), File)
if __name__ == '__main__':
mozunit.main()