Bug 1216371 - Pack addons that can be packed as XPIs. r=gps
authorMike Hommey <mh+mozilla@glandium.org>
Wed, 11 Nov 2015 18:02:41 +0900
changeset 273166 cad6d8407311200d02cdde65f2b05cf4b26b26ba
parent 273165 8ce4cdc77f88ee20f7fd669db89cd613e1f9d73d
child 273167 f20f90d8cbbb01061d3f12efbd613170456b7d69
push id68190
push usermh@glandium.org
push dateWed, 18 Nov 2015 23:06:38 +0000
treeherdermozilla-inbound@cad6d8407311 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps
bugs1216371
milestone45.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
Bug 1216371 - Pack addons that can be packed as XPIs. r=gps
python/mozbuild/mozpack/packager/formats.py
python/mozbuild/mozpack/packager/unpack.py
python/mozbuild/mozpack/test/test_packager_formats.py
--- a/python/mozbuild/mozpack/packager/formats.py
+++ b/python/mozbuild/mozpack/packager/formats.py
@@ -182,19 +182,24 @@ class JarFormatter(PiecemealFormatter):
     entries.
     '''
     def __init__(self, copier, compress=True, optimize=True):
         PiecemealFormatter.__init__(self, copier)
         self._compress=compress
         self._optimize=optimize
 
     def _add_base(self, base, addon=False):
-        self._sub_formatter[base] = JarSubFormatter(
-            FileRegistrySubtree(base, self.copier),
-            self._compress, self._optimize)
+        if addon is True:
+            jarrer = Jarrer(self._compress, self._optimize)
+            self.copier.add(base + '.xpi', jarrer)
+            self._sub_formatter[base] = FlatSubFormatter(jarrer)
+        else:
+            self._sub_formatter[base] = JarSubFormatter(
+                FileRegistrySubtree(base, self.copier),
+                self._compress, self._optimize)
 
 
 class JarSubFormatter(PiecemealFormatter):
     '''
     Sub-formatter for the jar package format. It is a PiecemealFormatter that
     dispatches between further sub-formatter for each of the jar files it
     dispatches the chrome data to, and a FlatSubFormatter for the non-chrome
     files.
--- a/python/mozbuild/mozpack/packager/unpack.py
+++ b/python/mozbuild/mozpack/packager/unpack.py
@@ -59,33 +59,38 @@ class UnpackFinder(FileFinder):
             # if there is a corresponding manifest in the directory.
             if not p.endswith('.xpi') and self._maybe_zip(f) and \
                     (mozpath.basename(p) == self.omnijar or
                      not self.omnijar):
                 jar = self._open_jar(p, f)
                 if 'chrome.manifest' in jar:
                     self.kind = 'omni'
                     self.omnijar = mozpath.basename(p)
-                    self._fill_with_omnijar(base, jar)
+                    self._fill_with_jar(base, jar)
                     continue
             # If the file is a manifest, scan its entries for some referencing
             # jar: urls. If there are some, the files contained in the jar they
             # point to, go under a directory named after the jar.
             if is_manifest(p):
                 m = self.files[p] if self.files.contains(p) \
                     else ManifestFile(base)
                 for e in parse_manifest(self.base, p, f.open()):
                     m.add(self._handle_manifest_entry(e, jars))
                 if self.files.contains(p):
                     continue
                 f = m
+            # If the file is a packed addon, unpack it under a directory named
+            # after the xpi.
+            if p.endswith('.xpi') and self._maybe_zip(f):
+                self._fill_with_jar(p[:-4], self._open_jar(p, f))
+                continue
             if not p in jars:
                 self.files.add(p, f)
 
-    def _fill_with_omnijar(self, base, jar):
+    def _fill_with_jar(self, base, jar):
         for j in jar:
             path = mozpath.join(base, j.filename)
             if is_manifest(j.filename):
                 m = self.files[path] if self.files.contains(path) \
                     else ManifestFile(mozpath.dirname(path))
                 for e in parse_manifest(None, path, j):
                     m.add(e)
                 if not self.files.contains(path):
