author | Gregory Szorc <gps@mozilla.com> |
Thu, 04 Jun 2015 11:24:03 -0700 | |
changeset 247844 | 187dfb251703ddce7ffbb553850efcabf3bf8774 |
parent 247843 | 553615c0705ea3aa76fea98e3b4b14dcbabcc760 |
child 247845 | 1a470efc9fc2b3d76831f683dc2eae1c143628c1 |
push id | 28885 |
push user | cbook@mozilla.com |
push date | Wed, 10 Jun 2015 13:18:59 +0000 |
treeherder | autoland@e101c589c242 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | glandium |
bugs | 1168607 |
milestone | 41.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
python/mozbuild/mozpack/files.py | file | annotate | diff | comparison | revisions | |
python/mozbuild/mozpack/test/test_files.py | file | annotate | diff | comparison | revisions |
--- a/python/mozbuild/mozpack/files.py +++ b/python/mozbuild/mozpack/files.py @@ -708,16 +708,30 @@ class BaseFinder(object): mozpack.path.match documentation for a description of the handled patterns. ''' while pattern.startswith('/'): pattern = pattern[1:] 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 starting with a '.' and files at any level under a directory starting with a '.'). for path, file in finder: ... ''' @@ -783,17 +797,18 @@ class FileFinder(BaseFinder): Note all files with a name starting with a '.' are ignored when scanning directories, but are not ignored when explicitely requested. ''' if '*' in pattern: return self._find_glob('', mozpath.split(pattern)) 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): ''' Actual implementation of FileFinder.find() when the given pattern corresponds to an existing directory under the base directory. Ignores file names starting with a '.' under the given path. If the path itself has leafs starting with a '.', they are not ignored. ''' @@ -805,33 +820,29 @@ class FileFinder(BaseFinder): # likely dependent on filesystem implementation details, such as # inode ordering. for p in sorted(os.listdir(os.path.join(self.base, path))): if p.startswith('.'): continue 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): ''' Actual implementation of FileFinder.find() when the given pattern contains globbing patterns ('*' or '**'). This is meant to be an equivalent of: for p, f in self: if mozpath.match(p, pattern):
--- a/python/mozbuild/mozpack/test/test_files.py +++ b/python/mozbuild/mozpack/test/test_files.py @@ -906,16 +906,26 @@ class TestFileFinder(MatchTestTemplate, do_check(self, self.finder, pattern, result) def test_file_finder(self): self.prepare_match_test(with_dotfiles=True) self.finder = FileFinder(self.tmpdir) 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() self.add('fooz') # Present to ensure prefix matching doesn't exclude. self.add('foo/quxz') @@ -964,16 +974,19 @@ class TestJarFinder(MatchTestTemplate, T def test_jar_finder(self): self.jar = JarWriter(file=self.tmppath('test.jar')) self.prepare_match_test() self.jar.finish() reader = JarReader(file=self.tmppath('test.jar')) 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): # 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) @@ -995,11 +1008,14 @@ class TestComposedFinder(MatchTestTempla 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() + self.assertIsNone(self.finder.get('does-not-exist')) + self.assertIsInstance(self.finder.get('bar'), File) + if __name__ == '__main__': mozunit.main()