diff --git a/python/mozbuild/mozpack/packager/__init__.py b/python/mozbuild/mozpack/packager/__init__.py index 993e2145111c..71c5cb485504 100644 --- a/python/mozbuild/mozpack/packager/__init__.py +++ b/python/mozbuild/mozpack/packager/__init__.py @@ -10,6 +10,7 @@ import os from mozpack.errors import errors from mozpack.chrome.manifest import ( Manifest, + ManifestBinaryComponent, ManifestChrome, ManifestInterfaces, is_manifest, @@ -236,8 +237,9 @@ class SimplePackager(object): self._chrome_queue = CallDeque() # Queue for formatter.add() calls. self._file_queue = CallDeque() - # All paths containing addons. - self._addons = set() + # All paths containing addons. (key is path, value is whether it + # should be packed or unpacked) + self._addons = {} # All manifest paths imported. self._manifests = set() # All manifest paths included from some other manifest. @@ -256,7 +258,7 @@ class SimplePackager(object): else: self._file_queue.append(self.formatter.add, path, file) if mozpath.basename(path) == 'install.rdf': - self._addons.add(mozpath.dirname(path)) + self._addons[mozpath.dirname(path)] = True def _add_manifest_file(self, path, file): ''' @@ -278,6 +280,12 @@ class SimplePackager(object): e.move(e.base)) elif not isinstance(e, (Manifest, ManifestInterfaces)): self._queue.append(self.formatter.add_manifest, e.move(e.base)) + # If a binary component is added to an addon, prevent the addon + # from being packed. + if isinstance(e, ManifestBinaryComponent): + addon = mozpath.basedir(e.base, self._addons) + if addon: + self._addons[addon] = 'unpacked' if isinstance(e, Manifest): if e.flags: errors.fatal('Flags are not supported on ' + @@ -294,11 +302,11 @@ class SimplePackager(object): for m in self._manifests - set(self._included_manifests)) if not addons: - all_bases -= self._addons + all_bases -= set(self._addons) else: # If for some reason some detected addon doesn't have a # non-included manifest. - all_bases |= self._addons + all_bases |= set(self._addons) return all_bases def close(self): @@ -315,8 +323,8 @@ class SimplePackager(object): errors.fatal('"%s" is included from "%s", which is outside "%s"' % (m, self._included_manifests[m], mozpath.basedir(m, bases))) - for base in bases: - self.formatter.add_base(base, base in self._addons) + for base in sorted(bases): + self.formatter.add_base(base, self._addons.get(base, False)) self._chrome_queue.execute() self._queue.execute() self._file_queue.execute() diff --git a/python/mozbuild/mozpack/packager/formats.py b/python/mozbuild/mozpack/packager/formats.py index 892cc04112c5..98db516e9143 100644 --- a/python/mozbuild/mozpack/packager/formats.py +++ b/python/mozbuild/mozpack/packager/formats.py @@ -46,8 +46,9 @@ The base interface provides the following methods: Register a base directory for an application or GRE, or an addon. Base directories usually contain a root manifest (manifests not included in any other manifest) named chrome.manifest. - The optional boolean addon argument tells whether the base directory - is that of an addon. + The optional addon argument tells whether the base directory + is that of a packed addon (True), unpacked addon ('unpacked') or + otherwise (False). - add(path, content) Add the given content (BaseFile instance) at the given virtual path - add_interfaces(path, content) diff --git a/python/mozbuild/mozpack/test/test_packager.py b/python/mozbuild/mozpack/test/test_packager.py index c5fd2ba5c44f..38b701fed3aa 100644 --- a/python/mozbuild/mozpack/test/test_packager.py +++ b/python/mozbuild/mozpack/test/test_packager.py @@ -14,8 +14,9 @@ from mozpack.packager import ( ) from mozpack.files import GeneratedFile from mozpack.chrome.manifest import ( - ManifestResource, + ManifestBinaryComponent, ManifestContent, + ManifestResource, ) from mozunit import MockedOpen from mozbuild.preprocessor import Preprocessor @@ -150,7 +151,10 @@ class TestSimplePackager(unittest.TestCase): with errors.context('manifest', 3): packager.add('qux/qux.manifest', - GeneratedFile('resource qux qux/')) + GeneratedFile(''.join([ + 'resource qux qux/\n', + 'binary-component qux.so\n', + ]))) bar_xpt = GeneratedFile('bar.xpt') qux_xpt = GeneratedFile('qux.xpt') foo_html = GeneratedFile('foo_html') @@ -181,6 +185,18 @@ class TestSimplePackager(unittest.TestCase): with errors.context('manifest', 9): packager.add('addon/install.rdf', install_rdf) + with errors.context('manifest', 10): + packager.add('addon2/install.rdf', install_rdf) + packager.add('addon2/chrome.manifest', + GeneratedFile('binary-component addon2.so')) + + with errors.context('manifest', 11): + packager.add('addon3/install.rdf', install_rdf) + packager.add('addon3/chrome.manifest', GeneratedFile( + 'manifest components/components.manifest')) + packager.add('addon3/components/components.manifest', + GeneratedFile('binary-component addon3.so')) + self.assertEqual(formatter.log, []) with errors.context('dummy', 1): @@ -190,8 +206,10 @@ class TestSimplePackager(unittest.TestCase): # chrome entries appear before the others. self.assertEqual(formatter.log, [ (('dummy', 1), 'add_base', '', False), - (('dummy', 1), 'add_base', 'qux', False), (('dummy', 1), 'add_base', 'addon', True), + (('dummy', 1), 'add_base', 'addon2', 'unpacked'), + (('dummy', 1), 'add_base', 'addon3', 'unpacked'), + (('dummy', 1), 'add_base', 'qux', False), ((os.path.join(curdir, 'foo', 'bar.manifest'), 2), 'add_manifest', ManifestContent('foo', 'bar', 'bar/')), ((os.path.join(curdir, 'foo', 'bar.manifest'), 1), @@ -200,16 +218,25 @@ class TestSimplePackager(unittest.TestCase): 'add_manifest', ManifestResource('bar', 'baz', 'baz/')), (('qux/qux.manifest', 1), 'add_manifest', ManifestResource('qux', 'qux', 'qux/')), + (('qux/qux.manifest', 2), + 'add_manifest', ManifestBinaryComponent('qux', 'qux.so')), (('manifest', 4), 'add_interfaces', 'foo/bar.xpt', bar_xpt), (('manifest', 7), 'add_interfaces', 'foo/qux.xpt', qux_xpt), ((os.path.join(curdir, 'addon', 'chrome.manifest'), 1), 'add_manifest', ManifestResource('addon', 'hoge', 'hoge/')), + (('addon2/chrome.manifest', 1), 'add_manifest', + ManifestBinaryComponent('addon2', 'addon2.so')), + (('addon3/components/components.manifest', 1), 'add_manifest', + ManifestBinaryComponent('addon3/components', 'addon3.so')), (('manifest', 5), 'add', 'foo/bar/foo.html', foo_html), (('manifest', 5), 'add', 'foo/bar/bar.html', bar_html), (('manifest', 9), 'add', 'addon/install.rdf', install_rdf), + (('manifest', 10), 'add', 'addon2/install.rdf', install_rdf), + (('manifest', 11), 'add', 'addon3/install.rdf', install_rdf), ]) - self.assertEqual(packager.get_bases(), set(['', 'addon', 'qux'])) + self.assertEqual(packager.get_bases(), + set(['', 'addon', 'addon2', 'addon3', 'qux'])) self.assertEqual(packager.get_bases(addons=False), set(['', 'qux'])) def test_simple_packager_manifest_consistency(self):