--- a/python/mozbuild/mozpack/test/test_packager_formats.py
+++ b/python/mozbuild/mozpack/test/test_packager_formats.py
@@ -30,40 +30,45 @@ from mozpack.test.test_files import (
 import mozpack.path as mozpath
 
 
 CONTENTS = {
     'bases': {
         # base_path: is_addon?
         '': False,
         'app': False,
-        'addon0': True,
+        'addon0': 'unpacked',
+        'addon1': True,
     },
     'manifests': [
         ManifestContent('chrome/f', 'oo', 'oo/'),
         ManifestContent('chrome/f', 'bar', 'oo/bar/'),
         ManifestResource('chrome/f', 'foo', 'resource://bar/'),
         ManifestBinaryComponent('components', 'foo.so'),
         ManifestContent('app/chrome', 'content', 'foo/'),
         ManifestComponent('app/components', '{foo-id}', 'foo.js'),
         ManifestContent('addon0/chrome', 'content', 'foo/bar/'),
+        ManifestContent('addon1/chrome', 'content', 'foo/bar/'),
     ],
     'files': {
         'chrome/f/oo/bar/baz': GeneratedFile('foobarbaz'),
         'chrome/f/oo/baz': GeneratedFile('foobaz'),
         'chrome/f/oo/qux': GeneratedFile('fooqux'),
         'components/foo.so': GeneratedFile('foo.so'),
         'components/foo.xpt': foo_xpt,
         'components/bar.xpt': bar_xpt,
         'foo': GeneratedFile('foo'),
         'app/chrome/foo/foo': GeneratedFile('appfoo'),
         'app/components/foo.js': GeneratedFile('foo.js'),
         'addon0/chrome/foo/bar/baz': GeneratedFile('foobarbaz'),
         'addon0/components/foo.xpt': foo2_xpt,
         'addon0/components/bar.xpt': bar_xpt,
+        'addon1/chrome/foo/bar/baz': GeneratedFile('foobarbaz'),
+        'addon1/components/foo.xpt': foo2_xpt,
+        'addon1/components/bar.xpt': bar_xpt,
     },
 }
 
 FILES = CONTENTS['files']
 
 RESULT_FLAT = {
     'chrome.manifest': [
         'manifest chrome/chrome.manifest',
@@ -97,33 +102,40 @@ RESULT_FLAT = {
     'app/chrome/chrome.manifest': [
         'content content foo/',
     ],
     'app/chrome/foo/foo': FILES['app/chrome/foo/foo'],
     'app/components/components.manifest': [
         'component {foo-id} foo.js',
     ],
     'app/components/foo.js': FILES['app/components/foo.js'],
-    'addon0/chrome.manifest': [
-        'manifest chrome/chrome.manifest',
-        'manifest components/components.manifest',
-    ],
-    'addon0/chrome/chrome.manifest': [
-        'content content foo/bar/',
-    ],
-    'addon0/chrome/foo/bar/baz': FILES['addon0/chrome/foo/bar/baz'],
-    'addon0/components/components.manifest': [
-        'interfaces interfaces.xpt',
-    ],
-    'addon0/components/interfaces.xpt': {
-        'foo': read_interfaces(foo2_xpt.open())['foo'],
-        'bar': read_interfaces(bar_xpt.open())['bar'],
-    },
 }
 
+for addon in ('addon0', 'addon1'):
+    RESULT_FLAT.update({
+        mozpath.join(addon, p): f
+        for p, f in {
+            'chrome.manifest': [
+                'manifest chrome/chrome.manifest',
+                'manifest components/components.manifest',
+            ],
+            'chrome/chrome.manifest': [
+                'content content foo/bar/',
+            ],
+            'chrome/foo/bar/baz': FILES[mozpath.join(addon, 'chrome/foo/bar/baz')],
+            'components/components.manifest': [
+                'interfaces interfaces.xpt',
+            ],
+            'components/interfaces.xpt': {
+                'foo': read_interfaces(foo2_xpt.open())['foo'],
+                'bar': read_interfaces(bar_xpt.open())['bar'],
+            },
+        }.iteritems()
+    })
+
 RESULT_JAR = {
     p: RESULT_FLAT[p]
     for p in (
         'chrome.manifest',
         'chrome/chrome.manifest',
         'components/components.manifest',
         'components/foo.so',
         'components/interfaces.xpt',
@@ -155,30 +167,35 @@ RESULT_JAR.update({
         'foo': FILES['app/chrome/foo/foo'],
     },
     'addon0/chrome/chrome.manifest': [
         'content content jar:foo.jar!/bar/',
     ],
     'addon0/chrome/foo.jar': {
         'bar/baz': FILES['addon0/chrome/foo/bar/baz'],
     },
+    'addon1.xpi': {
+        mozpath.relpath(p, 'addon1'): f
+        for p, f in RESULT_FLAT.iteritems()
+        if p.startswith('addon1/')
+    },
 })
 
 RESULT_OMNIJAR = {
     p: RESULT_FLAT[p]
     for p in (
         'components/foo.so',
         'foo',
     )
 }
 
 RESULT_OMNIJAR.update({
     p: RESULT_JAR[p]
     for p in RESULT_JAR
-    if p.startswith('addon0/')
+    if p.startswith('addon')
 })
 
 RESULT_OMNIJAR.update({
     'omni.foo': {
         'components/components.manifest': [
             'interfaces interfaces.xpt',
         ],
     },