Bug 1147207 - Add a ComposedFinder class that acts like a FileFinder proxy over multiple FileFinders. r=gps

This commit is contained in:
Mike Hommey 2015-03-26 12:07:17 +09:00
parent cf36c9a4c6
commit 6ad063c793
2 changed files with 63 additions and 0 deletions

View File

@ -885,3 +885,30 @@ class JarFinder(BaseFinder):
for p in self._files:
if mozpath.basedir(p, [pattern]) == pattern:
yield p, DeflatedFile(self._files[p])
class ComposedFinder(BaseFinder):
'''
Composes multiple File Finders in some sort of virtual file system.
A ComposedFinder is initialized from a dictionary associating paths to
*Finder instances.
Note this could be optimized to be smarter than getting all the files
in advance.
'''
def __init__(self, finders):
# Can't import globally, because of the dependency of mozpack.copier
# on this module.
from mozpack.copier import FileRegistry
self.files = FileRegistry()
for base, finder in sorted(finders.iteritems()):
if self.files.contains(base):
self.files.remove(base)
for p, f in finder.find(''):
self.files.add(mozpath.join(base, p), f)
def find(self, pattern):
for p in self.files.match(pattern):
yield p, self.files[p]

View File

@ -10,6 +10,7 @@ from mozpack.errors import (
)
from mozpack.files import (
AbsoluteSymlinkFile,
ComposedFinder,
DeflatedFile,
Dest,
ExistingFile,
@ -852,6 +853,10 @@ class MatchTestTemplate(object):
self.do_check('foo/*/2/test*', ['foo/qux/2/test', 'foo/qux/2/test2'])
self.do_check('**/bar', ['bar', 'foo/bar', 'foo/qux/bar'])
self.do_check('foo/**/test', ['foo/qux/2/test'])
self.do_check('foo', [
'foo/bar', 'foo/baz', 'foo/qux/1', 'foo/qux/bar',
'foo/qux/2/test', 'foo/qux/2/test2'
])
self.do_check('foo/**', [
'foo/bar', 'foo/baz', 'foo/qux/1', 'foo/qux/bar',
'foo/qux/2/test', 'foo/qux/2/test2'
@ -965,5 +970,36 @@ class TestJarFinder(MatchTestTemplate, TestWithTmpDir):
self.do_match_test()
class TestComposedFinder(MatchTestTemplate, TestWithTmpDir):
def add(self, path, content=None):
# Put foo/qux files under $tmp/b.
if path.startswith('foo/qux/'):
real_path = mozpath.join('b', path[8:])
else:
real_path = mozpath.join('a', path)
ensureParentDir(self.tmppath(real_path))
if not content:
content = path
open(self.tmppath(real_path), 'wb').write(content)
def do_check(self, pattern, result):
if '*' in pattern:
return
do_check(self, self.finder, pattern, result)
def test_composed_finder(self):
self.prepare_match_test()
# Also add files in $tmp/a/foo/qux because ComposedFinder is
# expected to mask foo/qux entirely with content from $tmp/b.
ensureParentDir(self.tmppath('a/foo/qux/hoge'))
open(self.tmppath('a/foo/qux/hoge'), 'wb').write('hoge')
open(self.tmppath('a/foo/qux/bar'), 'wb').write('not the right content')
self.finder = ComposedFinder({
'': FileFinder(self.tmppath('a')),
'foo/qux': FileFinder(self.tmppath('b')),
})
self.do_match_test()
if __name__ == '__main__':
mozunit.main()