Bug 1260241 - Pre: Allow to store (rather than deflate) files into Jarrers. r?glandium draft
authorNick Alexander <nalexander@mozilla.com>
Mon, 28 Mar 2016 13:35:07 -0700
changeset 345330 ef88cda78b4fd2f76cc04929fd2bda0d785f413f
parent 345329 70016419a99c553016874b0d8906e3b5058bd28b
child 345331 ad2de0559461d8750b76dab4df57c489a363d2b1
push id14050
push usernalexander@mozilla.com
push dateMon, 28 Mar 2016 20:40:35 +0000
reviewersglandium
bugs1260241
milestone48.0a1
Bug 1260241 - Pre: Allow to store (rather than deflate) files into Jarrers. r?glandium I couldn't think of a better way to pass arguments into the Jarrer for a single file. While I was here, I expanded mozjar just a little. MozReview-Commit-ID: CDVLoLANqWY
python/mozbuild/mozpack/copier.py
python/mozbuild/mozpack/files.py
python/mozbuild/mozpack/mozjar.py
--- a/python/mozbuild/mozpack/copier.py
+++ b/python/mozbuild/mozpack/copier.py
@@ -7,16 +7,17 @@ from __future__ import absolute_import
 import os
 import stat
 import sys
 
 from mozpack.errors import errors
 from mozpack.files import (
     BaseFile,
     Dest,
+    StoredFile,
 )
 import mozpack.path as mozpath
 import errno
 from collections import (
     Counter,
     OrderedDict,
 )
 import concurrent.futures as futures
@@ -535,16 +536,21 @@ class Jarrer(FileRegistry, BaseFile):
         except Exception:
             old_jar = []
 
         old_contents = dict([(f.filename, f) for f in old_jar])
 
         with JarWriter(fileobj=dest, compress=self.compress,
                        optimize=self.optimize) as jar:
             for path, file in self:
+                if isinstance(file, StoredFile):
+                    jar.add(path, file, mode=file.mode, compress=file.compress,
+                            compress_level=file.compress_level)
+                    continue
+
                 if path in old_contents:
                     deflater = DeflaterDest(old_contents[path], self.compress)
                 else:
                     deflater = DeflaterDest(compress=self.compress)
                 file.copy(deflater, skip_if_older)
                 jar.add(path, deflater.deflater, mode=file.mode)
             if self._preload:
                 jar.preload(self._preload)
--- a/python/mozbuild/mozpack/files.py
+++ b/python/mozbuild/mozpack/files.py
@@ -506,16 +506,27 @@ class DeflatedFile(BaseFile):
         return self.file
 
     def read(self):
         '''Return the contents of the file.'''
         self.file.seek(0)
         return self.file.read()
 
 
+class StoredFile(File):
+    '''
+    File class that includes compression options when included in a
+    jar archive.
+    '''
+    def __init__(self, path, compress=False, compress_level=9):
+        File.__init__(self, path)
+        self.compress = compress
+        self.compress_level = compress_level
+
+
 class XPTFile(GeneratedFile):
     '''
     File class for a linked XPT file. It takes several XPT files as input
     (using the add() and remove() member functions), and links them at copy()
     time.
     '''
     def __init__(self):
         self._files = set()
--- a/python/mozbuild/mozpack/mozjar.py
+++ b/python/mozbuild/mozpack/mozjar.py
@@ -565,43 +565,47 @@ class JarWriter(object):
         if not self._optimize:
             end['cdir_offset'] = offset
             for entry, _ in self._contents.itervalues():
                 self._data.write(entry.serialize())
         # Store the end of central directory.
         self._data.write(end.serialize())
         self._data.close()
 
-    def add(self, name, data, compress=None, mode=None):
+    def add(self, name, data, compress=None, compress_level=None, mode=None):
         '''
         Add a new member to the jar archive, with the given name and the given
         data.
         The compress option indicates if the given data should be compressed
         (True), not compressed (False), or compressed according to the default
         defined when creating the JarWriter (None).
         When the data should be compressed (True or None with self.compress ==
         True), it is only really compressed if the compressed size is smaller
-        than the uncompressed size.
+        than the uncompressed size.  The compress_level option indicates the
+        level of compression, from least (0) to most (9) or the default
+        defined when creating the JarWriter (None).
         The mode option gives the unix permissions that should be stored
         for the jar entry.
         The given data may be a buffer, a file-like instance, a Deflater or a
         JarFileReader instance. The latter two allow to avoid uncompressing
         data to recompress it.
         '''
         name = mozpath.normsep(name)
 
         if name in self._contents:
             raise JarWriterError("File %s already in JarWriter" % name)
         if compress is None:
             compress = self._compress
+        if compress_level is None:
+            compress_level = self._compress_level
         if (isinstance(data, JarFileReader) and data.compressed == compress) \
                 or (isinstance(data, Deflater) and data.compress == compress):
             deflater = data
         else:
-            deflater = Deflater(compress, compress_level=self._compress_level)
+            deflater = Deflater(compress, compress_level=compress_level)
             if isinstance(data, basestring):
                 deflater.write(data)
             elif hasattr(data, 'read'):
                 if hasattr(data, 'seek'):
                     data.seek(0)
                 deflater.write(data.read())
             else:
                 raise JarWriterError("Don't know how to handle %s" %